Skip to content

docs: RSC integration pitfalls from tutorial app#3087

Merged
justin808 merged 5 commits into
mainfrom
jg/3076-rsc-pitfalls-docs
Apr 13, 2026
Merged

docs: RSC integration pitfalls from tutorial app#3087
justin808 merged 5 commits into
mainfrom
jg/3076-rsc-pitfalls-docs

Conversation

@justin808

@justin808 justin808 commented Apr 9, 2026

Copy link
Copy Markdown
Member

Summary

Documents five real-world RSC integration pitfalls discovered during the react-webpack-rails-tutorial RSC integration:

  • VM sandbox constraints (rendering-flow.md, rsc-troubleshooting.md): Documents why externals must not be used for Node builtins in the server bundle (generates require() calls that fail in the VM sandbox), and that resolve.fallback: false is the correct approach
  • MessageChannel polyfill (rsc-troubleshooting.md): Documents the BannerPlugin polyfill pattern for react-dom/server.browser.js which needs MessageChannel at module load time
  • 'use client' classification audit (upgrading-existing-pro-app.md): Adds a pre-migration section covering the .server.jsx naming collision, how auto-classification works, and a checklist of client APIs to audit for
  • CI/test environment setup (basics.md): Documents Rails.env.local? vs Rails.env.development?, TCP readiness checks, RENDERER_PASSWORD in CI, and a common CI failures table
  • Three-bundle architecture table (rendering-flow.md): Adds a reference table comparing all three bundles across runtime, Node builtin handling, require() availability, CSS extraction, and env vars

Closes #3076

Test plan

  • Verify all markdown links resolve (pre-push hook validates this)
  • Verify formatting passes prettier (pre-commit hook validates this)
  • Review each doc section for technical accuracy against the tutorial PR

🤖 Generated with Claude Code


Note

Low Risk
Low risk because changes are documentation-only, though reviewers should sanity-check technical accuracy of the new webpack/VM and CI guidance.

Overview
Adds a new CI/test setup section for the Node Renderer, including Rails.env.local? initializer guarding, a GitHub Actions example that starts the renderer with an HTTP/2 (h2c) readiness probe, RENDERER_PASSWORD guidance, and a common-failures table.

Expands RSC troubleshooting and Pro RSC docs to clarify bundle runtime differences (client vs SSR server bundle VM sandbox vs full-Node RSC bundle), document require()/missing-global failure modes, recommend resolve.fallback: false over webpack externals for Node builtins in the server bundle, and add guidance for handling missing MessageChannel (polyfill via BannerPlugin / prefer additionalContext).

Adds a pre-migration checklist for existing Pro apps to audit for client-only APIs and warns about the .server.jsx naming collision that can cause unintended Server Component classification without 'use client'.

Reviewed by Cursor Bugbot for commit bf26cb1. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Documentation
    • Added CI/test SSR setup with readiness checks, env guidance, retry/fail behavior, and mapped common CI failure symptoms to fixes.
    • Expanded runtime and bundle architecture guidance, clarifying sandboxed server vs full-Node RSC constraints and safer handling of Node builtins to avoid runtime require failures.
    • Added troubleshooting entries for missing globals (require, MessageChannel) and guidance for polyfill or context-injection fixes.

Document five real-world RSC integration issues discovered during
react-webpack-rails-tutorial integration:

- VM sandbox constraints: externals vs resolve.fallback, require()
  unavailability in server bundle
- MessageChannel polyfill: BannerPlugin pattern for react-dom/server
- 'use client' classification audit: .server.jsx naming collision,
  auto-classification gotchas, migration checklist
- CI/test setup: Rails.env.local? guard, TCP readiness check, common
  CI failure table
- Three-bundle architecture reference table comparing runtimes,
  constraints, and env vars across client/server/RSC bundles

Closes #3076

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Added documentation clarifying Node renderer CI/test setup, VM-sandbox constraints for the server (SSR) bundle, a bundle-architecture reference distinguishing client/server/RSC runtimes, and a pre-migration audit for detecting client-only API usage before enabling React Server Components.

Changes

Cohort / File(s) Summary
Node Renderer CI & Test Setup
docs/oss/building-features/node-renderer/basics.md
Adds "CI and Test Environment Setup": use Rails.env.local? (or include test), start client/node-renderer.js in CI as a background process, poll http://localhost:3800/ with retries, require RENDERER_PASSWORD/RENDERER_BUNDLE_PATH, and map common CI failure symptoms to fixes.
RSC Troubleshooting & VM Sandbox Diagnostics
docs/oss/migrating/rsc-troubleshooting.md
Expanded diagnostics: added ReferenceError: require is not defined and ReferenceError: MessageChannel is not defined rows; clarified that missing globals apply to the server (VM) bundle only; added "Handling Node Builtins -- externals vs resolve.fallback" guidance and "MessageChannel Not Defined" with BannerPlugin polyfill and additionalContext alternatives.
Bundle Architecture Reference
docs/pro/react-server-components/rendering-flow.md
Extended "Types of Bundles" with explicit runtime constraints for Client, Server (VM sandbox), and RSC (full Node); added a "Bundle Architecture Reference" comparison table and highlighted the pitfall that webpack externals can emit require() which fails in the server VM.
RSC Pre-Migration Audit
docs/pro/react-server-components/upgrading-existing-pro-app.md
Inserted "Pre-Migration: Audit Components for Client API Usage": checklist of client-only APIs (hooks, React-on-Rails client APIs, Redux/router, event handlers, browser globals), explained .server.jsx naming collision vs RSC semantics, and described auto-classification behavior and recommendation to add 'use client' when uncertain.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 I hopped through docs to tidy the trail,

Ports polled, guards swapped, and bundles set right,
MessageChannel patched with a gentle byte,
'use client' lit paths that once were frail,
CI hums — tests wake up without fail.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'docs: RSC integration pitfalls from tutorial app' clearly and specifically describes the main change—adding documentation about real-world RSC integration challenges discovered during tutorial app development.
Linked Issues check ✅ Passed All five objectives from issue #3076 are fully addressed: VM sandbox constraints documented with resolve.fallback guidance [rendering-flow.md, rsc-troubleshooting.md], MessageChannel polyfill pattern provided [rsc-troubleshooting.md], 'use client' classification gotcha covered with audit checklist [upgrading-existing-pro-app.md], CI setup with readiness checks and Rails.env guidance [basics.md], and three-bundle architecture table added [rendering-flow.md].
Out of Scope Changes check ✅ Passed All changes are directly related to the five RSC integration pitfalls documented in issue #3076; documentation additions address VM sandbox constraints, MessageChannel requirements, 'use client' classification, CI setup, and bundle architecture—with no unrelated changes.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg/3076-rsc-pitfalls-docs

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/pro/react-server-components/upgrading-existing-pro-app.md Outdated
Comment thread docs/oss/building-features/node-renderer/basics.md Outdated
Comment thread docs/oss/migrating/rsc-troubleshooting.md Outdated
Comment thread docs/oss/migrating/rsc-troubleshooting.md Outdated
@claude

claude Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Review: docs — RSC integration pitfalls

Overall this is a valuable addition. The five pitfall categories are accurate, well-structured, and clearly sourced from real-world integration work. A few technical corrections are needed before merge:

Issues (inline comments posted)

  1. StaticRouter misclassified as a client API (upgrading-existing-pro-app.md line 44)
    StaticRouter is a server-side router for SSR — it is not a client API alongside useNavigate/useLocation. The reason a file using StaticRouter needs 'use client' is the .server.jsx naming collision you document in the very next section, not because StaticRouter itself is client-side. Grouping them together sends the wrong mental model to readers.

  2. CI readiness loop has no failure exit (basics.md lines 162–169)
    The for loop that polls port 3800 exits silently on timeout. If the renderer never starts, the CI step still passes and every downstream test hits Net::ReadTimeout — exactly the confusing failure this section warns against. Add a curl check + exit 1 after the loop.

  3. additionalContext timing claim is inaccurate (rsc-troubleshooting.md line 914)
    The note says additionalContext "may not take effect early enough depending on your bundling setup." This isn't correct — additionalContext is merged into the VM context before vm.runInContext() fires, so it is always available during module initialization. Both additionalContext and BannerPlugin work; the choice is one of preference, not timing reliability.

  4. resolve.fallback: false described as "empty object" (rsc-troubleshooting.md line 873)
    resolve.fallback: { path: false } omits the module entirely (no shim is bundled); the import resolves to undefined, not {}. The key correctness point (no require() call is emitted) stands, but the "empty object" description is inaccurate.

Minor observations (no inline comment)

  • The Bundle Architecture Reference table in rendering-flow.md is an excellent quick-reference; the cross-links to the troubleshooting guide work well.
  • The pre-migration audit checklist in upgrading-existing-pro-app.md is a practical addition. The "when in doubt, add 'use client'" advice is safe and correct.
  • Rails.env.local? availability note (Rails 7.1+) with fallback for older versions is a nice touch.

@greptile-apps

greptile-apps Bot commented Apr 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds documentation for five real-world RSC integration pitfalls discovered during a tutorial app migration: VM sandbox constraints (externals vs resolve.fallback), the MessageChannel polyfill pattern, 'use client' classification audit guidance, CI/test environment setup for the Node Renderer, and a three-bundle architecture reference table. All changes are docs-only with no code modifications.

The documentation is thorough and technically accurate overall, with a few minor clarifications worth considering before merge.

Confidence Score: 5/5

Safe to merge — all findings are P2 style/clarification suggestions with no correctness or data-integrity impact.

All four comments are P2 (non-blocking suggestions): a missing exit-1 in example CI YAML, a note about env var scoping in the CI example, a misleading link text, and a minor framing issue around StaticRouter. None affect production behavior or introduce incorrect technical guidance. The core technical content (externals vs resolve.fallback, MessageChannel polyfill, Rails.env.local?, auto-classification) is accurate.

docs/oss/building-features/node-renderer/basics.md — CI example could mislead users into incomplete RENDERER_PASSWORD setup across job steps.

Vulnerabilities

No security concerns identified. The documentation correctly notes that RENDERER_PASSWORD should be stored as a CI secret (not hardcoded), and the existing security guidance about binding the renderer to localhost and never exposing it to the public internet is preserved.

Important Files Changed

Filename Overview
docs/oss/building-features/node-renderer/basics.md Adds "CI and Test Environment Setup" section; CI readiness loop silently continues if renderer never starts, and RENDERER_PASSWORD is only scoped to the renderer step rather than the Rails test step.
docs/oss/migrating/rsc-troubleshooting.md Adds externals vs resolve.fallback pitfall and MessageChannel BannerPlugin polyfill sections; technically accurate and well-explained.
docs/pro/react-server-components/rendering-flow.md Adds bundle architecture reference table and externals pitfall callout; internal link text "VM Sandbox Constraints" doesn't match the target section title "Bundle Architecture Reference".
docs/pro/react-server-components/upgrading-existing-pro-app.md Adds pre-migration client API audit section; StaticRouter is listed as a "client API requiring 'use client'" but it is a server-side router — the framing could mislead developers into thinking it always requires the directive.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Component file] --> B{Has 'use client'?}
    B -- Yes --> C[Registered via ReactOnRails.register]
    B -- No --> D[Registered via registerServerComponent]
    C --> E[Client Component - Browser runtime]
    D --> F[Server Component - RSC Bundle full Node.js]
    D --> G[SSR via Server Bundle - VM sandbox no require]

    subgraph ServerBundle[Server Bundle VM Sandbox]
        G
        H[resolve.fallback false - Node builtins to empty modules]
        I[externals commonjs path - generates require crash]
        J[BannerPlugin MessageChannel polyfill - injects before module init]
    end

    subgraph CI[CI Setup]
        K[Start node-renderer.js background]
        L[Poll port 3800 readiness]
        M[Run Rails tests]
        K --> L --> M
    end
Loading

Reviews (1): Last reviewed commit: "docs: add RSC integration pitfalls from ..." | Re-trigger Greptile

Comment thread docs/oss/building-features/node-renderer/basics.md Outdated
Comment thread docs/oss/building-features/node-renderer/basics.md Outdated
Comment thread docs/pro/react-server-components/upgrading-existing-pro-app.md Outdated
Comment thread docs/pro/react-server-components/rendering-flow.md Outdated

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

Copy link
Copy Markdown

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: 4d95bb7045

ℹ️ 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/building-features/node-renderer/basics.md Outdated
Comment thread docs/oss/migrating/rsc-troubleshooting.md Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/pro/react-server-components/upgrading-existing-pro-app.md (1)

33-78: LGTM! Pre-migration audit section is comprehensive and clear.

The new section effectively addresses the .server.jsx naming collision and auto-classification gotcha. The client API checklist is thorough and the explanation clearly distinguishes between file suffix bundling (.server.jsx for SSR) and RSC directive classification ('use client').

Optional enhancement: Line 66 mentions runtime errors like "useState is not a function" -- consider adding a forward reference to the troubleshooting guide to help readers quickly resolve those errors:

📖 Optional cross-reference enhancement
 There is no warning when a component is auto-classified as a server component. If it uses client APIs, it will fail at runtime with errors like "useState is not a function" or "Cannot read properties of undefined."
+
+> **Tip:** See [RSC Troubleshooting](../../oss/migrating/rsc-troubleshooting.md) for a complete error message catalog and solutions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/pro/react-server-components/upgrading-existing-pro-app.md` around lines
33 - 78, Add a brief forward reference to the troubleshooting guide where
runtime errors are mentioned (the sentence containing "useState is not a
function" / "Cannot read properties of undefined") so readers can quickly
navigate to remediation steps; update the paragraph under "How
auto-classification works" to append something like "See the troubleshooting
guide for common RSC runtime errors" and link or point to the existing
Troubleshooting section or doc page you maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/pro/react-server-components/rendering-flow.md`:
- Around line 37-49: The doc incorrectly states that resolve.fallback is a
server-bundle setting; update the "Server Bundle (SSR)" and "Client Bundle"
descriptions and the "Key pitfall" paragraph to state that resolve.fallback
(e.g., resolve.fallback: { fs: false, path: false, stream: false }) is used by
the client bundle to avoid generating require() calls for browser builds, while
the server bundle uses target: 'node' (so Node builtins are natively supported
and do not need resolve.fallback) and that using externals on the server can
produce require() calls that fail in non-Node VM contexts; adjust the table row
for "Node builtins" and the pitfall text to clearly distinguish "what webpack
generates (externals)" vs "how webpack handles imports (resolve.fallback)" for
each bundle, referencing the "Client Bundle", "Server Bundle (SSR)",
`resolve.fallback`, `externals`, and `target: 'node'` tokens to locate the
edits.

---

Nitpick comments:
In `@docs/pro/react-server-components/upgrading-existing-pro-app.md`:
- Around line 33-78: Add a brief forward reference to the troubleshooting guide
where runtime errors are mentioned (the sentence containing "useState is not a
function" / "Cannot read properties of undefined") so readers can quickly
navigate to remediation steps; update the paragraph under "How
auto-classification works" to append something like "See the troubleshooting
guide for common RSC runtime errors" and link or point to the existing
Troubleshooting section or doc page you maintain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bdf09b4d-2356-4b90-9656-174348deaf9f

📥 Commits

Reviewing files that changed from the base of the PR and between 16ac897 and 4d95bb7.

📒 Files selected for processing (4)
  • docs/oss/building-features/node-renderer/basics.md
  • docs/oss/migrating/rsc-troubleshooting.md
  • docs/pro/react-server-components/rendering-flow.md
  • docs/pro/react-server-components/upgrading-existing-pro-app.md

Comment thread docs/pro/react-server-components/rendering-flow.md Outdated
- Separate StaticRouter from client API list (it's an SSR router, not a client API)
- Add failure exit to CI readiness loop when renderer never starts
- Fix inaccurate additionalContext timing claim (both approaches work)
- Fix resolve.fallback description (omits module, not empty object)
- Fix link text mismatch (VM Sandbox Constraints → Bundle Architecture Reference)
- Add note about RENDERER_PASSWORD needing job-level scope in CI
- Scope externals guidance: note that externals work with supportModules enabled
- Clarify resolve.fallback usage across client and server bundles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@justin808

Copy link
Copy Markdown
Member Author

Review feedback addressed in 4281a61

All 11 review threads resolved. Changes in a single commit:

Technical corrections (4):

  1. StaticRouter reclassified — moved from "client APIs" to "SSR entry-point files" with cross-ref to .server.jsx naming collision
  2. CI readiness loop — added curl check + exit 1 after the loop so CI fails fast instead of silently proceeding to timeout
  3. additionalContext timing — removed inaccurate "may not take effect early enough" claim; both BannerPlugin and additionalContext work
  4. resolve.fallback description — corrected from "empty object" to "omits the module" (resolves to undefined, not {})

Clarifications (4):
5. Link text mismatch — "VM Sandbox Constraints" → "Bundle Architecture Reference" to match heading
6. RENDERER_PASSWORD scope — added note to declare at job level so Rails test step can also read it
7. externals guidance scoped — added note that externals work when supportModules/additionalContext injects require into the VM
8. Bundle architecture table — client bundle now shows resolve.fallback usage; server bundle notes supportModules exception; RSC bundle notes target: 'node'

3 duplicate threads (greptile, codex) replied to and resolved.

Comment thread docs/oss/building-features/node-renderer/basics.md Outdated

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
docs/oss/migrating/rsc-troubleshooting.md (1)

736-736: Align the fallback snippet with the detailed section.

Line 736 omits stream: false, but the canonical config later includes it. Please make both examples identical to avoid partial copy/paste fixes.

Suggested docs diff
-| `ReferenceError: require is not defined`                                                                                     | Server bundle webpack config uses `externals` for Node builtins, generating `require()` calls that fail in VM sandbox                                                                              | Use `resolve.fallback: { path: false, fs: false }` instead of `externals`. See [Handling Node Builtins](`#handling-node-builtins----externals-vs-resolvefallback`)                                                                                                       |
+| `ReferenceError: require is not defined`                                                                                     | Server bundle webpack config uses `externals` for Node builtins, generating `require()` calls that fail in VM sandbox                                                                              | Use `resolve.fallback: { path: false, fs: false, stream: false }` instead of `externals`. See [Handling Node Builtins](`#handling-node-builtins----externals-vs-resolvefallback`)                                                                                          |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oss/migrating/rsc-troubleshooting.md` at line 736, The docs table entry
shows using resolve.fallback: { path: false, fs: false } but omits stream,
causing inconsistency with the canonical example; update the short table snippet
to include stream: false so it exactly matches the detailed section (use the
same resolve.fallback keys: path, fs, and stream) and ensure the phrase
references resolve.fallback consistently to avoid partial copy/paste errors.
🤖 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-troubleshooting.md`:
- Line 736: The docs table entry shows using resolve.fallback: { path: false,
fs: false } but omits stream, causing inconsistency with the canonical example;
update the short table snippet to include stream: false so it exactly matches
the detailed section (use the same resolve.fallback keys: path, fs, and stream)
and ensure the phrase references resolve.fallback consistently to avoid partial
copy/paste errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dc8d1cc6-06e4-4922-8172-57fd747a463d

📥 Commits

Reviewing files that changed from the base of the PR and between 4d95bb7 and 4281a61.

📒 Files selected for processing (4)
  • docs/oss/building-features/node-renderer/basics.md
  • docs/oss/migrating/rsc-troubleshooting.md
  • docs/pro/react-server-components/rendering-flow.md
  • docs/pro/react-server-components/upgrading-existing-pro-app.md
✅ Files skipped from review due to trivial changes (1)
  • docs/oss/building-features/node-renderer/basics.md

Comment thread docs/oss/building-features/node-renderer/basics.md Outdated
Comment thread docs/oss/migrating/rsc-troubleshooting.md
Comment thread docs/pro/react-server-components/upgrading-existing-pro-app.md Outdated
Comment thread docs/pro/react-server-components/upgrading-existing-pro-app.md Outdated
@claude

claude Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review: RSC Integration Pitfalls Documentation

Overall this is a high-quality, clearly structured documentation PR. The content is technically accurate and directly addresses real integration pain points. A few issues worth addressing before merge:

Functional issue (blocks correct CI setup)

RENDERER_PASSWORD env var scope in the CI snippet (line 176): The example YAML declares RENDERER_PASSWORD at the step level, but the key-points text (correctly) says it must be at the job level so Rails can read it during the test step. A reader copying the snippet verbatim will hit "Invalid password" failures — the exact scenario this section exists to prevent. Recommend restructuring the example to show the job-level env: block.

Minor robustness issues

  • curl readiness loop without --max-time (line 163): Without a per-request timeout, each probe could stall for the OS default (~30s) if the port is open but the process is hung, turning a 30-second poll loop into a 15-minute one. Adding --max-time 2 keeps the loop snappy.

  • MessageChannel polyfill delivers synchronously (line 884): React's scheduler expects MessageChannel to fire as a macrotask; the polyfill fires it synchronously. This works for current SSR streaming scenarios (verified by the tutorial PR), but deserves a caveat note so readers know to fall back to additionalContext with the real Node.js MessageChannel if they encounter recursive scheduling issues.

Documentation completeness

  • Missing React hooks in the 'use client' audit list (line 41): useTransition, useDeferredValue, useOptimistic, useFormStatus, useId are absent. These appear in performance-optimized components and are easy to miss during migration.

  • Grep checklist misses React Router v6 components (line 73): <Link>, <NavLink>, <Navigate>, useNavigate, useLocation, useParams all require 'use client' and are common in existing apps.

Nits (no action required)

  • The bundle architecture table in rendering-flow.md says "Use resolve.fallback: false to omit" for the client bundle too. This is accurate but might confuse readers who don't expect Node builtins to appear in a client bundle — a parenthetical "(for any accidentally-imported Node builtins)" would clarify the intent.
  • The rsc-troubleshooting.md quick-reference table now has entries for require is not defined and MessageChannel is not defined, but the symptom column says just the ReferenceError — consider matching the format of other rows which give a bit more context about when the error fires.

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

Copy link
Copy Markdown

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: 4281a61454

ℹ️ 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/pro/react-server-components/upgrading-existing-pro-app.md Outdated
- Fix .server.jsx rename recommendation: renaming to .ssr.jsx breaks
  auto-bundling (packs_generator.rb uses Dir.glob("*.server.*"))
- Add missing React 18/19 hooks to client API audit list:
  useTransition, useDeferredValue, useId, useOptimistic, useFormStatus
- Add router hooks to grep checklist: useNavigate, useLocation, useParams
- Restructure CI YAML to show RENDERER_PASSWORD at job level
- Add --max-time 2 to curl readiness probe to prevent stalled hangs
- Add MessageChannel polyfill sync semantics caveat with
  additionalContext fallback note

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@justin808

Copy link
Copy Markdown
Member Author

Review feedback addressed in 08bd481

All 6 remaining review threads resolved. Changes in a single commit:

Critical fix (1):

  1. .server.jsx rename removed — replaced the .ssr.jsx rename recommendation with a warning not to rename. Auto-bundling relies on Dir.glob("*.server.*") in packs_generator.rb; renaming would silently drop files from server bundle detection. Guidance now says to add 'use client' instead.

Completeness fixes (2):
2. Missing React 18/19 hooks — added useTransition, useDeferredValue, useId, useOptimistic, useFormStatus to the client API audit list
3. Grep checklist expanded — added useNavigate, useLocation, useParams, useTransition, useDeferredValue to the audit grep command

CI snippet fixes (2):
4. RENDERER_PASSWORD scope — restructured YAML to show the env var at job level (not step level) so Rails test steps can read it
5. curl --max-time 2 — added per-request timeout to readiness probe to prevent 30s hangs per iteration

Documentation caveat (1):
6. MessageChannel polyfill semantics — added note that the BannerPlugin polyfill delivers messages synchronously; recommends additionalContext with native MessageChannel if recursive scheduling issues occur

Comment thread docs/pro/react-server-components/upgrading-existing-pro-app.md Outdated
Comment thread docs/oss/migrating/rsc-troubleshooting.md
Comment thread docs/oss/building-features/node-renderer/basics.md
Comment thread docs/oss/migrating/rsc-troubleshooting.md
@claude

claude Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review: docs/RSC integration pitfalls

This is a high-quality, battle-tested set of documentation additions. The three-bundle architecture reference table is particularly valuable — the server bundle / RSC bundle confusion is one of the hardest pitfalls to debug, and having a single-page diff laid out in a table will save a lot of time. The .server.jsx naming collision section is an excellent catch that protects users from a very non-obvious failure mode.

Four specific issues flagged via inline comments:

  1. useFormStatus import source (upgrading-existing-pro-app.md line 41) — it's from react-dom, not react, and grouping it under "React hooks" will cause users to write the wrong import.

  2. MessageChannel polyfill scheduler semantics (rsc-troubleshooting.md line 920) — the synchronous polyfill is presented as primary with the correct async approach as a fallback. React's scheduler depends on macrotask delivery; synchronous delivery is a pragmatic workaround that works today but has broader risk than just stack overflows. Recommend leading with additionalContext + native MessageChannel.

  3. CI readiness timeout (basics.md line 168) — 30 seconds can be tight on cold CI runners with large bundles. Suggest bumping to 60 iterations since the loop breaks early on success anyway.

  4. resolve.fallback: false semantics (rsc-troubleshooting.md line 876) — description says it "omits the module at build time" but webpack actually emits an empty stub and a build warning. Fine in practice for this use case, but a one-line clarification would help users who see the warning in their build output.

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

Copy link
Copy Markdown

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: 08bd4814d2

ℹ️ 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/building-features/node-renderer/basics.md Outdated
Comment thread docs/oss/building-features/node-renderer/basics.md Outdated
…on order

- Split useFormStatus into separate "React DOM hooks" bullet with correct
  import path (react-dom, not react) to prevent wrong imports
- Lead with additionalContext + native MessageChannel as recommended
  approach; demote BannerPlugin synchronous polyfill to fallback option

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@justin808

Copy link
Copy Markdown
Member Author

Review feedback addressed in 25c3781

Third round — 4 of 6 threads resolved. Changes in a single commit:

Fixes (2):

  1. useFormStatus import source — split into separate "React DOM hooks" bullet with correct react-dom import path to prevent users writing import { useFormStatus } from 'react'
  2. MessageChannel recommendation orderadditionalContext + native MessageChannel is now the primary recommendation; BannerPlugin synchronous polyfill demoted to fallback for when renderer config is not accessible

Declined with rationale (2):
3. CI timeout 30→60 — keeping at 30 iterations; with --max-time 2 the worst case is ~60s wall time, and 60 iterations would mean a 2-minute wait on genuine failures
4. resolve.fallback description — keeping current wording; already corrected in the previous round, and the key point (no require() emitted) is accurate

Remaining (2 unresolved, need decision):
5. h2c-aware curl — codex bot notes the renderer uses cleartext HTTP/2 by default (worker.ts:217), so plain curl may fail. Verified in source code. Options: curl --http2-prior-knowledge or TCP probe
6. RENDERER_BUNDLE_PATH semantics — codex bot notes this env var maps to serverBundleCachePath (deprecated cache dir), not webpack output. Verified in configBuilder.ts:189. May need to use RENDERER_SERVER_BUNDLE_CACHE_PATH or remove it

```yaml
# .github/workflows/test.yml (GitHub Actions example)
jobs:
test:

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 YAML snippet is missing the required runs-on: key for the job. GitHub Actions will reject this workflow without it, making this example non-functional if copy-pasted directly.

Suggested change
test:
test:
runs-on: ubuntu-latest
env:

(Users may need to substitute their actual runner label, but the key itself is required.)


```js
// In serverWebpackConfig.js -- tells webpack to provide empty modules
resolve: {

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 inline code comment contradicts the explanatory paragraph below it. resolve.fallback: false does not tell webpack to provide empty modules — it tells webpack to omit the module entirely (no shim is generated, and any direct require('path') that can't be tree-shaken away becomes a build warning/error). An empty module shim would be resolve.fallback: { path: {} } or a stub file.

The paragraph at line 876 correctly says "no fallback shim is bundled", so the comment and the explanation are contradicting each other.

Suggested change
resolve: {
// In serverWebpackConfig.js -- tells webpack to omit these modules (no require() call emitted)

**Root cause:** `react-dom/server.browser.js` (used for SSR streaming) instantiates `MessageChannel` at **module load time** for React's internal scheduler. The VM sandbox does not provide `MessageChannel` as a global, and `supportModules` does not include it.

**Fix:** Use webpack's `BannerPlugin` to inject a minimal `MessageChannel` polyfill at the top of the server bundle. The polyfill only needs to support `port2.postMessage` triggering `port1.onmessage`, which is all React's scheduler requires:

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 section structure is confusing: the Fix: label leads users into the BannerPlugin (synchronous polyfill) approach, and the Recommended approach: using additionalContext only appears 35 lines later after the full code example. Most users will implement the first **Fix:** they see and never read to the recommended option.

Suggest flipping the order:

  1. Lead with additionalContext + native MessageChannel as the primary fix
  2. Follow with the BannerPlugin as the fallback for environments where renderer config can't be changed

This matches the intent of the > When to use the BannerPlugin polyfill: callout at the bottom, which already correctly frames BannerPlugin as the exception rather than the rule.

- **Router client APIs**: `useNavigate`, `useLocation`, `useParams`
- **SSR entry-point files** using `StaticRouter`: these are SSR wrappers, not RSC server components — see the `.server.jsx` naming collision below
- **Event handlers**: `onClick`, `onChange`, `onSubmit`, etc.
- **Browser APIs**: `window`, `document`, `localStorage`, `fetch` in effects

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.

fetch is not a browser-only API — it has been a Node.js global since v18.0.0 (built-in, unflagged since Node 21). It works in Server Components and RSC bundles. Listing it under "Browser APIs" is misleading and may cause developers to add unnecessary 'use client' directives to components that call fetch directly in server context (which is a common and encouraged RSC pattern).

The "in effects" qualifier partially saves this, but useEffect is already listed separately and would catch that pattern. I'd suggest dropping fetch from this list, or scoping it more precisely to fetch called inside useEffect (i.e., the client effect pattern), not fetch in general.


Before proceeding to Step 1:

- [ ] Search your component source files for `useState`, `useEffect`, `useContext`, `useSelector`, `useDispatch`, `useTransition`, `useDeferredValue`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`

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 grep checklist is missing several hooks that appear in the "What to look for" list just above it. Users following only the checklist will miss:

  • useRef, useReducer, useCallback, useMemo (common hooks)
  • useId, useOptimistic (React 18/19)
  • useFormStatus (react-dom)
  • ReactOnRails.authenticityToken

Suggest expanding the search pattern:

Suggested change
- [ ] Search your component source files for `useState`, `useEffect`, `useContext`, `useSelector`, `useDispatch`, `useTransition`, `useDeferredValue`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`
- [ ] Search your component source files for `useState`, `useEffect`, `useContext`, `useRef`, `useReducer`, `useCallback`, `useMemo`, `useTransition`, `useDeferredValue`, `useId`, `useOptimistic`, `useFormStatus`, `useSelector`, `useDispatch`, `useNavigate`, `useLocation`, `useParams`, `ReactOnRails.getStore`, `ReactOnRails.authenticityToken`

@claude

claude Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review: docs: RSC integration pitfalls from tutorial app

Overall this is high-quality documentation that fills real gaps — the three-bundle architecture table, the .server.jsx naming collision, and the Rails.env.local? CI gotcha are all valuable additions that will save developers significant debugging time.

Issues found

Blocking / correctness:

  1. CI YAML missing runs-on: (basics.md) — the GitHub Actions job snippet omits the required runs-on: key, making it invalid YAML that will fail immediately if copy-pasted. Inline comment with a suggestion posted.

  2. Incorrect inline code comment (rsc-troubleshooting.md line 866) — the comment says "tells webpack to provide empty modules" but resolve.fallback: false omits the module entirely (no shim). This directly contradicts the correct explanation in the paragraph below it. Inline comment with a fix suggestion posted.

  3. fetch incorrectly listed as a browser-only API (upgrading-existing-pro-app.md) — fetch is a global in Node.js ≥ 18 and is available in Server Components. Listing it under "Browser APIs" will cause developers to add unnecessary 'use client' to components that call fetch in server context — the opposite of RSC best practice. Inline comment posted.

Non-blocking / improvements:

  1. MessageChannel section: recommended approach buried after the "Fix" (rsc-troubleshooting.md) — the section leads with **Fix:** Use BannerPlugin... but the **Recommended approach:** (additionalContext) appears 35 lines later. Users implementing the first fix they see will end up with the synchronous polyfill, which the docs themselves warn may cause subtle bugs. The recommended additionalContext approach should be presented first. Inline comment posted.

  2. Audit grep checklist is a subset of "What to look for" (upgrading-existing-pro-app.md) — the checklist at the bottom omits useRef, useReducer, useCallback, useMemo, useId, useOptimistic, useFormStatus, and ReactOnRails.authenticityToken, all of which appear in the bullet list just above. A developer following only the checklist step would miss these. Inline comment with an expanded grep pattern posted.

What looks good

  • The VM sandbox vs full Node.js distinction is clearly explained and cross-referenced consistently across all four files
  • The .server.jsx naming collision and the guidance to add 'use client' rather than rename (to preserve Dir.glob("*.server.*") detection) is precise and technically accurate — confirmed against packs_generator.rb:520
  • The BannerPlugin polyfill implementation is correct: the arrow function captures this from the constructor, so this.port1 resolves to the right instance
  • The three-bundle reference table in rendering-flow.md is a genuinely useful addition; the column-per-bundle layout makes the runtime constraints scannable
  • The Rails.env.local? guidance with a Rails version caveat for < 7.1 is exactly the right level of detail

- Use curl --http2-prior-knowledge for readiness probe since the renderer
  uses cleartext HTTP/2 (h2c) and rejects HTTP/1.1 requests
- Remove incorrect RENDERER_BUNDLE_PATH env var (deprecated alias for
  serverBundleCachePath cache dir, not webpack output path)
- Replace with guidance to use rake pre_stage_bundle_for_node_renderer
  to symlink webpack output into the renderer cache before starting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@justin808

Copy link
Copy Markdown
Member Author

Review feedback addressed in bf26cb1

Fourth round — all 6 threads now resolved.

Fixes (2):

  1. h2c readiness probe — verified in worker.ts:217-221 that the renderer uses cleartext HTTP/2 by default. Readiness probe now uses curl --http2-prior-knowledge
  2. RENDERER_BUNDLE_PATH removed — verified in configBuilder.ts:189 that this is a deprecated alias for serverBundleCachePath (cache dir), not webpack output. Removed the env var from CI snippet; replaced with guidance to use rake react_on_rails_pro:pre_stage_bundle_for_node_renderer (symlinks webpack output into renderer cache)

Follow-up issue filed:

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

Copy link
Copy Markdown

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

ℹ️ 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".

- Generated using the RSC Webpack Loader which transforms client components into references
- Used specifically for generating RSC payloads
- Configured with `react-server` condition to enable RSC-specific code paths that tell the runtime that this bundle is used for RSC payload generation.
- **Runtime: Full Node.js** -- Node builtins (`path`, `fs`, `stream`) and `require()` work normally

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Describe RSC bundle as VM-sandboxed runtime

This line says the RSC bundle runs in full Node.js with normal require(), but the renderer executes both server and RSC bundles inside VM contexts: Rails sends both bundle hashes as dependencyBundleTimestamps (react_on_rails_pro/lib/react_on_rails_pro/utils.rb:168-177), handleRenderRequest builds VMs for all bundle paths (packages/react-on-rails-pro-node-renderer/src/worker/handleRenderRequest.ts:218-271), and execution happens via vm.createContext/vm.runInContext (packages/react-on-rails-pro-node-renderer/src/worker/vm.ts:240,148). This guidance can cause users to configure the RSC bundle as if Node builtins and require() are always available, leading to runtime failures unless they explicitly inject the needed globals/modules.

Useful? React with 👍 / 👎.


```js
// In serverWebpackConfig.js -- tells webpack to provide empty modules
resolve: {

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 inline comment "tells webpack to provide empty modules" contradicts the false values below. In webpack 5, resolve.fallback: { path: false } means no fallback is provided — not that an empty module is injected. If code directly imports path, webpack will throw a "Module not found" build error. The correct phrasing is something like "tells webpack not to polyfill these Node builtins":

Suggested change
resolve: {
// In serverWebpackConfig.js -- tells webpack not to polyfill these Node builtins

The subsequent prose explanation on line 876 ("omit the module at build time") has the same nuance issue — it's technically "no polyfill is provided" rather than "the module is omitted." The important and correct point is that no require() call is emitted in the output bundle, which should be kept.

This injects the polyfill as raw JavaScript at the top of the bundle output, ensuring `MessageChannel` is defined before any module code executes.

**Recommended approach:** Use `additionalContext` in the renderer config to inject Node.js' native `MessageChannel` into the VM sandbox. This provides correct async scheduling (macrotask delivery), which React's scheduler depends on. The `BannerPlugin` polyfill above delivers messages synchronously — this works for current SSR streaming scenarios but may cause subtle rendering bugs if React yields mid-render and re-enters the scheduler.

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 recommended approach (additionalContext) is buried after the BannerPlugin walkthrough, which means many readers will stop reading after the fix and use the synchronous polyfill without seeing the warning. Consider inverting the order — lead with additionalContext as the preferred path, then describe BannerPlugin as the escape hatch for when renderer config is unavailable. The current structure nudges users toward the approach that can cause "subtle rendering bugs."

Also worth calling out explicitly: the synchronous postMessage means React's scheduler fires microtask-style (in the same call stack) instead of via a macrotask. This can mask real scheduling issues and cause stack overflows on deeply recursive RSC trees — not just a theoretical concern.

steps:
- name: Start Node Renderer
run: |
node client/node-renderer.js &

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.

If node-renderer.js fails immediately (missing file, bad config, syntax error), the background process exits but the shell continues, and the readiness loop burns all 30 seconds before failing. Consider adding a brief initial wait and an explicit exit-status check:

Suggested change
node client/node-renderer.js &
node client/node-renderer.js &
RENDERER_PID=$!
sleep 1
# Bail early if the process already crashed
if ! kill -0 "$RENDERER_PID" 2>/dev/null; then
echo "Node Renderer process exited immediately — check logs above" >&2
exit 1
fi

This surfaces startup crashes in ~1 second instead of 30.


- **React hooks** (`import { ... } from 'react'`): `useState`, `useEffect`, `useContext`, `useRef`, `useReducer`, `useCallback`, `useMemo`, `useTransition`, `useDeferredValue`, `useId`, `useOptimistic`
- **React DOM hooks** (`import { ... } from 'react-dom'`): `useFormStatus`
- **React on Rails client APIs**: `ReactOnRails.getStore()`, `ReactOnRails.authenticityToken()`

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.

In React 19, useFormState was renamed useActionState and moved from react-dom to react. useFormStatus stays in react-dom. Worth mentioning both since codebases targeting React 18 may use useFormState and the rename is a common migration trip-wire:

Suggested change
- **React on Rails client APIs**: `ReactOnRails.getStore()`, `ReactOnRails.authenticityToken()`
- **React DOM hooks** (`import { ... } from 'react-dom'`): `useFormStatus`
- **React 19 form hooks** (`import { ... } from 'react'`): `useActionState` (was `useFormState` from `react-dom` in React 18)

@claude

claude Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review: docs: RSC integration pitfalls from tutorial app

Good set of real-world pitfalls — the bundle architecture reference table and the .server.jsx naming collision section are especially useful. A few things worth addressing:

Technical accuracy

resolve.fallback: false description (inline comment on rsc-troubleshooting.md:866)
The code comment reads "tells webpack to provide empty modules" — this is the opposite of what false means. In webpack 5, resolve.fallback: { path: false } means no polyfill is provided; if path is directly imported webpack throws a build error rather than injecting an empty module. The key accurate claim — that no require() call is emitted in the output — is correct and should be preserved, just the surrounding description needs tightening.

MessageChannel polyfill ordering (inline comment on rsc-troubleshooting.md:919)
The BannerPlugin approach is presented first as "The Fix" and additionalContext is listed as the "Recommended approach" afterward. Most readers will stop after the first working fix and never see the recommendation. Consider flipping the order so readers land on the additionalContext path first, with BannerPlugin as the escape hatch for build-only environments.

useActionState missing from the hook audit list (inline comment on upgrading-existing-pro-app.md:43)
React 19 renamed useFormStateuseActionState and moved it from react-dom to react. Apps migrating from React 18 may still use useFormState; both names should appear in the audit checklist.

Resilience

CI script: no fast-fail on immediate renderer crash (inline comment on basics.md:166)
If node client/node-renderer.js exits immediately (missing file, bad config, etc.), the loop polls for 30 seconds before failing. Capturing the PID and doing a kill -0 check after a 1-second initial wait would surface startup crashes in ~1 second.

Minor nits (no inline comment needed)

  • fetch is listed under "Browser APIs" — it's been available natively in Node 18+, so calling it browser-only may confuse readers. Replacing it with something like "browser fetch in side-effects (not SSR-safe)" or just removing it would be cleaner.
  • The audit checklist in upgrading-existing-pro-app.md doesn't mention useRef or useCallback, both of which are listed in the bullet above it. Not critical, but consistency would help.

@justin808 justin808 merged commit b76a52c into main Apr 13, 2026
24 checks passed
@justin808 justin808 deleted the jg/3076-rsc-pitfalls-docs branch April 13, 2026 00:04
justin808 added a commit that referenced this pull request Apr 18, 2026
…ages

* origin/main:
  Fix initial page startup race for late-loading client bundles (#3151)
  chore: apply prettier formatting to tracked docs files (#3153)
  docs: comprehensive RSC API documentation and registration consolidation (#3140)
  Split rspec-package-tests into parallel generator/unit shards (#3134)
  fix: add concurrency groups to long-running CI workflows (#3133)
  refactor: add RenderRequest, JsCodeBuilder, and RenderingStrategy abstractions (#3094)
  fix: address deferred review items from PR #2849 (#3093)
  Add complimentary OSS license policy for React on Rails Pro (#3123)
  fix: centralize CI docs-only detection and add CLI flag validation (#3091)
  refactor: replace stub-throw + Object.assign with capability-based composition (#3096)
  Enhance address-review with parallel fixes, self-review, and Greptile verification (#3121)
  fix: Doctor no longer fails custom projects for missing bin/dev (#3117)
  fix: cap webpack <5.106.0 to prevent ExecJS SSR breakage (#3095)
  Add Rspack + RSC compatibility tests and documentation (#1828) (#3120)
  Add error scenarios hub and test pages (#2497)
  docs: document polyfill requirements for web-targeted server bundles (#3092)
  docs: RSC integration pitfalls from tutorial app (#3087)
  docs: fix render function/helper API documentation (#3088)
  Doctor: accept TS/TSX server bundle suffixes (#3111)
  feat: add CI guard requiring sidebar updates when adding docs (#3089)
justin808 added a commit that referenced this pull request Apr 18, 2026
Applies the documentation review comments surfaced against PR #3087:

- Add missing `runs-on: ubuntu-latest` to the CI workflow example in
  node-renderer/basics.md so the snippet is copy-paste valid.
- Correct the `resolve.fallback: false` inline comment in
  rsc-troubleshooting.md to match the surrounding explanation
  ("omit the module" rather than "provide empty modules").
- Expand the upgrading-existing-pro-app audit checklist to include the
  React, React DOM, router, and ReactOnRails hook names that were
  listed in "What to look for" but missing from the checklist.
- Reorder the MessageChannel troubleshooting section to lead with the
  recommended `additionalContext` fix and demote BannerPlugin to a
  fallback, so users encounter the preferred option first.
- Clarify `fetch` under "Browser APIs": it is a Node.js global since v18
  and works in Server Components; only flag it when called inside a
  `useEffect` (already covered by the hooks list).

Fixes #3155

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
justin808 added a commit that referenced this pull request Apr 18, 2026
Applies the documentation review comments surfaced against PR #3087:

- Add missing `runs-on: ubuntu-latest` to the CI workflow example in
  node-renderer/basics.md so the snippet is copy-paste valid.
- Correct the `resolve.fallback: false` inline comment in
  rsc-troubleshooting.md to match the surrounding explanation
  ("omit the module" rather than "provide empty modules").
- Expand the upgrading-existing-pro-app audit checklist to include the
  React, React DOM, router, and ReactOnRails hook names that were
  listed in "What to look for" but missing from the checklist.
- Reorder the MessageChannel troubleshooting section to lead with the
  recommended `additionalContext` fix and demote BannerPlugin to a
  fallback, so users encounter the preferred option first.
- Clarify `fetch` under "Browser APIs": it is a Node.js global since v18
  and works in Server Components; only flag it when called inside a
  `useEffect` (already covered by the hooks list).

Fixes #3155

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
justin808 added a commit that referenced this pull request Apr 18, 2026
## Summary

Applies the five documentation review comments from PR #3087 that were
triaged to issue #3155:

- `docs/oss/building-features/node-renderer/basics.md` — Add missing
`runs-on: ubuntu-latest` to the GitHub Actions workflow example so the
snippet is copy-paste valid.
- `docs/oss/migrating/rsc-troubleshooting.md` — Correct the
`resolve.fallback: false` inline comment to say "omit these modules (no
require() call emitted)", matching the paragraph below it (no
empty-module shim is generated).
- `docs/pro/react-server-components/upgrading-existing-pro-app.md` —
Expand the audit checklist to include the React hooks (`useRef`,
`useReducer`, `useCallback`, `useMemo`, `useId`, `useOptimistic`), React
DOM hooks (`useFormStatus`), and `ReactOnRails.authenticityToken` that
were listed under "What to look for" but missing from the checklist.
- `docs/oss/migrating/rsc-troubleshooting.md` — Reorder the
MessageChannel Not Defined section to lead with the recommended
`additionalContext` fix (injecting Node's native `MessageChannel` from
`node:worker_threads`) and demote BannerPlugin to a labeled fallback, so
readers encounter the preferred approach first.
- `docs/pro/react-server-components/upgrading-existing-pro-app.md` —
Clarify `fetch` under "Browser APIs": it's a Node.js global since v18
and works in Server Components. The list now only flags `fetch` calls
inside `useEffect`, which are already captured by the hooks list above.

Fixes #3155

## Test plan

- [x] Prettier check (`npx prettier --check`) passes on all three
modified docs
- [x] Lefthook hooks (trailing-newlines, markdown-links, prettier)
passed on commit
- [x] No code changes — documentation only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation-only updates that adjust examples and recommended fixes;
no runtime behavior changes, so risk is low aside from potential reader
confusion if guidance is misapplied.
> 
> **Overview**
> Updates RSC/Node Renderer docs to make setup and troubleshooting
guidance more accurate and copy/paste-ready.
> 
> The CI workflow snippet now includes `runs-on: ubuntu-latest`, the
webpack `resolve.fallback: false` explanation is clarified, and the
`MessageChannel is not defined` section is reordered to recommend
injecting Node’s native `MessageChannel` via `additionalContext` (with
`BannerPlugin` polyfill as an explicit fallback). The Pro RSC upgrade
guide expands the client-API audit checklist to cover additional
hooks/APIs and clarifies that `fetch` is usable in Server Components
(flag it only when used in `useEffect`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6ba6295. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Specified explicit runner environment for Node Renderer test workflow
* Updated MessageChannel troubleshooting to recommend injecting Node’s
MessageChannel at the renderer level, with the webpack polyfill noted as
a fallback
* Clarified that fetch is usable in Server Components and expanded the
audit checklist to include additional React hooks and related APIs
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

Docs: RSC integration pitfalls discovered in tutorial app (VM sandbox, 'use client' classification, CI setup)

1 participant