Skip to content

Reframe RSC migration docs around React on Rails patterns#2661

Merged
justin808 merged 14 commits intomainfrom
2526-rsc-migration-docs-structural-and-framing-improvements
Mar 29, 2026
Merged

Reframe RSC migration docs around React on Rails patterns#2661
justin808 merged 14 commits intomainfrom
2526-rsc-migration-docs-structural-and-framing-improvements

Conversation

@AbanoubGhadban
Copy link
Copy Markdown
Collaborator

@AbanoubGhadban AbanoubGhadban commented Mar 17, 2026

Summary

  • Reframed key sections in rsc-data-fetching.md around React on Rails patterns (Rails controller props + async props), including:
    • clearer "after" examples and section labels for React Query/SWR usage with Rails-provided data
    • React on Rails context notes for avoiding server waterfalls and React.cache() usage
    • migration checklist wording updates aligned with async props and streaming SSR guidance
  • Updated .lychee.toml link-check behavior:
    • added vite-ruby.netlify.app to flaky CI exclusions
    • removed per-URL GitHub exclusions in favor of retry-based handling
  • Removed duplicate historical entries from NEWS.md.
  • Fixed the React on Rails Pro docs URL in 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.md
  • Verified branch rebased onto origin/main and force-pushed cleanly.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 17, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Docs 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

Cohort / File(s) Summary
RSC component patterns
docs/oss/migrating/rsc-component-patterns.md
Clarified that Rails prepares data server-side; reframed Pattern 1 around reducing client bundle size, removing unnecessary client JS, and supporting streaming with async props. Updated ProductPage "After" comments to state Rails passes product as props (no async/await or direct data-layer calls).
RSC data fetching
docs/oss/migrating/rsc-data-fetching.md
Reframed guidance to a props-first React on Rails flow: recommend rendering without async/await or direct data-layer calls; advise using async props + Suspense for slow data. Clarified React Query initialData behavior, added alternative server-side cache seeding via dehydrate/HydrationBoundary, refined notes on avoiding waterfalls and React.cache(), and adjusted "When to Keep Client-Side Fetching" framing.
Tooling / meta
/.lychee.toml, react_on_rails_pro/CONTRIBUTING.md, NEWS.md
Added two URL exclusion regexes to Lychee's exclude list and normalized a docs URL to include a trailing slash; updated two NEWS.md links to point to https://reactonrails.com/docs/.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nibble docs where Rails seeds grow,
Props tumble down where fresh data flows,
Async props hum while slow bits bake,
Client code lightens with every break,
Hooray—less bundle, more carrot cake 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes (docs/oss/migrating files and react_on_rails_pro/CONTRIBUTING.md) are directly in-scope. However, .lychee.toml link exclusions and NEWS.md URL updates appear unrelated to the RSC migration docs reframing objective. Remove unrelated changes: the .lychee.toml exclusions and NEWS.md URL updates should be in a separate maintenance PR, not bundled with documentation reframing.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: reframing RSC migration docs to center React on Rails patterns rather than generic approaches.
Linked Issues check ✅ Passed All four objectives from issue #2526 are addressed: D1 updated data-fetching.md to lead with async props and Rails props, D2 reframed component patterns with bundle size/streaming motivation, D3 refined the fetching table with Rails context, and D4 ensured consistency with async props usage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2526-rsc-migration-docs-structural-and-framing-improvements

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 17, 2026

Greptile Summary

This 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:

  • rsc-data-fetching.md: Pattern 1 "After" example now uses ProductList({ products }) instead of async function ProductList() + await getProducts(); Pattern 2 replaced the dehydrate/HydrationBoundary prefetch pattern with an initialData approach seeded from Rails props; contextual "React on Rails note" callouts added to the waterfalls, use(), and React.cache() sections.
  • rsc-component-patterns.md: Pattern 1 heading and intro reframed from "move data fetching to server" to "reduce bundle size / eliminate unnecessary JavaScript / enable streaming"; the After example simplified to accept product as a prop.
  • rsc-context-and-state.md: Two code examples (multi-provider composition and Redux donut pattern) updated to accept product as a prop rather than calling await getProduct(productId).

Issues found:

  • The initialData example in Pattern 2 (React Query) omits initialDataUpdatedAt, which causes React Query to treat the Rails data as immediately stale and fire a background refetch on every component mount. initialDataUpdatedAt: Date.now() (or a non-zero staleTime) should be added or at least noted.
  • The "Hybrid Pattern: Server Fetch + Client Updates" example in the "When to Keep Client-Side Fetching" section still uses async function ChatPage + await getMessages(channelId) — the exact pattern the PR now explicitly marks as "not recommended."
  • The Migration Checklist numbered list skips item 6 after two steps were removed from Step 2 (now ends at 5), while Step 3 still starts at 7.

Confidence Score: 3/5

  • Safe to merge after addressing the initialData stale-time omission and the inconsistent Hybrid Pattern example, which could mislead readers following the guide.
  • The doc changes are well-targeted and the Rails-props framing is clearer. However, the initialData example without initialDataUpdatedAt is a factual gap that could cause production apps to make unnecessary API calls, the Hybrid Pattern example directly contradicts the PR's core advisory, and there is a numbered-list continuity error in the checklist. These issues lower confidence slightly below a clean merge.
  • docs/oss/migrating/rsc-data-fetching.md — the initialData stale-time behavior, the Hybrid Pattern inconsistency, and the numbered-list skip all live here.

Important Files Changed

Filename Overview
docs/oss/migrating/rsc-data-fetching.md Most substantive changes: Pattern 1 and Pattern 2 re-framed around Rails props; added React on Rails contextual notes to waterfalls, use(), and React.cache() sections. Three issues found: (1) numbered list skips item 6 after step removal, (2) initialData without initialDataUpdatedAt causes immediate background refetch on every mount, (3) the unmodified "Hybrid Pattern" example still uses the async/await + direct data layer call pattern the PR now explicitly labels as not recommended.
docs/oss/migrating/rsc-component-patterns.md Added a "React on Rails context" callout to Pattern 1 reframing the goal from "move data fetching to server" to "reduce bundle size / eliminate unnecessary JS / enable streaming." Section heading updated from "State pushed to a leaf, data fetched on server" to "State pushed to a leaf, JavaScript eliminated." The example was also simplified to remove async/await and accept product as a prop. Changes are clear and consistent.
docs/oss/migrating/rsc-context-and-state.md Two examples updated to accept product as a prop instead of calling await getProduct(productId) — one in the multi-provider composition example and one in the Redux donut pattern. Both are clean, consistent changes that align with the rest of the PR's Rails-props framing.

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]
Loading

Comments Outside Diff (2)

  1. docs/oss/migrating/rsc-data-fetching.md, line 937-939 (link)

    P2 Numbered list skips item 6 after step reduction

    Step 2 now ends at item 5 (two items were removed from the original 1-6 list), but Step 3 still starts at item 7, skipping 6 entirely. This is a markdown authoring bug introduced by the removal of the old steps 4 and 5.

    Should be:

  2. docs/oss/migrating/rsc-data-fetching.md, line 811-824 (link)

    P2 Hybrid Pattern uses async/await with direct data layer calls — inconsistent with PR's central guidance

    The "Hybrid Pattern: Server Fetch + Client Updates" example (unchanged by this PR) directly contradicts the PR's core message. Line 815 uses:

    export default async function ChatPage({ channelId }) {
      const initialMessages = await getMessages(channelId);

    This is exactly the async function + await + direct data layer call pattern that the PR's new note (added just above at line 232) says "bypasses Rails' authorization and caching layers and is not recommended."

    Since this PR is specifically reframing the docs around Rails patterns, it should either:

    1. Rewrite this example to use Rails props (ChatPage({ channelId, initialMessages })) — valid because initialMessages could come from a Rails controller action, and
    2. Or add a contextual note explaining why this specific case is an exception (e.g., because the channel content is dynamic per-user action and cannot be pre-fetched by the controller the same way).

    Leaving this example unaddressed weakens the consistency of the new framing and will likely confuse readers who follow the guide top to bottom.

Last reviewed commit: b79e87b

Comment thread docs/oss/migrating/rsc-data-fetching.md
Comment thread docs/oss/migrating/rsc-data-fetching.md
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 17, 2026

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.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 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/HydrationBoundary is 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

📥 Commits

Reviewing files that changed from the base of the PR and between b79e87b and e3bb9e6.

📒 Files selected for processing (2)
  • docs/oss/migrating/rsc-component-patterns.md
  • docs/oss/migrating/rsc-data-fetching.md
✅ Files skipped from review due to trivial changes (1)
  • docs/oss/migrating/rsc-component-patterns.md

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 27, 2026

Overall this is a solid, focused improvement. The framing changes are accurate and the additions (TanStack Query dehydrate/HydrationBoundary tip, async props callouts, initialData inline comment) will genuinely help readers unfamiliar with the Rails-props-first mental model.

Three things worth addressing:

D4 not reflected in the diff: The description says D4 replaced await getProduct(productId) with Rails props in rsc-context-and-state.md, but that file is not in the diff and that pattern is not present in it today. Either this was done in a prior commit and the description is stale, or it was planned but not implemented. Please clarify or add the missing change.

getReactOnRailsAsyncProp(key) needs a Pro attribution and link: The updated React.cache() note references this function without indicating it lives in the Pro package. OSS-only readers will not find it. It should be marked as "(React on Rails Pro)" with a link to the relevant Pro docs section.

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.

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 27, 2026

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 # 750ms total comment) still illustrates it. Worth deciding whether the total-time framing belongs in the prose or if the code comment is sufficient.

Everything else looks solid:

  • The Pattern 1 context note clearly distinguishes Rails RSC adoption goals from generic RSC goals.
  • The React.cache() note's mention of getReactOnRailsAsyncProp(key) caching behaviour is a useful addition.
  • The TanStack Query dehydrate/HydrationBoundary alternative note is a good pointer for complex cases.
  • The .lychee.toml exclusion is well-commented.

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Comment thread docs/oss/migrating/rsc-data-fetching.md
Comment thread docs/oss/migrating/rsc-data-fetching.md
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 27, 2026

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: getReactOnRailsAsyncProp(key) at line 537 of rsc-data-fetching.md - this function name does not exist anywhere in the codebase (searched OSS and Pro packages). A wrong API name in migration docs is a direct user trap. See the inline comment.

Two minor items: (1) The new TanStack Query link to tanstack.com/query/... is not covered by the existing lychee exclusion (which only targets tanstack.com/router). Worth watching whether the lychee CI job passes. (2) A blank line between StatsPanel and PostFeed in the waterfall examples was removed - cosmetic, but restoring it improves readability.

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 data-fetching-in-react-on-rails-pro are valid. The React Query initialData and SWR fallbackData examples are correct. The dehydrate/HydrationBoundary alternative is a useful addition. The CONTRIBUTING.md trailing-slash fix is correct. The new lychee exclusions are well-targeted.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 27, 2026

Review: Reframe RSC migration docs around React on Rails patterns

Overall 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:

  • The "React on Rails context" callout in Pattern 1 accurately corrects a common misconception — Rails already handles server-side data, so the RSC migration goal is bundle reduction and streaming, not "moving data to the server"
  • The React.cache() note mentioning getReactOnRailsAsyncProp(key) returning a cached Promise is a valuable technical detail
  • The TanStack Query dehydrate/HydrationBoundary alternative note fills a real documentation gap for complex multi-query cases
  • URL updates in NEWS.md and CONTRIBUTING.md are appropriate housekeeping

Minor observations:

  1. PR description D4 vs actual diff: The description claims D4 "Replaced await getProduct(productId) with Rails props in Pattern 2 and Redux examples in context-and-state guide", but rsc-context-and-state.md is not in the diff. Checking that file, it already uses the Rails props pattern (e.g., ProductPage({ product }) at the Redux Toolkit example). The description appears to reference prior work — worth updating the PR description for accuracy.

  2. Blank line removed between StatsPanel and PostFeed (rsc-data-fetching.md line ~388): The diff removes a blank line separating two function component definitions in a code example. For code readability, keeping the blank line between top-level function declarations is conventional JS/React style.

  3. Wording in waterfalls section: The new blockquote ("The primary React on Rails solutions are controller props and async props") reads a bit abruptly as the section opening since it precedes "### The Problem" without a transitional sentence. The old prose ("the most critical performance pitfall is sequential data fetching...") served as better context-setting before the problem/solution structure.

None of these block merging. The documentation changes are accurate and valuable.

Comment thread docs/oss/migrating/rsc-data-fetching.md
Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Comment thread docs/oss/migrating/rsc-data-fetching.md
Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
Comment thread docs/oss/migrating/rsc-data-fetching.md
Comment thread docs/oss/migrating/rsc-data-fetching.md
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 28, 2026

Review: Reframe RSC migration docs around React on Rails patterns

The 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

getReactOnRailsAsyncProp(key) does not exist in the codebase (line 543, rsc-data-fetching.md). Grepping both OSS and Pro packages returns zero matches. Documenting a phantom API in migration docs is a hard user trap — see the inline comment for options.

Should-fix

Missing lychee exclusion for tanstack.com/query (line 265). The existing exclusion covers tanstack.com/router; the new TanStack Query SSR link uses tanstack.com/query and is not excluded. This will likely fail the link-checker CI job if that domain has the same intermittent timeout issues. Add the exclusion to .lychee.toml alongside the existing one.

Minor

  • Waterfall section opener (line 310): The replacement blockquote leads with solutions before the reader has seen the problem. The original prose sentence ("when queries execute one after another, rendering is delayed by their total time") was the motivation — consider folding it into the new blockquote rather than dropping it. Inline suggestion provided.

  • Blank line between StatsPanel and PostFeed (line 392): The diff removes the blank line separating two top-level function declarations in the code example. Restoring it costs nothing and improves scannability. Inline suggestion provided.

  • PR description D4 is stale: The description says D4 "Replaced await getProduct(productId) with Rails props in Pattern 2 and Redux examples in context-and-state guide," but rsc-context-and-state.md is not in the diff and already uses the Rails props pattern. The description appears to reference prior work. Worth updating to avoid reviewer confusion.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 28, 2026

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.

Comment thread react_on_rails/lib/react_on_rails/doctor.rb Fixed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 29, 2026

size-limit report 📦

Path Size
react-on-rails/client bundled (gzip) 62.63 KB (0%)
react-on-rails/client bundled (gzip) (time) 62.63 KB (0%)
react-on-rails/client bundled (brotli) 53.7 KB (0%)
react-on-rails/client bundled (brotli) (time) 53.7 KB (0%)
react-on-rails-pro/client bundled (gzip) 63.65 KB (0%)
react-on-rails-pro/client bundled (gzip) (time) 63.65 KB (0%)
react-on-rails-pro/client bundled (brotli) 54.67 KB (0%)
react-on-rails-pro/client bundled (brotli) (time) 54.67 KB (0%)
registerServerComponent/client bundled (gzip) 127.46 KB (0%)
registerServerComponent/client bundled (gzip) (time) 127.46 KB (0%)
registerServerComponent/client bundled (brotli) 61.65 KB (0%)
registerServerComponent/client bundled (brotli) (time) 61.65 KB (0%)
wrapServerComponentRenderer/client bundled (gzip) 122.02 KB (0%)
wrapServerComponentRenderer/client bundled (gzip) (time) 122.02 KB (0%)
wrapServerComponentRenderer/client bundled (brotli) 56.77 KB (0%)
wrapServerComponentRenderer/client bundled (brotli) (time) 56.77 KB (0%)

AbanoubGhadban and others added 12 commits March 28, 2026 19:39
- 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]>
@justin808 justin808 force-pushed the 2526-rsc-migration-docs-structural-and-framing-improvements branch from d5f0c20 to eebe38d Compare March 29, 2026 05:41
Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 29, 2026

Review: Reframe RSC migration docs around React on Rails patterns

The 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 docs/oss/migrating/rsc-data-fetching.md contain an exact duplicate of the > **Alternative:** blockquote (the TanStack Query dehydrate/HydrationBoundary note). The second copy should be removed. I've left an inline suggestion.

Everything else looks good:

  • NEWS.md: correctly removes the two duplicated 2016 entries.
  • .lychee.toml: the added exclusions are well-commented and scoped tightly (anchored regexes, inline rationale). The GitHub PR link exclusions are appropriate given intermittent 502s from CI.
  • react_on_rails_pro/CONTRIBUTING.md: trailing-slash fix on the docs URL is correct.
  • The reframed Pattern 1 note (controller prepares data, no async/await in the component, recommendation against bypassing Rails auth/caching) is accurate and adds useful context for developers coming from other RSC frameworks.
  • The initialDataUpdatedAt/staleTime clarification and the React.cache() async-props callout are both accurate improvements over the previous text.

@justin808
Copy link
Copy Markdown
Member

Follow-up on skipped feedback triage:\n\n- initialDataUpdatedAt/staleTime gap: skipped because current content already includes both settings and explanatory notes.\n- getReactOnRailsAsyncProp API-name concern: skipped as stale after rebase; the current text no longer names that API directly.\n- Hybrid pattern async/await concern: skipped as stale; the current ChatPage example is props-based.\n- PR description mismatch (D4): skipped because the PR description was already updated to match the current 4-file scope.\n- Remaining blank-line/prose/note-consolidation suggestions: skipped as non-blocking editorial preference items for this PR scope.\n\nIf you want, I can take a separate docs-polish pass for those purely editorial suggestions in a follow-up PR.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 29, 2026

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.

Comment thread docs/oss/migrating/rsc-data-fetching.md Outdated
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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 }) {
}
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 }) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 + await pattern 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.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 29, 2026

Review Summary

This 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

  • ERB block reordering (Pattern 1): Moving the ERB snippet before the After JSX component improves reading flow.
  • as_json(only: [:id, :name]): Scoping serialized fields avoids accidentally exposing sensitive columns in copy-pasted examples — good security improvement over the bare as_json call.
  • Expanded initialDataUpdatedAt / staleTime note: the original was easy to misread as pick one.
  • TanStack Query dehydrate/HydrationBoundary callout: good addition for teams with more complex query graphs.

Minor issues (see inline comments)

  1. Blank line dropped between functions — the diff incidentally removes the separator between StatsPanel and PostFeed in the waterfall example.
  2. The bypasses Rails authorization wording is too absolute — the async Server Component pattern only bypasses Rails auth layers if the developer omits the checks. Worth softening to avoid stating it as a categorical technical fact.

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.

@justin808 justin808 merged commit c4f4411 into main Mar 29, 2026
12 checks passed
@justin808 justin808 deleted the 2526-rsc-migration-docs-structural-and-framing-improvements branch March 29, 2026 08:15
justin808 added a commit that referenced this pull request Mar 29, 2026
…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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RSC migration docs: Structural and framing improvements

2 participants