Skip to content

Server Rendering

This guide covers the practical setup for basic SSR. If you’re new to SSR concepts, read Intro to SSR first.


Rimitive provides three render functions for different SSR needs:

FunctionUse Case
renderToStringBasic sync SSR — no async data loading
renderToStringAsyncWaits for all load() boundaries before returning HTML
renderToStreamSends 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.


For basic SSR, you need:

  1. A server adapter that creates elements using parse5 instead of the real DOM
  2. A client hydration adapter that walks existing DOM instead of creating new elements

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:

service.ts
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 ✨

Create a parse5 adapter for server-side rendering:

server.ts
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);