Skip to content

Commit 94ade6c

Browse files
committed
Docs: explain RSC client references for compiled JS
1 parent 220b5f3 commit 94ade6c

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

docs/oss/core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,46 @@ The `.client.jsx` / `.server.jsx` suffixes that auto-bundling supports for split
631631

632632
3. **Use variants for the `wrapServerComponentRenderer` wrapper pattern.** When a client component contains `RSCRoute` and needs to be wrapped with `wrapServerComponentRenderer`, the wrappers are authored as `.client.tsx` and `.server.tsx` variants. See [Embedding Server Components in Client Components](../../pro/react-server-components/inside-client-components.md) for the full walkthrough.
633633

634+
#### Compiled-to-JS languages and RSC client references
635+
636+
For RSC builds, React on Rails only sees the JavaScript modules that webpack or rspack compile. If a component is authored in a language that emits JavaScript, such as ReScript, the RSC client-reference pipeline must discover the compiled JavaScript module that the RSC bundle will import, not the original source file.
637+
638+
Use one of these patterns:
639+
640+
1. **Prefer a thin JavaScript/TypeScript wrapper for each RSC boundary.** Put the wrapper in `components_subdirectory`, import the compiled output, and make the wrapper the module that server components import.
641+
642+
```text
643+
app/javascript/src/Comments/
644+
├── ReScriptLikeButton.bs.js
645+
└── ror_components/
646+
└── ReScriptLikeButton.jsx
647+
```
648+
649+
```jsx
650+
// app/javascript/src/Comments/ror_components/ReScriptLikeButton.jsx
651+
'use client';
652+
653+
import ReScriptLikeButton from '../ReScriptLikeButton.bs.js';
654+
655+
export default ReScriptLikeButton;
656+
```
657+
658+
Server components should import the wrapper path, not the compiled `.bs.js` file directly. That keeps the `'use client'` directive, auto-bundled pack, RSC client-reference manifest key, and runtime module resolution aligned on the same JavaScript module.
659+
660+
2. **If the compiled output is the boundary module, make the compiled JavaScript discoverable.** The generated RSC configs read client references from the file named by `RSC_MANIFEST_CLIENT_REFERENCES_JSON`, or from the default path `ssr-generated/rsc-client-references.json` when the env var is not set. That JSON must have this shape:
661+
662+
```json
663+
{
664+
"refs": ["client/app/src/Comments/ReScriptLikeButton.bs.js"]
665+
}
666+
```
667+
668+
The `refs` entries must match the compiled module paths that webpack/rspack resolve in the RSC build. Do not list the original `.res` source path unless that is the module actually imported by the RSC bundle through a loader.
669+
670+
3. **Keep the discovery manifest fresh.** `bin/shakapacker-precompile-hook` runs the RSC client-reference discovery build and writes the default manifest. A long-running webpack/rspack watch process reads that manifest at startup, so restart the watch after adding a new compiled-language client boundary.
671+
672+
For direct compiled-output integration, the loader or build step for that language must preserve or inject the client boundary (the `'use client'` directive) before the RSC loader/plugin scans it. If that is not practical, use the wrapper-file pattern above; it is explicit and keeps the React on Rails generated files on the supported path.
673+
634674
#### Related RSC documentation
635675

636676
- [Create a React Server Component](../../pro/react-server-components/create-without-ssr.md) — step-by-step tutorial for setting up RSC and authoring your first server component.

0 commit comments

Comments
 (0)