Reframe RSC migration docs around React on Rails patterns#2661
Reframe RSC migration docs around React on Rails patterns#2661
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughDocs and config updates clarifying React on Rails migration: emphasize Rails controller props and async props, adjust RSC examples (ProductPage, React Query, caching, waterfalls, streaming), add two Lychee URL exclusions, and normalize a docs URL in CONTRIBUTING.md. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Greptile SummaryThis PR re-frames three RSC migration documentation files around React on Rails' Rails-centric data model, replacing generic "async Server Component fetches data directly" examples with the idiomatic pattern of receiving data as Rails controller props (or streaming it via async props). The changes are largely editorial and improve the coherence of the guide for a Rails audience. Key changes:
Issues found:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
RC[Rails Controller] -->|"prepares data"| SP[Sync Props\nname, price, user...]
RC -->|"via stream_react_component_with_async_props"| AP[Async Props\nreviews, recommendations...]
SP -->|"passed immediately"| SC[Server Component\nno async/await needed]
AP -->|"streamed via Suspense"| SC
SC -->|"display-only subtree"| RSC[Child Server Components\nno JS shipped]
SC -->|"interactive subtree"| CC["Client Components\n'use client'"]
CC -->|"needs polling / optimistic updates"| RQ["React Query\ninitialData = Rails props\ninitialDataUpdatedAt = Date.now()"]
CC -->|"needs real-time / WebSocket"| WS[WebSocket / SSE\ninitialMessages from Rails]
CC -->|"needs Redux / Zustand"| GS[Global State Library\ndata from Rails props as initial values]
RQ -->|"background refetch"| API["/api endpoint"]
WS -->|"persistent connection"| WS2[WebSocket server]
|
|
Overall this is a well-executed reframing. The core insight -- that Rails controllers already handle data fetching so the RSC migration goal shifts to reducing client bundle size and enabling streaming rather than moving fetching to the server -- is exactly the right framing for a Rails audience. The contextual callout boxes are well-placed and the simplification of Pattern 2 (dropping dehydrate/HydrationBoundary in favour of initialData) reduces cognitive load for the common case. Three issues to address: (1) initialData stale-time -- see inline comment on line 279; (2) Hybrid Pattern ChatPage at line 815 still uses async/await getMessages directly, contradicting the new anti-pattern note; (3) minor: initialData vs placeholderData distinction not documented. Details below in inline comments and thread. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
docs/oss/migrating/rsc-data-fetching.md (1)
261-262: Good addition, but fix markdown linting issue.The alternative approach using
dehydrate/HydrationBoundaryis a valid advanced pattern for complex cases. However, there's a blank line issue triggering the MD028 markdownlint warning.If line 262 is a blank line within or immediately after the blockquote, remove it or ensure proper blockquote termination:
📝 Fix markdown linting
> **Alternative:** For complex cases with many queries, you can use TanStack Query's `dehydrate`/`HydrationBoundary` pattern to prefetch and seed the entire QueryClient cache on the server. See the [TanStack Query SSR docs](https://tanstack.com/query/latest/docs/framework/react/guides/ssr) for details. - ## Migrating from SWR🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/oss/migrating/rsc-data-fetching.md` around lines 261 - 262, Remove the stray blank line triggering MD028 inside or immediately after the blockquote that contains the Alternative sentence about the TanStack Query `dehydrate`/`HydrationBoundary` pattern; either delete the empty line or ensure the blockquote is properly terminated so the paragraph follows directly (i.e., keep the blockquote lines contiguous and do not leave a lone blank line inside or immediately after the quoted block).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/oss/migrating/rsc-data-fetching.md`:
- Around line 261-262: Remove the stray blank line triggering MD028 inside or
immediately after the blockquote that contains the Alternative sentence about
the TanStack Query `dehydrate`/`HydrationBoundary` pattern; either delete the
empty line or ensure the blockquote is properly terminated so the paragraph
follows directly (i.e., keep the blockquote lines contiguous and do not leave a
lone blank line inside or immediately after the quoted block).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b8e00c5e-b5e0-43c8-9044-5b7841fc26de
📒 Files selected for processing (2)
docs/oss/migrating/rsc-component-patterns.mddocs/oss/migrating/rsc-data-fetching.md
✅ Files skipped from review due to trivial changes (1)
- docs/oss/migrating/rsc-component-patterns.md
|
Overall this is a solid, focused improvement. The framing changes are accurate and the additions (TanStack Query Three things worth addressing: D4 not reflected in the diff: The description says D4 replaced
Waterfall section lost useful explanatory prose: The old intro stated "When queries execute one after another, rendering is delayed by their total time," which concretely explains why waterfalls hurt before showing the code examples. The replacement note points to solutions but drops this motivation entirely. Consider preserving that sentence so the section is self-contained. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ea9714536
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Good documentation improvements overall. The reframing around Rails props as the primary data delivery mechanism is accurate and helpful, and the async props references tie things together well. One minor observation: in the Avoiding Server-Side Waterfalls section, the original intro explicitly called out that "rendering is delayed by their total time" — a concrete framing that helps readers understand why sequential queries are costly. The new blockquote note doesn't include that, though the Ruby code example below (with Everything else looks solid:
|
|
Overall this is a solid documentation improvement. The React on Rails context callouts make the migration path much clearer, and the props-first framing is more accurate for the RoR workflow than generic RSC advice. One blocker: Two minor items: (1) The new TanStack Query link to Everything else looks good: The React on Rails context callout in Pattern 1 correctly reframes the goal as bundle size reduction and streaming rather than moving data fetching. All anchor links to |
Review: Reframe RSC migration docs around React on Rails patternsOverall this is a clean, focused documentation improvement. The reframing around Rails controller props as the primary data source is accurate and will reduce confusion for developers migrating to RSC. Strengths:
Minor observations:
None of these block merging. The documentation changes are accurate and valuable. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f3ee561b3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Review: Reframe RSC migration docs around React on Rails patternsThe framing improvements are solid — correctly positioning the RSC migration goal as "reduce bundle size and enable streaming" rather than "move data fetching to the server" is the right call for a Rails audience. The context callouts are well-placed and the pattern examples read naturally. One blocker needs to be resolved before merging. Blocker
Should-fixMissing lychee exclusion for Minor
|
|
Review: Reframe RSC migration docs around React on Rails patterns. Overall solid doc improvement. Issues: (1) rsc-data-fetching.md:545 mentions Pro-only APIs getReactOnRailsAsyncProp and addAsyncPropsCapabilityToComponentProps with no link to docs -- OSS users will be confused. (2) rsc-data-fetching.md:233 comment says 'Rails data renders instantly' but it is the initialData option that eliminates the loading state -- Rails is just the source. (3) Multiple locations use [async props] link text pointing to a Pro section without indicating it is a Pro feature -- [async props (Pro)] would help. (4) Spurious blank-line removal between StatsPanel and PostFeed adds diff noise. |
size-limit report 📦
|
- Data fetching guide: lead with Rails controller props and async props instead of generic async/await; show React Query `initialData` and SWR `fallbackData` with Rails props; add RoR context notes to waterfalls, use() hook, and React.cache() sections - Component patterns: reframe Pattern 1 motivation from "move data fetching to server" to "reduce bundle size / eliminate JS"; use Rails props in the After example - Context and state: replace `await getProduct()` with Rails props in Pattern 2 and Redux examples for consistency with async props pattern - "When to Keep Client-Side Fetching" table: note that read-only data is already server-side via Rails controller props Fixes #2526 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Restore blank line between StatsPanel and PostFeed component declarations and merge two overlapping notes about initialDataUpdatedAt/staleTime into a single consolidated note after the "How it works" list. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…uplicate NEWS.md entry Replace three permanent per-URL GitHub exclusions (PR 717, PR 2280, shakapacker blob) with increased max_retries (4 -> 6) to handle transient 502s more robustly. Remove duplicate 2016-08-27 Gitbook entry in NEWS.md. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
d5f0c20 to
eebe38d
Compare
Review: Reframe RSC migration docs around React on Rails patternsThe changes are well-targeted — consistently replacing generic async/await patterns with the Rails props-first framing, and correctly calling out where async props (Pro) fits into the picture. One bug to fix: Lines 261–263 in Everything else looks good:
|
|
Follow-up on skipped feedback triage:\n\n- |
|
Overall this is a good documentation cleanup. The framing around Rails controller props is clearer, the duplicate NEWS.md entries are removed, and the CONTRIBUTING.md URL fix is correct. Three issues worth addressing: 1. Duplicate notes about initialDataUpdatedAt / staleTime The PR adds a new brief note before 'How it works' (line 250), then the existing detailed note immediately after (line 259) covers the same ground plus more. Two adjacent notes explaining the same pair of options is redundant. The brief one should be removed, or both should be merged into a single note. 2. 'async props' links to a section that never defines the term Five new uses of 'async props' link to the 'Data Fetching in React on Rails Pro' section. That section opens with a description of stream_react_component and never uses the phrase 'async props'. A reader following the link will not find a definition. Either introduce 'async props' by name in that section's heading or opening paragraph, or link to a more targeted location (e.g. the Pro RSC tutorial) that explains the concept. 3. Pattern 1 no longer shows the Rails side The ERB code block showing stream_react_component was removed from Pattern 1. Pattern 1 now shows Before/After React components but gives no example of how the products prop arrives from Rails. Pattern 2 still has its ERB snippet, making Pattern 1 feel incomplete. A one-liner ERB example or a cross-reference to Pattern 2 would fill the gap. |
| props: { products: Product.limit(50).as_json }) %> | ||
| ``` | ||
|
|
||
| > **Note:** `initialDataUpdatedAt` and `staleTime` are intentional here. Together they tell React Query that the Rails data is fresh for the next five minutes instead of treating it as stale immediately on mount. |
There was a problem hiding this comment.
This note and the one at line 259 cover the same topic. The one at line 259 is strictly more informative (it explains why Date.now() is used, the precise-control alternative, and the staleTime: Infinity escape hatch). Keeping both leaves readers with two explanations of the same behavior back-to-back. Consider removing this brief note and letting the detailed one stand alone, or merging the two into a single callout.
| ``` | ||
|
|
||
| In React on Rails, data comes from Rails as props. The component simply renders it — no fetching, no loading states. For streaming HTML delivery, use [`stream_react_component`](#data-fetching-in-react-on-rails-pro). | ||
| > **React on Rails note:** In React on Rails, the controller prepares the data and passes it as props -- no `async/await` in the component, no direct data layer calls. For data that's slow to compute, use [async props](#data-fetching-in-react-on-rails-pro) to stream it in progressively with Suspense. The generic `async function` + `await` pattern shown in other RSC frameworks bypasses Rails' authorization and caching layers and is not recommended. |
There was a problem hiding this comment.
The link text "async props" points to #data-fetching-in-react-on-rails-pro, but that section describes stream_react_component and never introduces or defines the term "async props". A reader who doesn't already know what async props are will follow the link and find no explanation.
Suggest either adding a sentence like "React on Rails Pro supports async props — individual props that are Promises, resolved and streamed via Suspense" to that section's opening, or linking directly to the Pro RSC tutorial that explains the feature.
| @@ -181,17 +181,11 @@ function ProductList({ products }) { | |||
| } | |||
| ``` | |||
There was a problem hiding this comment.
The ERB snippet that was here (stream_react_component("ProductList", props: { products: Product.limit(50).as_json })) was the only Rails-side example in Pattern 1. Without it, the "After" component shows { products } arriving as a prop but doesn't show readers where that prop comes from. Pattern 2 keeps its ERB block, so Pattern 1 now looks asymmetric. A brief ERB one-liner, or even a note like "see Pattern 2's ERB block for how Rails passes props", would restore the complete picture.
- Remove duplicate initialDataUpdatedAt/staleTime note (line 250) that repeats the detailed note at line 259 - Introduce "async props" by name in the Data Fetching in React on Rails Pro section so the five link targets resolve to a definition - Add ERB snippet to Pattern 1 showing how Rails passes products as props, matching Pattern 2's completeness Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
| ); | ||
| } | ||
|
|
||
| function PostFeed({ posts }) { |
There was a problem hiding this comment.
The blank line between StatsPanel and PostFeed was removed by this diff. Adjacent top-level function declarations without a blank line are harder to scan.
| function PostFeed({ posts }) { | |
| function PostFeed({ posts }) { |
(Add a blank line before function PostFeed)
| ``` | ||
|
|
||
| In React on Rails, data comes from Rails as props. The component simply renders it — no fetching, no loading states. For streaming HTML delivery, use [`stream_react_component`](#data-fetching-in-react-on-rails-pro). | ||
| > **React on Rails note:** In React on Rails, the controller prepares the data and passes it as props -- no `async/await` in the component, no direct data layer calls. For data that's slow to compute, use [async props](#data-fetching-in-react-on-rails-pro) to stream it in progressively with Suspense. The generic `async function` + `await` pattern shown in other RSC frameworks bypasses Rails' authorization and caching layers and is not recommended. |
There was a problem hiding this comment.
The phrasing "bypasses Rails' authorization and caching layers" is too absolute. An async Server Component that calls a Rails service object (or a Node API that goes through the Rails app) can still enforce authorization — the issue is that developers often skip those checks when they have direct DB access, not that the pattern inherently bypasses them.
Consider softening to something like:
The generic
async function+awaitpattern shown in other RSC frameworks tends to bypass Rails' authorization and caching layers — it is not the recommended approach for React on Rails.
Or add a brief qualifier:
…unless you explicitly replicate Rails' authorization checks, this pattern bypasses Rails' controller/model layer and is not recommended.
Review SummaryThis is a clean, well-targeted docs-only PR. The reframing around Rails controller props / async props makes the migration guide much more coherent for a Rails audience. Positives
Minor issues (see inline comments)
Out of scope The .lychee.toml and NEWS.md changes are unrelated maintenance items. Harmless, but worth splitting into a separate PR for cleaner history. |
…e-repo * origin/main: Improve create-react-on-rails-app fresh app onboarding (#2849) Add Docker deployment guide for Kamal, Kubernetes, and Control Plane (#2837) Reframe RSC migration docs around React on Rails patterns (#2661) Enforce secure renderer password defaults for production-like envs (#2829)
Summary
rsc-data-fetching.mdaround React on Rails patterns (Rails controller props + async props), including:React.cache()usage.lychee.tomllink-check behavior:vite-ruby.netlify.appto flaky CI exclusionsNEWS.md.react_on_rails_pro/CONTRIBUTING.md.Fixes #2526
Test Plan
pnpm exec prettier --check --ignore-unknown .lychee.toml NEWS.md docs/oss/migrating/rsc-data-fetching.md react_on_rails_pro/CONTRIBUTING.mdorigin/mainand force-pushed cleanly.