Skip to content

Latest commit

 

History

History
74 lines (53 loc) · 2.05 KB

ssr.md

File metadata and controls

74 lines (53 loc) · 2.05 KB
outline deep

Custom SSR

Use custom SSR to choose your own router, data loading, HTML shell, and hydration code. If you want Void to handle these for you, use Pages Routing.

Create the app

Start with a root component. This React example renders a page based on the request path:

// src/App.tsx
export default function App({ url }: { url: string }) {
  return url === '/about' ? <main>About</main> : <main>Home</main>;
}

Required entries

Create both entry files:

  • src/main.ssr.ts or src/main.ssr.tsx
  • src/main.client.ts or src/main.client.tsx

Use one server entry and one client entry. Both are required.

Render API

Wrap your server renderer with defineRender() and return an HTML response. Insert assetTags.css and assetTags.preloads in <head>, and assetTags.body before </body>:

// src/main.ssr.tsx
import { renderToString } from 'react-dom/server';
import { defineRender } from 'void';
import App from './App';

export default defineRender(async (c, assetTags) => {
  const url = new URL(c.req.raw.url);
  const html = renderToString(<App url={url.pathname} />);
  return new Response(
    `<!doctype html>
<html>
  <head>${assetTags.css}${assetTags.preloads}</head>
  <body>
    <div id="root">${html}</div>
    ${assetTags.body}
  </body>
</html>`,
    { headers: { 'content-type': 'text/html; charset=utf-8' } },
  );
});

You can also export a named render(c, assetTags) function with the same signature. See defineRender for the types.

Hydrate in the browser

In the client entry, hydrate the same component:

// src/main.client.tsx
import { hydrateRoot } from 'react-dom/client';
import App from './App';

hydrateRoot(document.getElementById('root')!, <App url={window.location.pathname} />);

Caching

See Revalidation for stale-while-revalidate caching of SSR pages.

API routes and static files are served before custom rendering. Unmatched non-API requests use render(c, assetTags).