RMT Node SSR Adapter
Server-side light DOM and hydration payloads for Node hosts.
What it covers
The Node SSR adapter renders RMT core records on the server and returns a hydration envelope for the browser. It owns no browser DOM and may therefore emit serializable, policy-checked output only.
Public building blocks
xtendrmt/rmt-node-ssr-adapter.jsimplements rendering and streaming.xtendrmt/rmt-node-ssr-adapter.d.tsdescribes the public adapter API.rmt-node-ssr-adapterchecks envelopes, CSP, hydration, and JSONL streaming.
.rmtsources.- Core records and source maps.
- Host adapters for DOM, routing and components.
- Adapter contract
xtend.rmt.node-ssr-adapter.v1. - JSONL streaming frames with
xtend.rmt.node-ssr-jsonl-frame.v1.
Hydration Response Envelope
render().response uses rmt_template_prerender_response with executionMode: "server_prerender_hydrate". The response carries chunk, chunks, request, metadata.adapterKind: "node-ssr" and hydrate_existing target metadata so the client runtime can process it through hydrateResponse or degrade in a controlled way when diagnostics block the render.
Hydration Policies explains the choice between regular SSR hydration, deferred hydration, and a full resume handoff with RMT examples.
Automatic CSP
The adapter creates a framework-managed xtend.rmt.ssr-csp-policy.v1 policy for every render. render().headers, render().response.headers, hydration metadata, JSONL start frames and toHttpResponse() include Content-Security-Policy automatically, so hosts do not need separate CSP plumbing for the default SSR path.
Example
import { createRmtNodeSsrAdapter } from '@ccslabs/xtend/rmt/node-ssr-adapter';
const adapter = createRmtNodeSsrAdapter({ manifest, sourceTexts });
const result = await adapter.render({ source, filePath: 'app.rmt' });
Recommended workflow
Pass normalized core records, validate response status, and send markup, resume data, and CSP metadata together. On a policy diagnostic, return an error report rather than unsafe replacement HTML.
If your backend uses PHP or Laravel, use the same core output with the RMT PHP/Laravel SSR Adapter. Both adapters share the JSONL frame shape for incremental SSR output.
Next steps
Attribute literals and capability coverage
Strings in attributes/attrs are literal, including type: "search" when the model also has a search key. Use explicit $model.path, $item.path, ${model.path} interpolation, or expression records for bindings. This rule applies to portable Node/PHP projection and the DOM renderer as well. Bare model paths in attributes must migrate to explicit bindings. Native and ARIA attributes accept finite scalar values; structured values belong in component properties. Existing structured data-* serialization remains supported. Invalid structured native attributes are omitted with a diagnostic instead of serializing model objects into HTML.
Component SSR capabilities require the registry supplied through manifest and sourceTexts (or a registry). Component metadata existing in a package does not automatically register it in a host. This includes x-section.
getRmtSsrCoverage(result) reports xtend.rmt.ssr-coverage.v1: descriptor element nodes, resume-marked nodes, component nodes, missing-capability nodes, and raw HTML fragments. resumeMarkerCoverage is resume-marked nodes divided by descriptor element nodes, or null when there are none. It measures emitted adoption markers, not successful browser resumes or fallback frequency. Raw HTML fragments are reported separately because their inner nodes are not descriptor-enumerated. The record lives in result.fabricTelemetryHints.coverage; hydration v1 stays unchanged. Combine this output with browser resume diagnostics.