# SSR API reference

> Current emitted signatures and options for @db3.ai/app/ssr.

- Package: `@db3.ai/app/ssr`
- Canonical page: [https://db3.ai/docs/ssr-api](https://db3.ai/docs/ssr-api)
- Markdown: [https://db3.ai/docs/ssr-api.md](https://db3.ai/docs/ssr-api.md)
- Framework source of truth: `packages/app/src/ssr/README.md`

<a id="start"></a>

## Imports and examples

Import supported APIs from `@db3.ai/app/ssr`. These signatures come from the staged package used by consumers. Relative filenames in declarations describe type dependencies; they are not extra supported deep imports.

Use the guide for setup, executable examples, failure handling and ownership. A signature is not proof that every deployment or provider has been exercised.

- [Guide, examples and testing](https://db3.ai/docs/ssr.md)

<a id="markers"></a>

## Document template markers

### Document template markers

```typescript
/** Marker replaced with document head tags during SSR document assembly. */
export declare const SSR_HEAD_MARKER = "<!--platform-ssr-head-->";
/** Marker replaced with application markup during SSR document assembly. */
export declare const SSR_APP_MARKER = "<!--platform-ssr-app-->";
/** Marker replaced with safely serialised hydration state. */
export declare const SSR_STATE_MARKER = "<!--platform-ssr-state-->";
```

<a id="manifest"></a>

## Apply the manifest: @db3.ai/app/ssr/vite

### Apply the manifest: @db3.ai/app/ssr/vite

```typescript
import type { SsrRenderContext } from '../contracts/index.js';
/** Vite SSR manifest mapping rendered module ids to their client build files. */
export type ViteSsrManifest = Record<string, string[]>;
/** Controls which client files should be preloaded for a rendered request. */
export interface ApplyViteSsrManifestOptions {
    /** Whether JavaScript module chunks should be preloaded for hydration. */
    preloadJavaScript?: boolean;
}
/**
 * Adds request-used Vite assets to the single document-head pipeline.
 *
 * @param context - Request-owned SSR context populated by the Vue renderer.
 * @param manifest - Production Vite SSR manifest.
 * @param options - Client preload policy for the current application.
 */
export declare function applyViteSsrManifest<TState extends object>(context: SsrRenderContext<TState>, manifest: ViteSsrManifest, options?: ApplyViteSsrManifestOptions): void;
```

<a id="document"></a>

## Document assembly

### Document assembly

```typescript
import type { SsrRenderContext, SsrRenderResult } from './contracts/index.js';
/**
 * Assembles a complete HTML document from an application render result.
 *
 * The application marker is required because omitting rendered content would
 * silently turn a server-rendered page into an empty client-only shell. Head and
 * state markers are optional for deliberately non-hydrated documents.
 *
 * @param template - Application-owned HTML document shell.
 * @param context - Request-owned metadata collected during rendering.
 * @param result - Application markup and optional response overrides.
 * @returns Complete HTML document ready for the HTTP response.
 */
export declare function renderSsrDocument<TState extends object>(template: string, context: SsrRenderContext<TState>, result: SsrRenderResult<TState>): string;
```

<a id="head"></a>

## Head rendering

### Head rendering

```typescript
import type { DocumentHead } from './contracts/index.js';
/**
 * Renders collected head metadata into HTML tags.
 *
 * @param head - Request-owned document metadata.
 * @returns Escaped HTML ready for the document head marker.
 */
export declare function renderDocumentHead(head: DocumentHead): string;
```

<a id="head-contract"></a>

## Head metadata

### Head metadata

```typescript
/** Attribute value supported by server-rendered document head tags. */
export type DocumentHeadAttributeValue = string | number | boolean | null | undefined;
/** Attributes written onto a server-rendered document head tag. */
export type DocumentHeadAttributes = Record<string, DocumentHeadAttributeValue>;
/**
 * Script emitted through the single server-rendered document head pipeline.
 *
 * Content must come from trusted application code. The renderer prevents a
 * closing script sequence from escaping the tag but does not sanitise scripts.
 */
export interface DocumentHeadScript {
    /** HTML attributes written onto the script element. */
    attributes?: DocumentHeadAttributes;
    /** Trusted inline script or JSON-LD content. */
    content?: string;
}
/**
 * Head metadata collected while rendering one HTTP request.
 *
 * Applications can mutate this request-owned object from their SSR router or
 * page components. It is rendered once into the document template.
 */
export interface DocumentHead {
    /** Browser and search-result title for the rendered document. */
    title?: string;
    /** Meta elements, including descriptions, robots and social metadata. */
    meta: DocumentHeadAttributes[];
    /** Link elements, including canonical URLs and alternate resources. */
    link: DocumentHeadAttributes[];
    /** Trusted scripts, including JSON-LD structured data. */
    script: DocumentHeadScript[];
}
```

<a id="context"></a>

## Request render context

### Request render context

```typescript
import type { DocumentHead } from './DocumentHead.js';
import type { SsrRequest } from './SsrRequest.js';
/** JSON-compatible request state made available to the hydrating client. */
export type SsrState = Record<string, unknown>;
/**
 * Mutable state isolated to one server-side render request.
 *
 * Vue and other renderers may use `modules` to record the modules touched by a
 * render. A later build adapter can map those identifiers to route-specific
 * JavaScript and CSS without changing the application renderer contract.
 */
export interface SsrRenderContext<TState extends object = SsrState> {
    /** Transport-neutral request information. */
    request: SsrRequest;
    /** Response status used when the render result does not override it. */
    status: number;
    /** Document metadata collected during rendering. */
    head: DocumentHead;
    /** State serialised into the document for client hydration. */
    state: TState;
    /** Module identifiers observed by the concrete server renderer. */
    modules: Set<string>;
}
```

<a id="create-context"></a>

## Context factory

### Context factory

```typescript
import type { SsrRenderContext, SsrRequest, SsrState } from './contracts/index.js';
/**
 * Creates isolated mutable state for one server-side render request.
 *
 * @param request - Transport-neutral incoming request.
 * @param state - Optional initial hydration state owned by this request.
 * @returns A fresh render context that is safe to mutate during rendering.
 */
export declare function createSsrRenderContext<TState extends object = SsrState>(request: SsrRequest, state?: TState): SsrRenderContext<TState>;
```

<a id="renderer"></a>

## Renderer

### Renderer

```typescript
import type { SsrRenderContext, SsrState } from './SsrRenderContext.js';
import type { SsrRenderResult } from './SsrRenderResult.js';
/**
 * Application server entry capable of rendering a matched URL.
 *
 * The application owns Vue, its router, data loading and component lifecycle.
 * The framework owns the stable request, document and HTTP response boundary.
 */
export type SsrRenderer<TState extends object = SsrState> = (context: SsrRenderContext<TState>) => SsrRenderResult<TState> | Promise<SsrRenderResult<TState>>;
```

<a id="request"></a>

## Request

### Request

```typescript
/** Header values exposed to a transport-neutral SSR renderer. */
export type SsrRequestHeaderValue = string | string[] | undefined;
/**
 * HTTP request data available to the application SSR entry point.
 *
 * The request target remains relative so query strings and encoded path data
 * are preserved exactly as received by the HTTP adapter.
 */
export interface SsrRequest {
    /** Uppercase HTTP method used for the render request. */
    method: string;
    /** Relative request target, including its query string. */
    url: string;
    /** Incoming headers copied from the concrete HTTP transport. */
    headers: Readonly<Record<string, SsrRequestHeaderValue>>;
}
```

<a id="result"></a>

## Result and headers

### Result and headers

```typescript
import type { DocumentHead } from './DocumentHead.js';
import type { SsrState } from './SsrRenderContext.js';
/** Header value accepted from an application SSR render result. */
export type SsrResponseHeaderValue = string | number | string[];
/**
 * Application-owned output produced for one server-side render request.
 *
 * Optional values override their equivalents collected on the render context.
 */
export interface SsrRenderResult<TState extends object = SsrState> {
    /** Rendered application markup inserted into the HTML document shell. */
    appHtml: string;
    /** Optional HTTP status override, such as 404 for a rendered not-found page. */
    status?: number;
    /** Optional document head override. */
    head?: DocumentHead;
    /** Optional client hydration state override. */
    state?: TState;
    /** Additional response headers such as Location or cache policy. */
    headers?: Record<string, SsrResponseHeaderValue>;
}
```

<a id="state"></a>

## Safe JSON state

### Safe JSON state

```typescript
/**
 * Serialises hydration state without allowing it to terminate an inline script.
 *
 * The output is suitable for an `application/json` script element. Applications
 * should parse the element's text content instead of evaluating JavaScript.
 *
 * @param state - JSON-compatible state produced by the application renderer.
 * @returns Safely escaped JSON text.
 */
export declare function serializeSsrState(state: unknown): string;
```

<a id="fastify"></a>

## Fastify adapter: /ssr/fastify

### Fastify adapter: /ssr/fastify

```typescript
import type { FastifyPluginAsync } from 'fastify';
import type { SsrState } from '../contracts/index.js';
import type { FastifySsrOptions } from './contracts/index.js';
/**
 * Creates an encapsulated Fastify plugin that renders unmatched page requests.
 *
 * Concrete API routes registered on the same Fastify instance remain more
 * specific than the wildcard page route. `shouldRender` can preserve a JSON
 * not-found boundary for reserved prefixes such as `/api`.
 *
 * @param options - Application renderer, document template and route ownership.
 * @returns Fastify plugin ready to register on an application server.
 *
 * @example
 * await server.register(fastifySsr({
 * 	template,
 * 	render: renderPage,
 * 	routes: ['/blog', '/blog/*'],
 * 	shouldRender: (request) => {
 * 		const path = request.url.split('?')[0];
 * 		return path !== '/api' && !path.startsWith('/api/');
 * 	},
 * });
 */
export declare function fastifySsr<TState extends object = SsrState>(options: FastifySsrOptions<TState>): FastifyPluginAsync;
```

<a id="fastify-options"></a>

## Fastify options

### Fastify options

```typescript
import type { SsrRenderer, SsrRequest, SsrState } from '../../contracts/index.js';
/** Loads the current application document template for a render request. */
export type SsrTemplateLoader = (request: SsrRequest) => string | Promise<string>;
/** Determines whether the Fastify SSR fallback owns an incoming URL. */
export type SsrRequestMatcher = (request: SsrRequest) => boolean | Promise<boolean>;
/**
 * Configuration for the optional Fastify SSR adapter.
 *
 * Applications own their renderer and template. The adapter owns request
 * conversion, response headers, status handling and the private error boundary.
 */
export interface FastifySsrOptions<TState extends object = SsrState> {
    /** Application server entry used to render matching requests. */
    render: SsrRenderer<TState>;
    /** HTML shell or loader used for every matching request. */
    template: string | SsrTemplateLoader;
    /** Explicit Fastify page routes owned by this renderer. */
    routes?: readonly string[];
    /** Optional ownership check for excluding API or SPA paths. */
    shouldRender?: SsrRequestMatcher;
}
```

<a id="vite"></a>

## Vite adapter: /ssr/vite

### Vite adapter: /ssr/vite

```typescript
import type { FastifyPluginAsync } from 'fastify';
import type { SsrState } from '../contracts/index.js';
import type { FastifyViteSsrOptions } from './contracts/index.js';
/**
 * Creates a Fastify plugin that owns Vite development and production SSR.
 *
 * The adapter loads application code through Vite in development, immutable
 * build artifacts in production, optional static assets, and route-specific
 * manifest links. Vue, routing and page data remain application concerns.
 *
 * @param options - Vite application paths and explicit SSR route ownership.
 * @returns Fastify plugin ready to register on a web-delivery process.
 *
 * @example
 * await server.register(fastifyViteSsr({
 * 	root: import.meta.dirname,
 * 	routes: ['/blog', '/blog/*'],
 * 	staticAssets: {
 * 		prefix: '/site-assets/',
 * 		directory: 'dist/client/site-assets',
 * 	},
 * }));
 */
export declare function fastifyViteSsr<TState extends object = SsrState>(options: FastifyViteSsrOptions<TState>): FastifyPluginAsync;
```

<a id="vite-options"></a>

## Vite options

### Vite options

```typescript
import type { SsrRenderer, SsrState } from '../../contracts/index.js';
/** Runtime mode used to select Vite development or production integration. */
export type ViteSsrMode = 'development' | 'production';
/** Production client assets served directly by the SSR web process. */
export interface ViteSsrStaticAssets {
    /** URL prefix reserved for built client assets. */
    prefix: string;
    /** Build directory containing the files exposed below the prefix. */
    directory: string;
}
/**
 * Configuration for a first-class Vite SSR application hosted by Fastify.
 *
 * Paths may be absolute or relative to `root`. The adapter owns Vite's
 * development middleware and immutable production build loading while the
 * application owns the renderer exported by its server entry.
 */
export interface FastifyViteSsrOptions<TState extends object = SsrState> {
    /** Absolute application root containing Vite configuration and source files. */
    root: string;
    /** Explicit public page routes rendered by this SSR application. */
    routes: readonly string[];
    /** Runtime mode, defaulting from `NODE_ENV`. */
    mode?: ViteSsrMode;
    /** Optional Vite config file used by this isolated SSR build in development. */
    viteConfigFile?: string;
    /** Source HTML template transformed by Vite during development. */
    template?: string;
    /** Vite development server-entry module id. */
    developmentEntry?: string;
    /** Production client build directory containing the transformed template. */
    clientOutDir?: string;
    /** Production server bundle exporting the application renderer. */
    serverEntry?: string;
    /** Production Vite SSR manifest, or false when the app has no client graph. */
    manifest?: string | false;
    /** Named server-entry export implementing the framework renderer contract. */
    renderExport?: string;
    /** Whether JavaScript files observed through the SSR manifest are preloaded. */
    preloadJavaScript?: boolean;
    /** Optional production client asset directory and public prefix. */
    staticAssets?: ViteSsrStaticAssets;
}
/** Server-entry namespace containing a framework-compatible renderer export. */
export type ViteSsrServerModule<TState extends object = SsrState> = Record<string, SsrRenderer<TState> | unknown>;
```

## Related documentation
- [Render public HTML](https://db3.ai/docs/ssr.md): SSR owns the document and request boundary. Your application owns the pages, router, data and client hydration.

## Guidance for AI tools
Use the documented public import `@db3.ai/app/ssr` and its exported types. Prefer the source-backed examples and behavioural outcomes above over invented APIs or source-relative internal imports.
