Skip to content

Commit 5c63fee

Browse files
authored
SSR API Updates (#9058)
* chore: refactor useRenderDataRouter -> DataRouterProvider * Update types and exports * Remove foundMissingHydrationData check * Use default as location.key during SSR * Fix typo in docs * Flatten routes param for createStaticHandler * add unstable_ prefix for createStaticHandler * Bump bundle threshold * Expose statusCode and headers from query() * Automatic hydration via DataStaticRouter * Expose actionHeaders on static context * Automatically add routeIds inside DataStaticRouter * Built-in boundary tracking for static routers * Add getStaticContextFromError utility * Add unstable_ prex to static handler/router * Bump bundle * Remove <Routes routes> prop in favor of context * add unit tests for automatic hydration * update comments
1 parent 92aa5bb commit 5c63fee

File tree

25 files changed

+1216
-562
lines changed

25 files changed

+1216
-562
lines changed

.changeset/ninety-spoons-suffer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ feat: Add `createStaticRouter` for `@remix-run/router` SSR usage
1515

1616
```jsx
1717
// Create a static handler
18-
let { dataRoutes, query } = createStaticHandler({ routes });
18+
let { dataRoutes, query } = unstable_createStaticHandler(routes);
1919

2020
// Perform a full-document query for the incoming Fetch Request. This will
2121
// execute the appropriate action/loaders and return either the state or a
@@ -46,7 +46,7 @@ let hydrationData = {
4646

4747
```jsx
4848
// Create a static route handler
49-
let { queryRoute } = createStaticHandler({ routes });
49+
let { queryRoute } = unstable_createStaticHandler(routes);
5050

5151
// Perform a single-route query for the incoming Fetch Request. This will
5252
// execute the appropriate singular action/loader and return either the raw

docs/hooks/use-route-loader-data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: useRouteLoaderData
33
new: true
44
---
55

6-
# `useRouterLoaderData`
6+
# `useRouteLoaderData`
77

88
This hook makes the data at any currently rendered route available anywhere in the tree. This is useful for components deep in the tree needing data from routes much farther up, as well as parent routes needing the data of child routes deeper in the tree.
99

docs/routers/data-static-router.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: DataStaticRouter
2+
title: unstable_DataStaticRouter
33
new: true
44
---
55

6-
# `DataStaticRouter`
6+
# `unstable_DataStaticRouter`
77

88
<docs-info>TODO: This doc is a stub</docs-info>
99

examples/scroll-restoration/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ function Layout() {
112112
</div>
113113
</div>
114114
{/*
115-
Including this component inside a DataRouter component tree is what
115+
Including this component inside a data router component tree is what
116116
enables restoration
117117
*/}
118118
<ScrollRestoration getKey={getKey} />

examples/ssr-data-router/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This example contains a server (see [server.js](server.js)) that can run in both
1313

1414
In the browser entry point (see [src/entry.client.tsx](src/entry.client.tsx)), we use React Router like we would traditionally do in a purely client-side app and render a `<DataBrowserRouter>` to provide routing context to the rest of the app. The main difference is that instead of using `ReactDOM.render()` to render the app, since the HTML was already sent by the server, all we need is `ReactDOM.hydrate()`.
1515

16-
On the server (see [src/entry.server.tsx](src/entry.server.tsx)), we create a static request handler using `createStaticHandler` and query for the incoming `Request` we get from Express (note that we convert the Express request to a Web Fetch Request). Once the router is finished with data loading, we use React Router's `<DataStaticRouter>` to render the app in the correct state.
16+
On the server (see [src/entry.server.tsx](src/entry.server.tsx)), we create a static request handler using `createStaticHandler` and query for the incoming `Request` we get from Express (note that we convert the Express request to a Web Fetch Request). Once the router is finished with data loading, we use React Router's `<unstable_DataStaticRouter>` to render the app in the correct state.
1717

1818
## Preview
1919

examples/ssr-data-router/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
</head>
99
<body>
1010
<div id="app"><!--app-html--></div>
11-
<!--app-scripts-->
1211
<script type="module" src="/src/entry.client.tsx"></script>
1312
</body>
1413
</html>

examples/ssr-data-router/server.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,8 @@ async function createServer() {
5454
}
5555

5656
try {
57-
let { hydrationData, html: appHtml } = await render(req);
58-
let scriptHtml = `
59-
<script>
60-
window.__hydrationData = JSON.parse(${JSON.stringify(
61-
JSON.stringify(hydrationData)
62-
)});
63-
</script>
64-
`;
65-
66-
let html = template
67-
.replace("<!--app-html-->", appHtml)
68-
.replace("<!--app-scripts-->", scriptHtml);
57+
let appHtml = await render(req);
58+
let html = template.replace("<!--app-html-->", appHtml);
6959
res.setHeader("Content-Type", "text/html");
7060
return res.status(200).end(html);
7161
} catch (e) {

examples/ssr-data-router/src/entry.client.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ import { routes } from "./App";
77
ReactDOM.hydrateRoot(
88
document.getElementById("app"),
99
<React.StrictMode>
10-
<DataBrowserRouter
11-
routes={routes}
12-
hydrationData={window.__hydrationData}
13-
fallbackElement={null}
14-
/>
10+
<DataBrowserRouter routes={routes} fallbackElement={null} />
1511
</React.StrictMode>
1612
);

examples/ssr-data-router/src/entry.server.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
11
import type * as express from "express";
2-
import { createStaticHandler } from "@remix-run/router";
2+
import { unstable_createStaticHandler } from "@remix-run/router";
33
import * as React from "react";
44
import ReactDOMServer from "react-dom/server";
5-
import { DataStaticRouter } from "react-router-dom/server";
5+
import { unstable_ as DataStaticRouter } from "react-router-dom/server";
66
import { routes } from "./App";
77

88
export async function render(request: express.Request) {
9-
let { dataRoutes, query } = createStaticHandler({ routes });
9+
let { query } = unstable_createStaticHandler(routes);
1010
let remixRequest = createFetchRequest(request);
1111
let context = await query(remixRequest);
1212

1313
if (context instanceof Response) {
1414
throw context;
1515
}
1616

17-
let html = ReactDOMServer.renderToString(
17+
return ReactDOMServer.renderToString(
1818
<React.StrictMode>
19-
<DataStaticRouter dataRoutes={dataRoutes} context={context} />
19+
<DataStaticRouter routes={routes} context={context} nonce="the-nonce" />
2020
</React.StrictMode>
2121
);
22-
23-
return {
24-
hydrationData: {
25-
loaderData: context.loaderData,
26-
actionData: context.loaderData,
27-
errors: context.errors,
28-
},
29-
html,
30-
};
3122
}
3223

3324
export function createFetchHeaders(

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
},
102102
"filesize": {
103103
"packages/router/dist/router.js": {
104-
"none": "96 kB"
104+
"none": "97 kB"
105105
},
106106
"packages/react-router/dist/react-router.production.min.js": {
107107
"none": "11 kB"
@@ -113,7 +113,7 @@
113113
"none": "10 kB"
114114
},
115115
"packages/react-router-dom/dist/umd/react-router-dom.production.min.js": {
116-
"none": "14.5 kB"
116+
"none": "15.5 kB"
117117
}
118118
}
119119
}

0 commit comments

Comments
 (0)