-
-
Notifications
You must be signed in to change notification settings - Fork 638
Update spec/dummy for React 19 compatibility #2127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Upgrade react-redux from ^8.0.2 to ^9.2.0 for React 19 support
- Upgrade redux from ^4.0.1 to ^5.0.1 (required by react-redux 9.x)
- Upgrade redux-thunk from ^2.2.0 to ^3.1.0 (required by redux 5.x)
- Replace react-helmet@^6.1.0 with @dr.pogodin/react-helmet@^3.0.4
(thread-safe React 19 compatible fork)
Code changes:
- Update redux-thunk imports to use named export: { thunk }
- Update react-helmet SSR to use HelmetProvider with context prop
- Remove @types/react-helmet (new package has built-in types)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add HelmetProvider wrapper to client-side entry points for ReactHelmet components. The @dr.pogodin/react-helmet package requires HelmetProvider to wrap all Helmet components, on both server and client sides. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughUpdates redux-thunk imports from default to named imports across multiple files. Replaces react-helmet with Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Code Review: React 19 Compatibility UpdateI've reviewed this PR and overall it looks solid. The changes correctly update the spec/dummy app to React 19 and handle the necessary dependency migrations. Here's my detailed feedback: ✅ What's Good1. Dependency Updates Are Correct
2. Code Changes Are Thorough
3. Documentation Added
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
react_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsx (1)
8-32: Thunk update is correct; consider React 19 render API for this legacy entryThe move to
import { thunk } from 'redux-thunk'andapplyMiddleware(thunk)for store creation is consistent with the rest of the PR and the upgraded Redux stack. However, this entrypoint still usesReactDOM.render/ReactDOM.hydrate, which are removed in React 19; if this “react16” example is actually executed against the React 19 dependency fromspec/dummy/package.json, you may want to mirror the newer client entry’screateRoot/hydrateRootpattern or clearly scope this bundle to a React 16 build.Please double-check how this
app-react16bundle is built/loaded in your test matrix to ensure it doesn’t accidentally run against React 19’s removedReactDOM.renderAPI.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
react_on_rails/spec/dummy/Gemfile.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
react_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsx(2 hunks)react_on_rails/spec/dummy/client/app/components/ReactHelmet.jsx(1 hunks)react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx(1 hunks)react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsx(2 hunks)react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsx(1 hunks)react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsx(2 hunks)react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsx(2 hunks)react_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsx(2 hunks)react_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsx(2 hunks)react_on_rails/spec/dummy/package.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit inference engine (CLAUDE.md)
ALWAYS ensure files end with a newline character before committing/pushing
Files:
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/package.jsonreact_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to /CHANGELOG.md : Update `/CHANGELOG.md` for user-visible changes (features, bug fixes, breaking changes, deprecations, performance improvements) to the open-source React on Rails gem and npm package
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to /CHANGELOG*.md : Use changelog format: `[PR 1818](https://github.com/shakacode/react_on_rails/pull/1818) by [username](https://github.com/username)` (no hash in PR number)
📚 Learning: 2024-10-08T20:53:47.076Z
Learnt from: theforestvn88
Repo: shakacode/react_on_rails PR: 1620
File: spec/dummy/client/app/startup/HelloTurboStream.jsx:3-3
Timestamp: 2024-10-08T20:53:47.076Z
Learning: The `RailsContext` import in `spec/dummy/client/app/startup/HelloTurboStream.jsx` is used later in the project, as clarified by the user theforestvn88.
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/package.jsonreact_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to /CHANGELOG.md : Update `/CHANGELOG.md` for user-visible changes (features, bug fixes, breaking changes, deprecations, performance improvements) to the open-source React on Rails gem and npm package
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/package.jsonreact_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.
Applied to files:
react_on_rails/spec/dummy/package.json
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.
Applied to files:
react_on_rails/spec/dummy/package.jsonreact_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
Applied to files:
react_on_rails/spec/dummy/package.json
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: The `react_on_rails_pro/` directory has its own Prettier/ESLint configuration and must be linted separately
Applied to files:
react_on_rails/spec/dummy/package.json
📚 Learning: 2025-02-13T19:09:15.991Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/RSCWebpackLoader.ts:0-0
Timestamp: 2025-02-13T19:09:15.991Z
Learning: In React Server Components webpack loader, using `new Function('return import("react-server-dom-webpack/node-loader")')()` is necessary as a workaround to bypass TypeScript compilation issues with direct dynamic imports.
Applied to files:
react_on_rails/spec/dummy/package.jsonreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-02-13T16:50:47.848Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/clientStartup.ts:18-21
Timestamp: 2025-02-13T16:50:47.848Z
Learning: In the react_on_rails module, the `reactOnRailsPageUnloaded` function in clientStartup.ts is intentionally kept private as it's only used internally as a callback for `onPageUnloaded`.
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsxreact_on_rails/spec/dummy/client/app/components/ReactHelmet.jsxreact_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsx
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
Applied to files:
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsx
🧬 Code graph analysis (6)
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsx (3)
react_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsx (3)
store(32-32)combinedReducer(27-27)combinedProps(28-28)react_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsx (3)
store(31-31)combinedReducer(26-26)combinedProps(27-27)react_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsx (1)
combinedReducer(13-13)
react_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsx (2)
react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsx (3)
store(37-37)combinedReducer(32-32)combinedProps(33-33)react_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsx (1)
combinedReducer(13-13)
react_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsx (3)
react_on_rails/spec/dummy/client/app-react16/startup/ReduxApp.client.jsx (1)
combinedReducer(27-27)react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsx (1)
combinedReducer(32-32)react_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsx (1)
combinedReducer(26-26)
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsx (2)
packages/react-on-rails/src/ReactDOMServer.cts (1)
renderToString(4-4)react_on_rails/spec/dummy/client/app/components/ReactHelmet.jsx (1)
ReactHelmet(8-16)
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsx (1)
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsx (5)
helmetContext(21-21)helmetContext(27-27)componentHtml(22-26)props(20-34)renderedHtml(29-32)
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx (1)
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsx (1)
props(10-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: build-dummy-app-webpack-test-bundles (3.2, 20, minimum)
- GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
- GitHub Check: build
- GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
- GitHub Check: build
- GitHub Check: claude-review
🔇 Additional comments (12)
react_on_rails/spec/dummy/client/app/components/ReactHelmet.jsx (1)
2-7: Helmet import and provider expectations look goodSwitching to
@dr.pogodin/react-helmetand documenting that this component must be wrapped in aHelmetProvideraligns with the rest of the PR; no further changes needed here.Please confirm your local build/SSR tests that exercise Helmet continue to pass with
@dr.pogodin/react-helmetas configured inspec/dummy/package.json.react_on_rails/spec/dummy/client/app/startup/ReduxApp.server.jsx (1)
9-31: Server Redux store now uses namedthunkconsistentlyThe switch to
import { thunk } from 'redux-thunk'andapplyMiddleware(thunk)(createStore)(...)keeps the server-side store in sync with the client and shared store setups.Please rely on your server-rendering tests to confirm redux-thunk behavior is unchanged after the move to the named
thunkexport.react_on_rails/spec/dummy/client/app/stores/SharedReduxStore.jsx (1)
2-15: Shared Redux store thunk wiring matches other entrypointsUsing the named
thunkexport inapplyMiddleware(thunk)(createStore)(...)keeps the shared store aligned with the client/server Redux setups and the upgraded redux-thunk version.Confirm any consumers of this shared store behave as before (especially async action flows) after the thunk import change.
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.client.jsx (1)
3-14: Client ReactHelmet is correctly wrapped in HelmetProviderWrapping
ReactHelmetin<HelmetProvider>on the client matches the expectations documented inReactHelmet.jsxand the usage pattern for@dr.pogodin/react-helmet; the export signature remains compatible.Please confirm client-side Helmet behavior (e.g., title updates) still works as expected when exercising this “broken” example in the dummy app.
react_on_rails/spec/dummy/client/app/startup/ReactHelmetAppBroken.server.jsx (1)
6-32: Server ‘broken’ Helmet example now follows HelmetProvider SSR patternUsing
HelmetProviderwith a per-requesthelmetContextand derivingtitlefromhelmet.title.toString()matches the recommended SSR usage for@dr.pogodin/react-helmet, while preserving the intentionally “broken” single-argument signature described in the comments.Please exercise the server-side dummy route that uses this startup file to confirm that both the intended error path (due to the non-generator signature) and the captured
<title>still behave as expected under React 19.react_on_rails/spec/dummy/client/app/startup/ReduxApp.client.jsx (1)
8-37: All redux-thunk imports consistently use named export patternVerification confirms the review comment is accurate:
- All 4 files with redux-thunk imports use
import { thunk } from 'redux-thunk'(named import)- No default imports remain
- All store creation calls properly wire middleware:
applyMiddleware(thunk)- File under review (lines 8 and 37) follows the same consistent pattern as other entrypoints
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.server.jsx (4)
19-21: LGTM! Thread-safe per-request context pattern.The per-request
helmetContextinitialization correctly enables thread-safe helmet data capture for server-side rendering, consistent with the@dr.pogodin/react-helmetAPI pattern.
23-33: LGTM! Correct server-side rendering with HelmetProvider.The rendering logic properly:
- Wraps the component tree with
HelmetProviderpassing the per-request context- Uses inline
Helmetto set the page title- Renders the
HelloWorldcomponent with forwarded propsThis pattern aligns with the reference implementation in
ReactHelmetAppBroken.server.jsx.
35-39: LGTM! Safe helmet data extraction.The helmet extraction correctly:
- Retrieves helmet data from the context after rendering
- Includes a null check to prevent runtime errors
- Converts
helmet.titleto string with a safe fallbackThis matches the pattern in
ReactHelmetAppBroken.server.jsx.
4-5: All imports are valid and correctly used.The verification confirms:
HelloWorld.jsxexists at the expected pathreact_on_rails/spec/dummy/client/app/startup/HelloWorld.jsxHelmetandHelmetProviderare correctly exported from@dr.pogodin/react-helmetper the library's API- The usage in the file is correct:
HelmetProviderwraps components with an optionalcontextobject for SSR, andHelmetwraps head elements like<title>. This aligns exactly with the library's documentation- The file properly ends with a newline
react_on_rails/spec/dummy/client/app/startup/ReactHelmetApp.client.jsx (2)
3-3: Import aligns with client-side helmet usage pattern.The
HelmetProviderimport from@dr.pogodin/react-helmetis correct for client-side rendering. Note: Library API verification requested in the server file review (ReactHelmetApp.server.jsx) applies here as well.
9-14: LGTM! Correct client-side HelmetProvider wrapper.The client-side implementation correctly:
- Wraps
ReactHelmetwithHelmetProvider(no context prop needed for client rendering)- Forwards props to the wrapped component
- Matches the pattern in
ReactHelmetAppBroken.client.jsxThis completes the client-side migration to
@dr.pogodin/react-helmet.
| "@dr.pogodin/react-helmet": "^3.0.4", | ||
| "react": "^19.0.0", | ||
| "react-dom": "^19.0.0", | ||
| "react-on-rails": "link:.yalc/react-on-rails", | ||
| "react-redux": "^8.0.2", | ||
| "react-redux": "^9.2.0", | ||
| "react-router-dom": "^6.0.0", | ||
| "redux": "^4.0.1", | ||
| "redux-thunk": "^2.2.0", | ||
| "redux": "^5.0.1", | ||
| "redux-thunk": "^3.1.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Script executed:
#!/bin/bash
# Find all package.json files in the repository
fd package.json -t fRepository: shakacode/react_on_rails
<shell_result>
Repository: shakacode/react_on_rails
Exit code: 0
stdout:
package.json
packages/react-on-rails/package.json
packages/react-on-rails-pro/package.json
packages/react-on-rails-pro-node-renderer/package.json
react_on_rails/spec/dummy/package.json
react_on_rails/spec/react_on_rails/fixtures/absolute_path_package.json
react_on_rails/spec/react_on_rails/fixtures/beta_package.json
react_on_rails/spec/react_on_rails/fixtures/git_package.json
react_on_rails/spec/react_on_rails/fixtures/normal_package.json
react_on_rails/spec/react_on_rails/fixtures/pro_package.json
react_on_rails/spec/react_on_rails/fixtures/pro_semver_caret_package.json
react_on_rails/spec/react_on_rails/fixtures/relative_path_package.json
react_on_rails/spec/react_on_rails/fixtures/semver_caret_package.json
react_on_rails/spec/react_on_rails/fixtures/semver_exact_package.json
react_on_rails/spec/react_on_rails/fixtures/semver_range_package.json
react_on_rails/spec/react_on_rails/fixtures/semver_tilde_package.json
react_on_rails/spec/react_on_rails/fixtures/similar_packages_package.json
react_on_rails/spec/react_on_rails/fixtures/yalc_package.json
react_on_rails_pro/package.json
react_on_rails_pro/spec/dummy/package.json
react_on_rails_pro/spec/execjs-compatible-dummy/package.json
</shell_result>
Script executed:
#!/bin/bash
# Extract React/Redux/Helmet versions from key package.json files
echo "=== Root package.json ==="
cat package.json | jq '.dependencies // empty | {react: .react, "react-dom": .["react-dom"], "react-redux": .["react-redux"], redux: .redux, "redux-thunk": .["redux-thunk"], "@dr.pogodin/react-helmet": .["@dr.pogodin/react-helmet"]} | del(.[] | select(. == null))' 2>/dev/null || echo "No dependencies section"
echo -e "\n=== packages/react-on-rails/package.json ==="
cat packages/react-on-rails/package.json | jq '.peerDependencies // empty | {react: .react, "react-dom": .["react-dom"], "react-redux": .["react-redux"], redux: .redux, "redux-thunk": .["redux-thunk"], "@dr.pogodin/react-helmet": .["@dr.pogodin/react-helmet"]} | del(.[] | select(. == null))' 2>/dev/null || echo "No peerDependencies section"
echo -e "\n=== react_on_rails/spec/dummy/package.json ==="
cat react_on_rails/spec/dummy/package.json | jq '.dependencies // empty | {react: .react, "react-dom": .["react-dom"], "react-redux": .["react-redux"], redux: .redux, "redux-thunk": .["redux-thunk"], "@dr.pogodin/react-helmet": .["@dr.pogodin/react-helmet"]} | del(.[] | select(. == null))' 2>/dev/null || echo "No dependencies section"
echo -e "\n=== react_on_rails_pro/package.json ==="
cat react_on_rails_pro/package.json | jq '.dependencies // empty | {react: .react, "react-dom": .["react-dom"], "react-redux": .["react-redux"], redux: .redux, "redux-thunk": .["redux-thunk"], "@dr.pogodin/react-helmet": .["@dr.pogodin/react-helmet"]} | del(.[] | select(. == null))' 2>/dev/null || echo "No dependencies section"
echo -e "\n=== react_on_rails_pro/spec/dummy/package.json ==="
cat react_on_rails_pro/spec/dummy/package.json | jq '.dependencies // empty | {react: .react, "react-dom": .["react-dom"], "react-redux": .["react-redux"], redux: .redux, "redux-thunk": .["redux-thunk"], "@dr.pogodin/react-helmet": .["@dr.pogodin/react-helmet"]} | del(.[] | select(. == null))' 2>/dev/null || echo "No dependencies section"Repository: shakacode/react_on_rails
<shell_result>
Repository: shakacode/react_on_rails
Exit code: 0
stdout:
=== Root package.json ===
=== packages/react-on-rails/package.json ===
{
"react": ">= 16",
"react-dom": ">= 16"
}
=== react_on_rails/spec/dummy/package.json ===
{
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-redux": "^9.2.0",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"@dr.pogodin/react-helmet": "^3.0.4"
}
=== react_on_rails_pro/package.json ===
=== react_on_rails_pro/spec/dummy/package.json ===
{
"react": "19.0.0",
"react-dom": "19.0.0",
"react-redux": "^9.2.0",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0"
}
</shell_result>
Script executed:
#!/bin/bash
# Check if CHANGELOG.md was updated
echo "=== Recent CHANGELOG.md entries ==="
head -50 CHANGELOG.md
echo -e "\n=== Check git diff for CHANGELOG.md ==="
git diff HEAD~1 CHANGELOG.md 2>/dev/null | head -30 || echo "Cannot get git diff"Repository: shakacode/react_on_rails
<shell_result>
Repository: shakacode/react_on_rails
Exit code: 0
stdout:
=== Recent CHANGELOG.md entries ===
# Change Log
All notable changes to this project's source code will be documented in this file. Items under `Unreleased` is upcoming features that will be out in the next version.
Migration instructions for the major updates can be found [here](https://www.shakacode.com/react-on-rails/docs/guides/upgrading-react-on-rails#upgrading-to-version-9.md). Some smaller migration information can be found here.
## Want to Save Time Updating?
If you need help upgrading `react_on_rails`, `webpacker` to `shakapacker`, or JS packages, contact justin@shakacode.com. We can upgrade your project and improve your development and customer experiences, allowing you to focus on building new features or fixing bugs instead.
For an overview of working with us, see our [Client Engagement Model](https://www.shakacode.com/blog/client-engagement-model/) article and [how we bill for time](https://www.shakacode.com/blog/shortcut-jira-trello-github-toggl-time-and-task-tracking/).
If you think ShakaCode can help your project, [click here](https://meetings.hubspot.com/justingordon/30-minute-consultation) to book a call with [Justin Gordon](mailto:justin@shakacode.com), the creator of React on Rails and Shakapacker.
## Contributors
Please follow the recommendations outlined at [keepachangelog.com](http://keepachangelog.com/). Please use the existing headings and styling as a guide.
After a release, please make sure to run `bundle exec rake update_changelog`. This will add a heading for the latest version and update the links at the end of the file.
## Versions
### [Unreleased]
Changes since the last non-beta release.
#### Added
- **Service Dependency Checking for bin/dev**: Added optional `.dev-services.yml` configuration to validate required external services (Redis, PostgreSQL, Elasticsearch, etc.) are running before `bin/dev` starts the development server. Provides clear error messages with start commands and install hints when services are missing. Zero impact if not configured - backwards compatible with all existing installations. [PR 2098](https://github.com/shakacode/react_on_rails/pull/2098) by [justin808](https://github.com/justin808).
#### Changed
- **Monorepo Structure Reorganization**: Restructured the monorepo to use two top-level product directories (`react_on_rails/` and `react_on_rails_pro/`) instead of mixing source files at the root level. This improves organization and clarity for contributors working on either the open-source or Pro versions. **Important for contributors**: If you have an existing clone of the repository, you may need to update your IDE exclusion patterns and paths. See the updated `CLAUDE.md` for current project structure. [PR 2114](https://github.com/shakacode/react_on_rails/pull/2114) by [justin808](https://github.com/justin808).
- **Package Manager Migration to pnpm (Contributors Only)**: Migrated the monorepo from Yarn Classic to pnpm for improved dependency management and faster installs. **This only affects contributors** - end users can continue using any package manager (npm, yarn, pnpm) with their applications. Contributors should reinstall dependencies with `pnpm install` after pulling this change. [PR 2121](https://github.com/shakacode/react_on_rails/pull/2121) by [justin808](https://github.com/justin808).
#### Improved
- **Automatic Precompile Hook Coordination in bin/dev**: The `bin/dev` command now automatically runs Shakapacker's `precompile_hook` once before starting development processes and sets `SHAKAPACKER_SKIP_PRECOMPILE_HOOK=true` to prevent duplicate execution in spawned webpack processes.
- Eliminates the need for manual coordination, sleep hacks, and duplicate task calls in Procfile.dev
- Users can configure expensive build tasks (like locale generation or ReScript compilation) once in `config/shakapacker.yml` and `bin/dev` handles coordination automatically
- Includes warning for Shakapacker versions below 9.4.0 (the `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable is only supported in 9.4.0+)
- The `SHAKAPACKER_SKIP_PRECOMPILE_HOOK` environment variable is set for all spawned processes, making it available for custom scripts that need to detect when `bin/dev` is managing the precompile hook
- Addresses [2091](https://github.com/shakacode/react_on_rails/issues/2091) by [justin808](https://github.com/justin808)
- **Idempotent Locale Generation**: The `react_on_rails:locale` rake task is now idempotent, automatically skipping generation when locale files are already up-to-date. This makes it safe to call multiple times (e.g., in Shakapacker's `precompile_hook`) without duplicate work. Added `force=true` option to override timestamp checking. [PR 2090](https://github.com/shakacode/react_on_rails/pull/2090) by [justin808](https://github.com/justin808).
### [v16.2.0.beta.12] - 2025-11-20
#### Added
=== Check git diff for CHANGELOG.md ===
</shell_result>
Script executed:
#!/bin/bash
# Check lines 35-45 in spec/dummy/package.json to see the devDependencies
sed -n '35,45p' react_on_rails/spec/dummy/package.jsonRepository: shakacode/react_on_rails
<shell_result>
Repository: shakacode/react_on_rails
Exit code: 0
stdout:
"@babel/preset-react": "^7.10.4",
"@playwright/test": "^1.55.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
"@rescript/react": "^0.13.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"babel-loader": "8.2.4",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"compression-webpack-plugin": "9",
"css-loader": "^6.5.1",
"expose-loader": "^1.0.3",
</shell_result>
Based on my verification, I've identified real cross-package inconsistencies and a missing CHANGELOG entry. Here's the rewritten review comment:
Version inconsistencies exist across spec/dummy packages; React 19 upgrade missing from CHANGELOG
Cross-package comparison reveals:
react_on_rails/spec/dummy/package.json: React^19.0.0, React-Redux^9.2.0, Redux^5.0.1, redux-thunk^3.1.0, @dr.pogodin/react-helmet^3.0.4react_on_rails_pro/spec/dummy/package.json: React19.0.0(exact version, not caret), React-Redux^9.2.0, Redux^5.0.1, redux-thunk^3.1.0, @dr.pogodin/react-helmet missing
The semver mismatch (^19.0.0 vs 19.0.0) and missing Helmet dependency between the two spec/dummy packages should be reconciled. Additionally, per project guidelines, the React 19 upgrade and dependency bumps should be documented in CHANGELOG.md under the Unreleased section.
🤖 Prompt for AI Agents
In react_on_rails/spec/dummy/package.json around lines 21-28 there is a
semver/dep mismatch vs react_on_rails_pro/spec/dummy/package.json (this file
uses "react": "^19.0.0" and includes "@dr.pogodin/react-helmet": "^3.0.4", while
the pro package uses "react": "19.0.0" and omits Helmet); make the versions
consistent across both spec/dummy package.json files (choose careted or exact
for react and apply the same style to react-dom), add the missing
@dr.pogodin/react-helmet dependency to
react_on_rails_pro/spec/dummy/package.json with the same version, and add a
brief entry under the Unreleased section of CHANGELOG.md documenting the React
19 upgrade and dependency bumps.
|
/run-skipped-ci |
|
🚀 Full CI Mode Enabled ✅ Triggered all workflows for full CI coverage Note: Added the To disable full CI mode, use the View progress in the Actions tab. |
Summary
Updates
spec/dummydependencies to be compatible with React 19:Dependency Updates
reactreact-domreact-reduxreduxredux-thunkreact-helmet@dr.pogodin/react-helmet@^3.0.4Code Changes
redux-thunk imports - Updated from default export to named export:
import middleware from 'redux-thunk'→import { thunk } from 'redux-thunk'SharedReduxStore.jsx,ReduxApp.server.jsx,ReduxApp.client.jsxreact-helmet migration - Updated to
@dr.pogodin/react-helmet:HelmetProviderwrapper (required for both client and server)contextprop for thread-safe data captureReactHelmet.jsx,ReactHelmetApp.server.jsx,ReactHelmetAppBroken.server.jsx, client entry pointsTest Plan
🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.