|
| 1 | +--- |
| 2 | +"react-router": patch |
| 3 | +"react-router-dom": patch |
| 4 | +"@remix-run/router": patch |
| 5 | +--- |
| 6 | + |
| 7 | +feat: Add `createStaticRouter` for `@remix-run/router` SSR usage |
| 8 | + |
| 9 | +**Notable changes:** |
| 10 | + |
| 11 | +- `request` is now the driving force inside the router utils, so that we can better handle `Request` instances coming form the server (as opposed to `string` and `Path` instances coming from the client) |
| 12 | +- Removed the `signal` param from `loader` and `action` functions in favor of `request.signal` |
| 13 | + |
| 14 | +**Example usage (Document Requests):** |
| 15 | + |
| 16 | +```jsx |
| 17 | +// Create a static handler |
| 18 | +let { dataRoutes, query } = createStaticHandler({ routes }); |
| 19 | + |
| 20 | +// Perform a full-document query for the incoming Fetch Request. This will |
| 21 | +// execute the appropriate action/loaders and return either the state or a |
| 22 | +// Fetch Response in the case of redirects. |
| 23 | +let state = await query(fetchRequest); |
| 24 | + |
| 25 | +// If we received a Fetch Response back, let our server runtime handle directly |
| 26 | +if (state instanceof Response) { |
| 27 | + throw state; |
| 28 | +} |
| 29 | + |
| 30 | +// Otherwise, render our application providing the data routes and state |
| 31 | +let html = ReactDOMServer.renderToString( |
| 32 | + <React.StrictMode> |
| 33 | + <DataStaticRouter dataRoutes={dataRoutes} state={state} /> |
| 34 | + </React.StrictMode> |
| 35 | +); |
| 36 | + |
| 37 | +// Grab the hydrationData to send to the client for <DataBrowserRouter> |
| 38 | +let hydrationData = { |
| 39 | + loaderData: state.loaderData, |
| 40 | + actionData: state.actionData, |
| 41 | + errors: state.errors, |
| 42 | +}; |
| 43 | +``` |
| 44 | + |
| 45 | +**Example usage (Data Requests):** |
| 46 | + |
| 47 | +```jsx |
| 48 | +// Create a static route handler |
| 49 | +let { queryRoute } = createStaticHandler({ routes }); |
| 50 | + |
| 51 | +// Perform a single-route query for the incoming Fetch Request. This will |
| 52 | +// execute the appropriate singular action/loader and return either the raw |
| 53 | +// data or a Fetch Response |
| 54 | +let data = await queryRoute(fetchRequest); |
| 55 | + |
| 56 | +// If we received a Fetch Response back, return it directly |
| 57 | +if (data instanceof Response) { |
| 58 | + return data; |
| 59 | +} |
| 60 | + |
| 61 | +// Otherwise, construct a Response from the raw data (assuming json here) |
| 62 | +return new Response(JSON.stringify(data), { |
| 63 | + headers: { |
| 64 | + "Content-Type": "application/json; charset=utf-8", |
| 65 | + }, |
| 66 | +}); |
| 67 | +``` |
0 commit comments