Skip to content

feat: RSC Router APIs #13700

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

Draft
wants to merge 144 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
911c068
initial playground
jacob-ebey Feb 19, 2025
01044bb
feat: add `matchServerRequest`, `ServerMatch`, `ServerPayload`, `Serv…
jacob-ebey Feb 19, 2025
7db2d81
feat: add `routeServerRequest` to abstract out the bundler / runtime …
jacob-ebey Feb 19, 2025
27438a5
move things to core
jacob-ebey Feb 19, 2025
aabc807
cleanup
jacob-ebey Feb 19, 2025
9b38f06
feat: add initial server "manifest" payload
jacob-ebey Feb 19, 2025
10d0ce4
fix production build
jacob-ebey Feb 19, 2025
57c33c9
flatten routes
jacob-ebey Feb 19, 2025
6fd4987
cleanup types
jacob-ebey Feb 19, 2025
aca8764
cleanup
jacob-ebey Feb 20, 2025
9c519c4
render layout
jacob-ebey Feb 20, 2025
6691850
initial patchRoutesOnNavigation and dataStrategy
jacob-ebey Feb 21, 2025
971e860
cleanup
jacob-ebey Feb 21, 2025
1a30607
initialize router
jacob-ebey Feb 21, 2025
1c1c169
pass around decode
jacob-ebey Feb 25, 2025
266d95a
allow rendering `<ScrollRestoration>` and `<Links>`
jacob-ebey Feb 26, 2025
e0e0db8
add vite rsc playground
jacob-ebey Feb 27, 2025
8f55758
enable server first route components
jacob-ebey Mar 7, 2025
a6297e7
feat: support patching routes from dataStrategy
jacob-ebey Mar 11, 2025
4d6452d
update home route to have dynamic data
jacob-ebey Mar 11, 2025
65136c1
cleanup
jacob-ebey Mar 12, 2025
0171386
mutate route tree
jacob-ebey Mar 14, 2025
bb5a3a5
update parcel and fix module resolution
jacob-ebey Mar 18, 2025
4d5aa15
update parcel, revert import re-write
jacob-ebey Mar 19, 2025
4849e20
update deps for tests to begin to be migrated to React 19.
jacob-ebey Mar 25, 2025
afa0cb0
Merge branch 'dev' into rsc
brophdawg11 Apr 9, 2025
48ac62f
Add future flag values
brophdawg11 Apr 9, 2025
93443b8
Merge branch 'rsc' of https://github.com/remix-run/react-router into rsc
jacob-ebey Apr 9, 2025
858e9d4
remove overrides
jacob-ebey Apr 9, 2025
6eab18d
fix error boundaries
jacob-ebey Apr 9, 2025
2914b1d
- fixup Layout
jacob-ebey Apr 10, 2025
3cee45f
make root a complete server route
jacob-ebey Apr 10, 2025
0ade1f4
remove log
jacob-ebey Apr 10, 2025
49d6214
make sure data() function works when thrown
jacob-ebey Apr 10, 2025
f0a243f
feat: initial server actions
jacob-ebey Apr 10, 2025
9921953
note on cancellation
jacob-ebey Apr 10, 2025
9d35dfb
Merge branch 'dev' into rsc
brophdawg11 Apr 10, 2025
254f97e
better action revalidation support
jacob-ebey Apr 10, 2025
38e0626
prep for async initialization
jacob-ebey Apr 10, 2025
9d30bb8
Merge branch 'rsc' of https://github.com/remix-run/react-router into rsc
jacob-ebey Apr 10, 2025
b019439
remove log
jacob-ebey Apr 10, 2025
ec5fa31
remove log
jacob-ebey Apr 11, 2025
7095511
First pass of wiring up shared dataStrategy
brophdawg11 Apr 11, 2025
b1f4d3b
support for shouldRevalidate
jacob-ebey Apr 12, 2025
8e3eac7
cleanup
jacob-ebey Apr 12, 2025
630603d
feat:! type: module
jacob-ebey Apr 12, 2025
99d4212
fix build
jacob-ebey Apr 12, 2025
213e4b1
revert module changes
jacob-ebey Apr 12, 2025
7f3242e
Minor playground updates
brophdawg11 Apr 14, 2025
d129b6d
Add unstable parameter for in-place element mutations
brophdawg11 Apr 14, 2025
eaf8dfd
cleanup
brophdawg11 Apr 14, 2025
20b7cfc
Switch to use context instead of a WeakMap for renderedRoutes
brophdawg11 Apr 14, 2025
427df65
Remove routesPatched logic with auto-update
brophdawg11 Apr 14, 2025
df27738
Merge branch 'dev' into rsc
brophdawg11 Apr 14, 2025
768bcad
Add support for actions
brophdawg11 Apr 14, 2025
e38f49c
fix: skip revalidation for actions
jacob-ebey Apr 14, 2025
0be1854
update lockfile
jacob-ebey Apr 14, 2025
6edd937
Decouple query flags from matches rendering
brophdawg11 Apr 15, 2025
319856e
oops
brophdawg11 Apr 15, 2025
55e1d7d
Wire up clientLoader.hydrate behavior
brophdawg11 Apr 15, 2025
e31bc7e
Fix some issues with serverLoader and error boundaries
brophdawg11 Apr 15, 2025
3ccddfa
fix: discover index routes in reverse
jacob-ebey Apr 16, 2025
996e5f2
don't render element when route has error
jacob-ebey Apr 16, 2025
fcc3ad4
add explicit export for react server
jacob-ebey Apr 16, 2025
e0e92e3
fixup exports
jacob-ebey Apr 16, 2025
36a5255
cleanup lazy function
jacob-ebey Apr 16, 2025
97b5888
Handle scenarios when no loader exists
brophdawg11 Apr 16, 2025
8e3c86b
Revert "fix: discover index routes in reverse"
brophdawg11 Apr 16, 2025
355d676
Handle eager pathless/index route patches
brophdawg11 Apr 16, 2025
84d2372
implement redirects
jacob-ebey Apr 16, 2025
25335bd
remove log
jacob-ebey Apr 16, 2025
0fd8a02
Add some timeouts and navigaiton state
brophdawg11 Apr 16, 2025
7f6ba43
always return a payload
jacob-ebey Apr 17, 2025
404ec19
Merge branch 'rsc' of https://github.com/remix-run/react-router into rsc
jacob-ebey Apr 17, 2025
f6c6dae
Merge branch 'dev' into rsc
brophdawg11 Apr 17, 2025
be5fb2c
fix stream issue
jacob-ebey Apr 17, 2025
a76d373
Merge branch 'rsc' of https://github.com/remix-run/react-router into rsc
jacob-ebey Apr 17, 2025
e6781cd
Merge branch 'dev' into rsc
brophdawg11 Apr 17, 2025
eda7a8c
fix
brophdawg11 Apr 17, 2025
4cf8007
feat: add support for progressive enhanced actions
jacob-ebey Apr 18, 2025
b9264dc
export type
jacob-ebey Apr 18, 2025
573acd4
update progressive actions
jacob-ebey Apr 18, 2025
f0cc45f
RSC renames
brophdawg11 Apr 17, 2025
a31699f
Code cleanups/diff reductions
brophdawg11 Apr 18, 2025
201a701
Don't include patches on SPA navigation render payloads
brophdawg11 Apr 18, 2025
21f6f89
Clean uip a few todos
brophdawg11 Apr 18, 2025
856ae8c
Wire up headers
brophdawg11 Apr 18, 2025
3b3f4b7
Add back module export conditions
brophdawg11 Apr 18, 2025
1a5899f
Loosen check on loaderData existence
brophdawg11 Apr 18, 2025
692ce42
Align component props
markdalgleish Apr 23, 2025
54021f5
Fix client component check, refactor
markdalgleish Apr 24, 2025
afafbf6
fix: better flush assets as they are discovered for a flatter network…
jacob-ebey May 6, 2025
a490e56
Fix singleFetchUrl parameter
brophdawg11 May 6, 2025
e988dc6
RSC middleware
brophdawg11 Apr 25, 2025
1fb0df7
RSC Server Code Cleanup (#13577)
brophdawg11 May 9, 2025
d1d9344
Fix Parcel RSC playground (#13587)
markdalgleish May 12, 2025
ba05c30
Remove parcel bug workaround
brophdawg11 May 12, 2025
744f3c7
Merge branch 'dev' into rsc
brophdawg11 May 12, 2025
3027cd4
Update rsc-parcel playground to use stable react 19
brophdawg11 May 12, 2025
8866dde
Properly handle errors thrown from loaders/actions/middleware
brophdawg11 May 12, 2025
28626d6
Remove dynamic `react-router` import from RSC code (#13597)
markdalgleish May 13, 2025
24f5d5b
Remove client component wrappers (#13599)
markdalgleish May 13, 2025
5c7b7f7
Use object for `routeRSCServerRequest` args (#13600)
markdalgleish May 13, 2025
1398c7a
Support middleware on RSC server actions
brophdawg11 May 13, 2025
19ee16c
Ensure stream is called on 404/405 errors
brophdawg11 May 13, 2025
3f68c7c
Handle middleware errors via stream
brophdawg11 May 13, 2025
6e7c213
Skip rendering server components that won't surface to the UI
brophdawg11 May 14, 2025
00bea5e
Minor cleanups to server.rsc (#13609)
brophdawg11 May 14, 2025
d1966d4
PAss context provider to server components as a prop
brophdawg11 May 14, 2025
e152ee5
Simplify RSC server element creation
brophdawg11 May 14, 2025
552e70c
Add hydrate option to routeRSCServerRequest
brophdawg11 May 14, 2025
d31afa4
Fix error when cloning RSC server response (#13610)
markdalgleish May 15, 2025
0ff7099
Log localhost URL when starting Parcel RSC playground
markdalgleish May 15, 2025
1dcf5c8
Fix RSC ErrorBoundary error prop (#13611)
markdalgleish May 15, 2025
f1dd850
Fix JS-disabled server action submission
brophdawg11 May 15, 2025
689fd7d
Initial RSC playwright tests
brophdawg11 May 15, 2025
d9933d7
Remove no-optimize flag
brophdawg11 May 15, 2025
54b6632
Revert "PAss context provider to server components as a prop"
brophdawg11 May 16, 2025
c373685
Remove unused imports
brophdawg11 May 19, 2025
ef24dfc
Merge branch 'dev' into rsc
brophdawg11 May 20, 2025
87677d2
Fix merge conflicts
brophdawg11 May 20, 2025
d9c565a
Revert "Remove hashes on built filenames (#13567)"
brophdawg11 May 20, 2025
e87ed2f
Merge branch 'dev' into rsc
markdalgleish May 22, 2025
d4ac45f
RSC E2E tests
brophdawg11 May 16, 2025
c79b983
Revert unintended param ordering change
brophdawg11 May 22, 2025
0964a54
Revert "Revert unintended param ordering change"
brophdawg11 May 25, 2025
2d501d8
Merge branch 'dev' into rsc
brophdawg11 May 25, 2025
37f4e32
test: fix RSC type errors (#13678)
markdalgleish May 26, 2025
b3da1e9
Merge branch 'dev' into rsc
markdalgleish May 26, 2025
8c95759
chore: mark new APIs as unstable (#13685)
jacob-ebey May 27, 2025
25aeaad
Skip RSC templates in Framework Mode tests (#13689)
markdalgleish May 27, 2025
a2d5768
Fix RSC client loader support (#13663)
markdalgleish May 28, 2025
a32bc0b
Add RSC eager route discovery (#13698)
markdalgleish May 28, 2025
e7eb25a
Enable rsc error test (#13696)
jacob-ebey May 28, 2025
8652a00
chore: add basic server function test that runs on both bundlers (#13…
jacob-ebey May 29, 2025
c1f0dae
expand action check (#13705)
jacob-ebey May 29, 2025
1fcc8eb
support thrown redirects from server actions (#13707)
jacob-ebey May 29, 2025
17b9b60
wire thrown redirects from actions into the transition lifecycle (#13…
jacob-ebey May 30, 2025
2352aaa
Fix RSC `fetcher.load` (#13709)
markdalgleish May 30, 2025
4b96510
Add pathless fog of war test to fetchers unit tests (#13727)
markdalgleish Jun 4, 2025
f2b4258
feat(react-router): rename RSC `default` route property to `Component…
markdalgleish Jun 5, 2025
a417996
fix: flushSync support (#13755)
jacob-ebey Jun 5, 2025
7db49e8
Support RSC lazy `default` export as `Component` fallback (#13763)
markdalgleish Jun 6, 2025
98367e4
fix: allow resource routes to be called as fetchers or as public API …
jacob-ebey Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ node_modules/

.wireit
.eslintcache
.parcel-cache
.tmp
tsup.config.bundled_*.mjs
build.utils.d.ts
Expand Down
1 change: 1 addition & 0 deletions integration/helpers/rsc-parcel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
47 changes: 47 additions & 0 deletions integration/helpers/rsc-parcel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@playground/rsc-parcel",
"private": true,
"source": "src/entry.ssr.tsx",
"server": "dist/server.js",
"targets": {
"server": {
"context": "react-server",
"includeNodeModules": {
"express": false
}
}
},
"scripts": {
"dev": "parcel --no-cache",
"build": "parcel build --no-cache",
"start": "node dist/server.js",
"typecheck": "tsc"
},
"devDependencies": {
"@parcel/packager-react-static": "2.15.0",
"@parcel/transformer-react-static": "2.15.0",
"@types/express": "^5.0.0",
"@types/node": "^22.13.1",
"@types/parcel-env": "0.0.8",
"@types/react-dom": "^19.0.3",
"@types/react": "^19.0.8",
"browserify-zlib": "^0.2.0",
"buffer": "^5.5.0||^6.0.0",
"events": "^3.1.0",
"parcel": "2.15.0",
"path-browserify": "^1.0.0",
"querystring-es3": "^0.2.1",
"stream-http": "^3.1.0",
"typescript": "^5.1.6",
"url": "^0.11.0"
},
"dependencies": {
"@mjackson/node-fetch-server": "0.6.1",
"@parcel/runtime-rsc": "2.15.0",
"express": "^4.21.2",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router": "workspace:*",
"react-server-dom-parcel": "^19.1.0"
}
}
Binary file added integration/helpers/rsc-parcel/public/favicon.ico
Binary file not shown.
40 changes: 40 additions & 0 deletions integration/helpers/rsc-parcel/src/entry.browser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use client-entry";

import * as React from "react";
import { hydrateRoot } from "react-dom/client";
import {
unstable_createCallServer as createCallServer,
unstable_getServerStream as getServerStream,
unstable_RSCHydratedRouter as RSCHydratedRouter,
} from "react-router";
import type { unstable_ServerPayload as ServerPayload } from "react-router/rsc";
import {
createFromReadableStream,
encodeReply,
setServerCallback,
// @ts-expect-error
} from "react-server-dom-parcel/client";

const callServer = createCallServer({
decode: (body) => createFromReadableStream(body, { callServer }),
encodeAction: (args) => encodeReply(args),
});

setServerCallback(callServer);

createFromReadableStream(getServerStream(), { assets: "manifest" }).then(
(payload: ServerPayload) => {
React.startTransition(() => {
hydrateRoot(
document,
<React.StrictMode>
<RSCHydratedRouter
decode={createFromReadableStream}
// @ts-expect-error
payload={payload}
/>
</React.StrictMode>
);
});
}
);
43 changes: 43 additions & 0 deletions integration/helpers/rsc-parcel/src/entry.rsc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use server-entry";

import {
decodeAction,
decodeReply,
loadServerAction,
renderToReadableStream,
// @ts-expect-error
} from "react-server-dom-parcel/server.edge";
import {
type unstable_DecodeCallServerFunction as DecodeCallServerFunction,
type unstable_DecodeFormActionFunction as DecodeFormActionFunction,
unstable_matchRSCServerRequest as matchRSCServerRequest,
} from "react-router/rsc";

import { routes } from "./routes";

import "./entry.browser.tsx";

const decodeCallServer: DecodeCallServerFunction = async (actionId, reply) => {
const args = await decodeReply(reply);
const action = await loadServerAction(actionId);
return action.bind(null, ...args);
};

const decodeFormAction: DecodeFormActionFunction = async (formData) => {
return await decodeAction(formData);
};

export function callServer(request: Request) {
return matchRSCServerRequest({
decodeCallServer,
decodeFormAction,
request,
routes,
generateResponse(match) {
return new Response(renderToReadableStream(match.payload), {
status: match.statusCode,
headers: match.headers,
});
},
});
}
57 changes: 57 additions & 0 deletions integration/helpers/rsc-parcel/src/entry.ssr.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { createRequestListener } from "@mjackson/node-fetch-server";
import express from "express";
// @ts-expect-error - no types
import { renderToReadableStream as renderHTMLToReadableStream } from "react-dom/server.edge" assert { env: "react-client" };
import {
unstable_routeRSCServerRequest as routeRSCServerRequest,
unstable_RSCStaticRouter as RSCStaticRouter,
} from "react-router" assert { env: "react-client" };
// @ts-expect-error
import { createFromReadableStream } from "react-server-dom-parcel/client.edge" assert { env: "react-client" };

import { callServer } from "./entry.rsc" assert { env: "react-server" };

const app = express();

app.use(express.static("public"));

app.use("/client", express.static("dist/client"));

app.get("/.well-known/appspecific/com.chrome.devtools.json", (req, res) => {
res.status(404);
res.end();
});

app.use(
createRequestListener(async (request) => {
return routeRSCServerRequest({
request,
callServer,
decode: createFromReadableStream,
async renderHTML(getPayload) {
return await renderHTMLToReadableStream(
<RSCStaticRouter getPayload={getPayload} />,
{
bootstrapScriptContent: (
callServer as unknown as { bootstrapScript: string }
).bootstrapScript,
}
);
},
});
})
);

const port = parseInt(process.env.RR_PORT || "3000", 10);
const server = app.listen(port, () => {
console.log(`Server started on http://localhost:${port}`);
});

// Restart the server when it changes.
if (module.hot) {
module.hot.dispose(() => {
server.close();
});

module.hot.accept();
}
16 changes: 16 additions & 0 deletions integration/helpers/rsc-parcel/src/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router/rsc";

export const routes = [
{
id: "root",
path: "",
lazy: () => import("./routes/root"),
children: [
{
id: "home",
index: true,
lazy: () => import("./routes/home"),
},
],
},
] satisfies ServerRouteObject[];
3 changes: 3 additions & 0 deletions integration/helpers/rsc-parcel/src/routes/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function HomeRoute() {
return <h2>Home</h2>;
}
22 changes: 22 additions & 0 deletions integration/helpers/rsc-parcel/src/routes/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Links, Outlet, ScrollRestoration } from "react-router";

export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Vite (RSC)</title>
<Links />
</head>
<body>
{children}
<ScrollRestoration />
</body>
</html>
);
}

export default function ServerComponent() {
return <Outlet />;
}
13 changes: 13 additions & 0 deletions integration/helpers/rsc-parcel/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"strict": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"moduleResolution": "bundler",
"module": "esnext",
"isolatedModules": true,
"esModuleInterop": true,
"target": "es2022",
"noEmit": true
}
}
1 change: 1 addition & 0 deletions integration/helpers/rsc-vite/.wrangler/deploy/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"configPath":"../../dist/ssr/wrangler.json","auxiliaryWorkers":[{"configPath":"../../dist/server/wrangler.json"}]}
16 changes: 16 additions & 0 deletions integration/helpers/rsc-vite/framework/references.browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {
createServerReference as createServerReferenceImp,
createFromReadableStream,
encodeReply,
// @ts-expect-error - no types yet
} from "@jacob-ebey/react-server-dom-vite/client";
import { unstable_createCallServer as createCallServer } from "react-router";

export const callServer = createCallServer({
decode: (body) => createFromReadableStream(body, { callServer }),
encodeAction: (args) => encodeReply(args),
});

export function createServerReference(imp: unknown, id: string, name: string) {
return createServerReferenceImp(`${id}#${name}`, callServer);
}
5 changes: 5 additions & 0 deletions integration/helpers/rsc-vite/framework/references.rsc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// @ts-expect-error - no types yet
import RSD from "@jacob-ebey/react-server-dom-vite/server";

export const registerServerReference = RSD.registerServerReference;
export const registerClientReference = RSD.registerClientReference;
4 changes: 4 additions & 0 deletions integration/helpers/rsc-vite/framework/references.ssr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @ts-expect-error - no types yet
import RSD from "@jacob-ebey/react-server-dom-vite/client";

export const createServerReference = RSD.createServerReference;
19 changes: 19 additions & 0 deletions integration/helpers/rsc-vite/framework/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as stream from "node:stream";
// @ts-expect-error - no types yet
import RSD from "@jacob-ebey/react-server-dom-vite/server";
// @ts-expect-error - no types yet
import { manifest } from "virtual:react-manifest";

export function renderToReadableStream(payload: any) {
const { pipe } = RSD.renderToPipeableStream(payload, manifest);
return stream.Readable.toWeb(
pipe(new stream.PassThrough())
) as ReadableStream<Uint8Array>;
}

export function decodeReply(
reply: FormData | string,
options?: any
): unknown[] {
return RSD.decodeReply(reply, manifest, options);
}
34 changes: 34 additions & 0 deletions integration/helpers/rsc-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@playground/rsc-vite",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"start": "node server.js",
"typecheck": "tsc"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@cloudflare/vite-plugin": "0.1.7",
"@cloudflare/workers-types": "^4.20250224.0",
"@jacob-ebey/vite-react-server-dom": "0.0.12",
"@types/express": "^5.0.0",
"@types/node": "^22.13.1",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"typescript": "^5.1.6",
"vite": "^6.2.0",
"vite-tsconfig-paths": "^5.1.4",
"wrangler": "^3.111.0"
},
"dependencies": {
"@jacob-ebey/react-server-dom-vite": "19.0.0-experimental.14",
"@mjackson/node-fetch-server": "0.6.1",
"compression": "^1.8.0",
"express": "^4.21.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router": "workspace:*"
}
}
Binary file added integration/helpers/rsc-vite/public/favicon.ico
Binary file not shown.
39 changes: 39 additions & 0 deletions integration/helpers/rsc-vite/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { parseArgs } from "node:util";
import { createRequestListener } from "@mjackson/node-fetch-server";
import compression from "compression";
import express from "express";

import ssr from "./dist/ssr/entry.ssr.js";
import server from "./dist/server/entry.rsc.js";

const app = express();

app.use(compression());
app.use(express.static("dist/client"));

app.get("/.well-known/appspecific/com.chrome.devtools.json", (req, res) => {
res.status(404);
res.end();
});

app.use(
createRequestListener((request) => {
return ssr.fetch(request, {
SERVER: {
fetch(request) {
return server.fetch(request);
},
},
});
})
);

const { values } = parseArgs({
options: { p: { type: "string", default: "3000" } },
allowPositionals: true,
});

const port = parseInt(values.p, 10);
app.listen(port, () => {
console.log(`Server started on http://localhost:${port}`);
});
Loading