-
Notifications
You must be signed in to change notification settings - Fork 373
Add React Server Components with React on Rails Pro #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
4d09e13
Add React Server Components with React on Rails Pro
justin808 4c0df6e
Fix ESLint violations in RSC components and updated files
justin808 2f3c42c
Fix remaining lint issues: eslint-disable placement and no-danger
justin808 ae420af
Fix eslint-disable syntax for file-level rules before 'use client'
justin808 05cb2bc
Add Node renderer and fix RSC page rendering
justin808 0d8d75a
Address PR review feedback: fix bugs, security, and config issues
justin808 aaeba86
Address PR review feedback: fix bugs, security, and config issues
justin808 92306ff
Fix CI: resolve RSC bundle and server bundle build errors
justin808 3f7e452
Use externals instead of fallbacks for Node builtins in server bundle
justin808 1022234
Fix SSR runtime failures: Node renderer, polyfills, and RSC classific…
justin808 bc41706
Address PR review fixes 1-12 and resolve review threads
justin808 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,6 +38,8 @@ def simple; end | |
|
|
||
| def rescript; end | ||
|
|
||
| def server_components; end | ||
|
|
||
| private | ||
|
|
||
| def set_comments | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| <%= append_javascript_pack_tag('rsc-client-components') %> | ||
| <%= react_component("ServerComponentsPage", | ||
| prerender: false, | ||
| auto_load_bundle: false, | ||
| trace: Rails.env.development?, | ||
| id: "ServerComponentsPage-react-component-0") %> |
2 changes: 2 additions & 0 deletions
2
client/app/bundles/comments/components/Footer/ror_components/Footer.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 4 additions & 2 deletions
6
...pp/bundles/comments/components/SimpleCommentScreen/ror_components/SimpleCommentScreen.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
client/app/bundles/comments/rescript/ReScriptShow/ror_components/RescriptShow.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletion
4
client/app/bundles/comments/startup/App/ror_components/App.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletion
4
client/app/bundles/comments/startup/NavigationBarApp/ror_components/NavigationBarApp.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletion
4
client/app/bundles/comments/startup/RouterApp/ror_components/RouterApp.client.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
client/app/bundles/server-components/ServerComponentsPage.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| // Server Component - this entire component runs on the server. | ||
| // It can use Node.js APIs and server-only dependencies directly. | ||
| // None of these imports are shipped to the client bundle. | ||
|
|
||
| import React, { Suspense } from 'react'; | ||
| import ServerInfo from './components/ServerInfo'; | ||
| import CommentsFeed from './components/CommentsFeed'; | ||
| import TogglePanel from './components/TogglePanel'; | ||
|
|
||
| const ServerComponentsPage = () => { | ||
| return ( | ||
| <div className="max-w-4xl mx-auto py-8 px-4"> | ||
| <header className="mb-10"> | ||
| <h1 className="text-3xl font-bold text-slate-800 mb-2"> | ||
| React Server Components Demo | ||
| </h1> | ||
| <p className="text-slate-600 text-lg"> | ||
| This page is rendered using <strong>React Server Components</strong> with React on Rails Pro. | ||
| Server components run on the server and stream their output to the client, keeping | ||
| heavy dependencies out of the browser bundle entirely. | ||
| </p> | ||
| </header> | ||
|
|
||
| <div className="space-y-8"> | ||
| {/* Server Info - uses Node.js os module (impossible on client) */} | ||
| <section> | ||
| <h2 className="text-xl font-semibold text-slate-700 mb-4 flex items-center gap-2"> | ||
| Server Environment | ||
| <span className="text-xs font-normal bg-emerald-100 text-emerald-700 px-2 py-0.5 rounded-full"> | ||
| Server Only | ||
| </span> | ||
| </h2> | ||
| <ServerInfo /> | ||
| </section> | ||
|
|
||
| {/* Interactive toggle - demonstrates mixing server + client components */} | ||
| <section> | ||
| <h2 className="text-xl font-semibold text-slate-700 mb-4 flex items-center gap-2"> | ||
| Interactive Client Component | ||
| <span className="text-xs font-normal bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full"> | ||
| Client Hydrated | ||
| </span> | ||
| </h2> | ||
| <TogglePanel title="How does this work?"> | ||
| <div className="prose prose-slate max-w-none text-sm"> | ||
| <p> | ||
| This toggle is a <code>'use client'</code> component, meaning it ships JavaScript | ||
| to the browser for interactivity. But the content inside is rendered on the server | ||
| and passed as children — a key RSC pattern called the <strong>donut pattern</strong>. | ||
| </p> | ||
| <ul> | ||
| <li>The <code>TogglePanel</code> wrapper runs on the client (handles click events)</li> | ||
| <li>The children content is rendered on the server (no JS cost)</li> | ||
| <li>Heavy libraries used by server components never reach the browser</li> | ||
| </ul> | ||
| </div> | ||
| </TogglePanel> | ||
| </section> | ||
|
|
||
| {/* Async data fetching with Suspense streaming */} | ||
| <section> | ||
| <h2 className="text-xl font-semibold text-slate-700 mb-4 flex items-center gap-2"> | ||
| Streamed Comments | ||
| <span className="text-xs font-normal bg-amber-100 text-amber-700 px-2 py-0.5 rounded-full"> | ||
| Async + Suspense | ||
| </span> | ||
| </h2> | ||
| <p className="text-slate-500 text-sm mb-4"> | ||
| Comments are fetched directly on the server using the Rails API. | ||
| The page shell renders immediately while this section streams in progressively. | ||
|
justin808 marked this conversation as resolved.
|
||
| </p> | ||
| <Suspense | ||
|
justin808 marked this conversation as resolved.
|
||
| fallback={ | ||
| <div className="animate-pulse space-y-3"> | ||
| {[1, 2, 3].map((i) => ( | ||
| <div key={i} className="bg-slate-100 rounded-lg p-4"> | ||
| <div className="h-4 bg-slate-200 rounded w-1/4 mb-2" /> | ||
| <div className="h-3 bg-slate-200 rounded w-3/4" /> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| } | ||
| > | ||
| <CommentsFeed /> | ||
| </Suspense> | ||
| </section> | ||
|
|
||
| {/* Architecture explanation */} | ||
| <section className="bg-slate-50 border border-slate-200 rounded-xl p-6"> | ||
| <h2 className="text-lg font-semibold text-slate-700 mb-3"> | ||
| What makes this different? | ||
| </h2> | ||
| <div className="grid md:grid-cols-2 gap-4 text-sm text-slate-600"> | ||
| <div> | ||
| <h3 className="font-medium text-slate-800 mb-1">Smaller Client Bundle</h3> | ||
| <p> | ||
| Libraries like <code>lodash</code>, <code>marked</code>, and Node.js <code>os</code> module | ||
| are used on this page but never downloaded by the browser. | ||
| </p> | ||
| </div> | ||
| <div> | ||
| <h3 className="font-medium text-slate-800 mb-1">Direct Data Access</h3> | ||
| <p> | ||
| Server components fetch data by calling your Rails API internally — no | ||
| client-side fetch waterfalls or loading spinners for initial data. | ||
| </p> | ||
| </div> | ||
| <div> | ||
| <h3 className="font-medium text-slate-800 mb-1">Progressive Streaming</h3> | ||
| <p> | ||
| The page shell renders instantly. Async components (like the comments feed) | ||
| stream in as their data resolves, with Suspense boundaries showing fallbacks. | ||
| </p> | ||
| </div> | ||
| <div> | ||
| <h3 className="font-medium text-slate-800 mb-1">Selective Hydration</h3> | ||
| <p> | ||
| Only client components (like the toggle above) receive JavaScript. | ||
| Everything else is pure HTML — zero hydration cost. | ||
| </p> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default ServerComponentsPage; | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.