Server Rendering
This guide covers the practical setup for basic SSR. If you’re new to SSR concepts, read Intro to SSR first.
Render Functions
Section titled “Render Functions”Rimitive provides three render functions for different SSR needs:
| Function | Use Case |
|---|---|
renderToString | Basic sync SSR — no async data loading |
renderToStringAsync | Waits for all load() boundaries before returning HTML |
renderToStream | Sends HTML immediately, streams data as it loads |
This guide covers renderToString. For async data loading, see SSR with Data Loading. For streaming, see Streaming SSR.
What You Need
Section titled “What You Need”For basic SSR, you need:
- A server adapter that creates elements using parse5 instead of the real DOM
- A client hydration adapter that walks existing DOM instead of creating new elements
Shared Service
Section titled “Shared Service”Start with creating the service a little differently than normal. This time, createService() will take an adapter, so both the server and client can use the same service for running:
import { compose } from '@rimitive/core';import { SignalModule, ComputedModule, EffectModule } from '@rimitive/signals/extend';import { createElModule } from '@rimitive/view/el';import { createMatchModule } from '@rimitive/view/match';import type { Adapter } from '@rimitive/view/types';import type { DOMAdapterConfig } from '@rimitive/view/adapters/dom';
// 👇 New!export function createService(adapter: Adapter<DOMAdapterConfig>) { return compose( SignalModule, ComputedModule, EffectModule, createElModule(adapter), createMatchModule(adapter) );}
export type Service = ReturnType<typeof createService>;Now, this file can be shared with both the server and the client ✨
Server Setup
Section titled “Server Setup”Create a parse5 adapter for server-side rendering:
import { createServer } from 'node:http';import { createParse5Adapter, renderToString } from '@rimitive/ssr/server';import { createService } from './service.js';import { App } from './App.js';
const server = createServer((req, res) => { // Create per-request adapter and service const { adapter, serialize } = createParse5Adapter(); const service = createService(adapter);
// Create and render the app const root = App(service).create(service); const html = renderToString(root, serialize);
res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(`<!DOCTYPE html><html><body> <div class="app">${html}</div> <script src="/client.js"></script></body></html>`);});
server.listen(3000);Next Steps
Section titled “Next Steps”- Client Hydration — Make the server-rendered HTML interactive
- SSR with Data Loading — Fetch data during SSR with
load() - Streaming SSR — Send HTML progressively as data loads