Server/Packages/Server Renderer/API reference
@sigx/server-renderer · Stable

API reference#

Every public export of @sigx/server-renderer v0.13.0, grouped by kind. The import path for each symbol is noted, since the package splits into three subpaths: @sigx/server-renderer (main), @sigx/server-renderer/server, and @sigx/server-renderer/client.

Document render functions#

These take a full HTML template with an outlet marker and assemble the complete response (head injection, app shell, state serialization, async content). State serialization is on by default here (serializeState: false opts out) — these are the zero-config entry points. All accept a JSX element or an App and a DocumentOptions. Exported from the main entry and /server; also available as methods on createSSR() (where registered plugins apply).

renderDocument#

Render a complete HTML document to a string. Default mode: 'blocking' — every keyed useData/useStream resolves inline (no placeholders or replacement scripts), which is ideal for crawlers and AI agents. The sigx:ready completion script is still emitted so gated hydration runs.

TypeScript
function renderDocument(input: JSXElement | App, options: DocumentOptions): Promise<string>
  • Returns — a promise resolving to the full document HTML. Rejects if options.signal aborts.

renderDocumentToNodeStream#

Stream a complete document as a Node Readable, plus a shell promise that settles before the first byte — await it to decide the HTTP status code, then pipe. Default mode: 'stream'.

TypeScript
function renderDocumentToNodeStream(
  input: JSXElement | App,
  options: DocumentOptions
): { stream: import('node:stream').Readable; shell: Promise<void> }
  • Returns{ stream, shell }. The stream is byte-mode (not object mode) so backpressure is measured in bytes.

renderDocumentToWebStream#

Stream a complete document as a web ReadableStream<Uint8Array> of UTF-8 bytes, ready as a Response body (edge runtimes, Workers, Deno). Default mode: 'stream'.

TypeScript
function renderDocumentToWebStream(input: JSXElement | App, options: DocumentOptions): ReadableStream<Uint8Array>

DocumentOptions#

Options for the renderDocument* family. Extends SSRContextOptions.

TypeScript
interface DocumentOptions extends SSRContextOptions {
  template: string;                                   // full HTML with the outlet marker
  outlet?: string;                                    // default: '<!--ssr-outlet-->'
  mode?: 'stream' | 'blocking';                       // default: 'blocking' (string) / 'stream' (streams)
  signal?: AbortSignal;                               // abort: stream ends early, string render rejects
  onError?: (error: Error, phase: 'shell' | 'stream') => void;
  serializeState?: boolean;                           // default: true
}
  • template — the HTML document; must contain outlet. Head tags inject before </head>; the tail splits at </body> so entry scripts flush with the shell.
  • mode'blocking' resolves all keyed async inline; 'stream' flushes the shell then swaps in async chunks out of order.
  • onError'shell' fires before any byte is produced (you can still send a 500); 'stream' fires mid-stream. Per-component errors stream their own fallbacks and do not reach this.
  • serializeState — serialize resolved useData/useStream values for hydration pickup. Set false to opt out.

Production fetch handler#

Exported from /server and the main entry — both WinterCG-clean. See The fetch handler for the guide.

createFetchHandler#

Create a fetch-shaped production request handler — the WinterCG sibling of createRequestHandler for Cloudflare Workers, Deno, Bun, Vercel Edge and Netlify. Streams shell-first, switches to mode: 'blocking' for crawlers, resolves useResponse status/redirects before the first byte.

TypeScript
function createFetchHandler<TPlatform = unknown>(
  options: FetchHandlerOptions<TPlatform>
): FetchHandler<TPlatform>

type FetchHandler<TPlatform = unknown> =
  (request: Request, platform?: TPlatform) => Promise<Response>
// `platform` becomes REQUIRED when TPlatform doesn't admit undefined

interface FetchHandlerOptions<TPlatform = unknown> {
  template: string | ((url: string, request: Request, platform: TPlatform) => string | Promise<string>);
  app: (url: string, request: Request, platform: TPlatform) => App | JSXElement | Promise<App | JSXElement>;
  document?: Omit<DocumentOptions, 'template' | 'mode'>
    | ((url: string, request: Request, platform: TPlatform) => Omit<DocumentOptions, 'template' | 'mode'>);
  isBot?: (userAgent: string, request: Request) => boolean;   // default: defaultIsBot
  ssr?: Pick<SSRInstance, 'renderDocumentChunks'>;            // default: plugin-less shared instance
}

defaultIsBot#

The crawler UA regex shared by the fetch, Node and dev handlers.

TypeScript
function defaultIsBot(userAgent: string): boolean

chunksToBytes#

Encode a chunk generator as a pull-based UTF-8 byte stream (backpressure honored; cancellation releases the generator). The encoder under renderDocumentToWebStream and createFetchHandler.

TypeScript
function chunksToBytes(chunks: AsyncGenerator<string>): ReadableStream<Uint8Array>

Render functions#

renderToString#

Render a JSX element or App to the app-shell HTML string — no template, head injection, or state serialization (use renderDocument for those). Awaits all keyed useData/useStream components and plugin streaming chunks before resolving. Accepts an App from defineApp() (extracts the root component + AppContext for DI) or a raw JSX element.

TypeScript
function renderToString(input: JSXElement | App, context?: SSRContext): Promise<string>
  • input — a raw JSX element, or an App from defineApp().
  • context — optional pre-built SSRContext (auto-created if omitted).
  • Returns — a promise resolving to the full HTML string.
  • Exported from the main entry and /server.

renderToStream#

Render to a web ReadableStream<string>. Pull-based with 4KB chunk batching and natural backpressure; streams the shell first, then async-component replacement scripts interleaved as they resolve, then a final completion script. Recommended default.

TypeScript
function renderToStream(input: JSXElement | App, context?: SSRContext): ReadableStream<string>
  • input — JSX element or App.
  • context — optional SSRContext.
  • Returns — a web ReadableStream<string>.
  • Exported from the main entry and /server.

renderToNodeStream#

Render to a Node.js Readable stream (objectMode), bypassing WebStream overhead. Faster than renderToStream() on Node — recommended for Express/Fastify/H3. Pipe directly to the HTTP response.

TypeScript
function renderToNodeStream(input: JSXElement | App, context?: SSRContext): Readable
  • input — JSX element or App.
  • context — optional SSRContext.
  • Returns — a Node Readable (pipe to the response: stream.pipe(res)).
  • Exported from /server only (not the main entry).

renderToStreamWithCallbacks#

Callback-based streaming for fine-grained control. Calls onShellReady(html) once with the full synchronous shell (including plugin-injected HTML and the completion script), then onAsyncChunk(chunk) per resolved async component, then onComplete(); onError(err) on failure.

TypeScript
function renderToStreamWithCallbacks(input: JSXElement | App, callbacks: StreamCallbacks, context?: SSRContext): Promise<void>
  • input — JSX element or App.
  • callbacks — a StreamCallbacks set.
  • context — optional SSRContext.
  • Returns — a promise that resolves when streaming completes.
  • Exported from /server only (not the main entry).

renderVNodeToString#

Low-level helper that renders a single VNode subtree to an HTML string using an existing SSRContext (used internally for deferred async content).

TypeScript
function renderVNodeToString(element: JSXElement, ctx: SSRContext, appContext?: AppContext | null): Promise<string>
  • element — the VNode subtree to render.
  • ctx — an existing SSRContext.
  • appContext — optional AppContext for DI.
  • Returns — a promise resolving to the subtree's HTML.
  • Exported from the main entry and /server.

SSR instance & context#

createSSR#

Creates an SSR render pipeline. Plugins are installed on the app (app.use(pack())) and merged in per render call — the public install path; SSRInstance.use() was removed in 0.13. Pass a render input as a JSX element or an App, and render complete documents with .renderDocument()/ .renderDocumentToNodeStream()/.renderDocumentToWebStream(), or a shell with the lower-level .render()/.renderStream()/.renderNodeStream()/ .renderStreamWithCallbacks(). With no plugins the hooks are no-ops and it behaves like the standalone functions; islands/selective/resumable hydration are layered on as SSRPlugins. The renderDocument* methods append stateSerializationPlugin() automatically unless it is already registered or serializeState: false is passed.

TypeScript
function createSSR(instanceOptions?: CreateSSROptions): SSRInstance
  • instanceOptions — advanced/internal { plugins? }; prefer installing packs with app.use(pack()). Instance plugins run before app-carried ones (deduped by name, first wins).
  • Returns — an SSRInstance.
  • Exported from the main entry.

createSSRContext#

Create a fresh SSRContext that tracks component IDs/markers, collected <head> HTML, plugin data, streaming mode, and pending async components.

TypeScript
function createSSRContext(options?: SSRContextOptions): SSRContext
  • optionsstreaming, onComponentError, and appContext (seed the context from an existing AppContext so inject() resolves during render).
  • Returns — a new SSRContext.
  • Exported from the main entry and /server.

SSRContext state & pack authoring (0.13)#

The request-scoped SSRContext exposes a typed contract for pack authors:

TypeScript
// register request-scoped state to ship to the client under a key
registerSerializedState(key: string, value: unknown): void;
// the component currently rendering, and the recorded hydration boundaries
currentComponentId(): number | undefined;
boundaries(): ReadonlyMap<number, SSRBoundaryRecord>;
  • registerSerializedState(key, value) — publish a value into the page's window.__SIGX_ASYNC__ blob under key. The blob is codec-aware: top-level and nested Date / Map / Set / bigint / URL / RegExp / explicit undefined — plus any registered custom type handlers — round-trip, not just JSON primitives. Functions and circular references are still rejected.
  • A plugin can also implement the onStreamEnd(ctx) server hook — called once after the streaming loop drains, before the completion script — to flush end-of-response state.

Packs install through a small public seam:

TypeScript
interface SSRPack extends SSRPlugin { install(app: App): void }
  • SSRPack — an SSRPlugin with an install(app) method; app.use(pack) calls it. Inside, provideSSRPlugin(app._context, pack) registers the plugin on the app so the render pipeline picks it up (getSSRPlugins / SSR_PLUGINS_TOKEN read it back).
  • reviveFromServer(...) — now public — revives a value serialized into the hydration blob (applying the same codec + custom handlers) on the client; it is exported from the client entry (@sigx/server-renderer/client).

Head management#

useHead() itself lives in core sigx (a browser-standalone composable). During server rendering it collects configs onto the per-request SSRContext; this package only renders them. renderDocument* injects the result automatically.

renderHeadToString#

Render an array of collected HeadConfig objects to an HTML string. Dedupes meta by name/property/http-equiv/charset, applies the last title (through titleTemplate's %s if set), and HTML/attr-escapes output.

TypeScript
function renderHeadToString(configs: HeadConfig[]): string
  • configs — collected HeadConfig objects (the HeadConfig type is exported from sigx).
  • Returns — the head HTML string.
  • Exported from the main entry.

State serialization#

stateSerializationPlugin#

The built-in SSRPlugin (name 'sigx:state') that ships values resolved by keyed useData/useStream to the client as window.__SIGX_ASYNC__, keyed by the calls' explicit keys, so fetchers don't re-run after hydration. It's a plain SSRPlugin, so opt in for the lower-level render APIs by passing it to createSSR({ plugins: [stateSerializationPlugin()] }); the renderDocument* family enables it by default.

TypeScript
function stateSerializationPlugin(): SSRPlugin
  • Exported from the main entry.

serializeAsyncScript / asyncAssignmentJs#

Low-level helpers behind the state plugin: serializeAsyncScript builds the <script> that assigns the __SIGX_ASYNC__ blob; asyncAssignmentJs produces the assignment JS for a set of key/value pairs. Both exported from /server.

TypeScript
function serializeAsyncScript(values: Record<string, unknown>): string
function asyncAssignmentJs(values: Record<string, unknown>): string

Streaming script helpers#

generateStreamingScript#

Returns the one-time client bootstrap <script> defining window.$SIGX_REPLACE(id, html), which swaps an async placeholder ([data-async-placeholder="id"]) with rendered HTML and dispatches a sigx:async-ready CustomEvent. Emitted once before any replacement scripts.

TypeScript
function generateStreamingScript(): string
  • Returns — the bootstrap script HTML.
  • Exported from /server.

generateReplacementScript#

Generate the <script>$SIGX_REPLACE(id, "...escaped html...")</script> for a resolved async component, used during streaming to replace its placeholder.

TypeScript
function generateReplacementScript(id: number, html: string, extraScript?: string, preScript?: string): string
  • id — the async component id.
  • html — rendered HTML to inject.
  • extraScript — optional script appended after the replacement call.
  • preScript — optional script run before the replacement call (the state plugin installs per-component keys here, ahead of hydration listeners).
  • Returns — the replacement script HTML.
  • Exported from /server.

generateAppendBootstrap / generateAppendScript#

Progressive-text streaming helpers for useStream. generateAppendBootstrap returns the one-time window.$SIGX_APPEND(id, text) bootstrap; generateAppendScript returns a per-chunk append call that grows a streaming text node as tokens arrive.

TypeScript
function generateAppendBootstrap(): string
function generateAppendScript(id: number, text: string): string
  • Exported from /server.

escapeJsonForScript#

Escape a JSON string for safe embedding inside a <script> tag (replaces <, >, U+2028, U+2029) to prevent XSS / script-context breakout.

TypeScript
function escapeJsonForScript(json: string): string
  • json — the JSON string to escape.
  • Returns — the escaped string.
  • Exported from /server.

generateSignalKey#

Generate the stable serialization key for a signal during SSR state capture/restore. Named signals use the name; unnamed use a positional key ($0, $1, …). Server (tracking) and client (restoring) MUST both use this for key parity.

TypeScript
function generateSignalKey(name: string | undefined, index: number): string
  • name — the signal's name, or undefined for positional keying.
  • index — the declaration index for unnamed signals.
  • Returns — the serialization key.
  • Exported from the main entry and /server.

Client hydration#

ssrClientPlugin#

A sigx app Plugin that adds app.hydrate(container) to the App instance. hydrate() resolves a string selector or Element, finds the root component + AppContext, and hydrates existing SSR DOM (or falls back to client-side render() when the container has no SSR content).

TypeScript
const ssrClientPlugin: Plugin
  • Use via defineApp(<App/>).use(ssrClientPlugin).hydrate('#root').
  • Exported from the main entry and /client.

hydrate#

Core hydration entry: normalizes element to a VNode, sets the current AppContext for DI, runs registered client plugins' beforeHydrate (return false to skip the DOM walk, e.g. resumable SSR), walks existing SSR DOM via hydrateNode, then runs afterHydrate hooks. Stores _vnode on the container.

TypeScript
function hydrate(element: any, container: Element, appContext?: AppContext): void
  • Exported from /client.

hydrateNode#

Hydrate a single VNode against existing DOM (no DOM creation in the happy path); attaches events/props/directives/refs, skips SSR comment markers (<!--t-->, <!--$c:N-->), recovers from minor SSR drift by scanning forward (dev warns), and returns the next sibling DOM node. Recurses for fragments/components/elements.

TypeScript
function hydrateNode(vnode: VNode, dom: Node | null, parent: Node): Node | null
  • Exported from /client.

hydrateComponent#

Hydrate a single component: locates its trailing <!--$c:N--> marker, builds reactive props/slots, creates the ComponentSetupContext (with the client ssr flags and any serverState to restore keyed useData/useStream values), runs setup, and creates the reactive effect that hydrates-on-first-run then patches. Used by SSR strategy plugins for selective/island hydration.

TypeScript
function hydrateComponent(vnode: VNode, dom: Node | null, parent: Node, serverState?: Record<string, any>, trailingMarker?: Comment | null): Node | null
  • Exported from /client.

registerClientPlugin#

Register a client-side SSRPlugin so its client.beforeHydrate/hydrateComponent/afterHydrate hooks run during hydration. The mechanism behind selective/island/resumable hydration strategies.

TypeScript
function registerClientPlugin(plugin: SSRPlugin): void
  • Exported from /client.

getClientPlugins / clearClientPlugins#

Return all currently registered client-side SSRPlugins, or clear them (useful in tests).

TypeScript
function getClientPlugins(): SSRPlugin[]
function clearClientPlugins(): void
  • Exported from /client.

createRestoringSignal#

Create a signal() replacement that restores values from server-captured state by key (via generateSignalKey), avoiding client re-fetch during hydration. Dev-warns once if an unnamed (positional-key) signal is restored, since declaration-order drift between server/client builds silently mismatches state.

TypeScript
function createRestoringSignal(serverState: Record<string, any>): SSRSignalFn
  • Exported from /client.

setPendingServerState#

Set server-captured signal state to apply to the next component mounted during hydration (used internally when mounting async components after streaming). The context extension consumes and clears it.

TypeScript
function setPendingServerState(state: Record<string, any> | null): void
  • Exported from /client.

getCurrentAppContext / setCurrentAppContext#

Get or set the AppContext tracked during hydration (for DI in deferred/island hydration callbacks).

TypeScript
function getCurrentAppContext(): AppContext | null
function setCurrentAppContext(ctx: AppContext | null): void
  • Exported from /client.

Interfaces & types#

SSRInstance#

The object returned by createSSR(). Plugins come from the app you render (app.use(pack())) — there is no use() method as of 0.13. Render methods accept SSRContextOptions or a pre-built SSRContext. createContext() builds a raw SSRContext with this instance's plugins pre-configured.

TypeScript
interface SSRInstance {
  // Complete-document rendering (state serialization on by default)
  renderDocument(input: JSXElement | App, options: DocumentOptions): Promise<string>;
  renderDocumentToNodeStream(input: JSXElement | App, options: DocumentOptions): { stream: import('node:stream').Readable; shell: Promise<void> };
  renderDocumentToWebStream(input: JSXElement | App, options: DocumentOptions): ReadableStream<Uint8Array>;
  // Lower-level shell rendering
  render(input: JSXElement | App, options?: SSRContextOptions | SSRContext): Promise<string>;
  renderStream(input: JSXElement | App, options?: SSRContextOptions | SSRContext): ReadableStream<string>;
  renderNodeStream(input: JSXElement | App, options?: SSRContextOptions | SSRContext): import('node:stream').Readable;
  renderStreamWithCallbacks(input: JSXElement | App, callbacks: StreamCallbacks, options?: SSRContextOptions | SSRContext): Promise<void>;
  createContext(options?: SSRContextOptions): SSRContext;
}
  • Exported as a type from the main entry.

SSRPlugin#

The strategy-agnostic extension interface that implements selective/island/resumable/Defer hydration without core changes. Server hooks fire during render; client hooks fire during hydration.

TypeScript
interface SSRPlugin {
  name: string;
  server?: {
    setup?(ctx: SSRContext): void;
    transformComponentContext?(ctx: SSRContext, vnode: VNode, componentCtx: ComponentSetupContext): ComponentSetupContext | void;
    suppressComponentRender?(id: number, vnode: VNode, ctx: SSRContext): { placeholder?: string } | void;
    afterRenderComponent?(id: number, vnode: VNode, html: string, ctx: SSRContext): string | void;
    handleAsyncSetup?(id: number, ssrLoads: Promise<void>[], renderFn: () => any, ctx: SSRContext): { mode: 'block' | 'stream' | 'skip'; placeholder?: string } | void;
    onAsyncComponentResolved?(id: number, html: string, ctx: SSRContext): { html?: string; script?: string; preScript?: string } | void;
    getInjectedHTML?(ctx: SSRContext): string | Promise<string>;
    getStreamingChunks?(ctx: SSRContext): AsyncGenerator<string> | void;
  };
  client?: {
    beforeHydrate?(container: Element): boolean | void;
    transformComponentContext?(vnode: VNode, componentCtx: ComponentSetupContext): ComponentSetupContext | void;
    hydrateComponent?(vnode: VNode, dom: Node | null, parent: Node): Node | null | undefined;
    afterHydrate?(container: Element): void;
  };
}

Server hooks, in lifecycle order around each component:

  • server.transformComponentContext runs after the ComponentSetupContext is built but before setup() — mutate or replace it (swap ctx.signal, adjust the ssr helper, transform props). Return a new context, or void to accept as-is.
  • server.suppressComponentRender runs after transformComponentContext (id assigned), still before setup() — return an object to skip the component's setup/render entirely and emit its (optional) placeholder string followed by the <!--$c:id--> hydration marker; return void to render normally. First plugin to return an object wins. This is how islands make client:only ship no server HTML, and it works in both string and streaming modes.
  • server.afterRenderComponent receives the rendered HTML and can transform it.
  • server.handleAsyncSetup chooses block/stream/skip per async component; onAsyncComponentResolved can rewrite the streamed replacement (with script / preScript); getInjectedHTML and getStreamingChunks emit extra markup.

Client hooks (during hydration):

  • client.beforeHydrate returning false skips the default DOM walk (resumable).
  • client.transformComponentContext is the hydration-time mirror of server.transformComponentContext: it runs after the context is built and before setup() during hydration (no SSRContext is available then, so only the vnode and built context are passed). A strategy can swap ctx.signal for a variant that restores each signal from server-captured state — keeping render and hydration symmetric.
  • client.hydrateComponent returning a Node claims a component (islands intercept client:* props).
  • Exported as a type from the main entry.

SSRContext#

Per-render context tracking component IDs/markers, collected head HTML, streaming flag, pending async components, and per-plugin data (get/setPluginData keyed by plugin name).

TypeScript
interface SSRContext {
  _componentId: number;
  _componentStack: number[];
  _head: string[];
  _onComponentError?: (error: Error, componentName: string, componentId: number) => string | null;
  _plugins?: SSRPlugin[];
  _pluginData: Map<string, any>;
  _streaming: boolean;
  _pendingAsync: CorePendingAsync[];
  nextId(): number;
  pushComponent(id: number): void;
  popComponent(): number | undefined;
  addHead(html: string): void;
  getHead(): string;
  getPluginData<T>(pluginName: string): T | undefined;
  setPluginData<T>(pluginName: string, data: T): void;
}
  • Exported as a type from the main entry and /server.

SSRContextOptions#

Options for createSSRContext() and the render methods. streaming defaults to true. onComponentError returns fallback HTML for a component whose setup() throws, or null for the default error placeholder.

TypeScript
interface SSRContextOptions {
  streaming?: boolean;
  onComponentError?: (error: Error, componentName: string, componentId: number) => string | null;
}
  • Exported as a type from the main entry and /server.

RenderOptions#

Optional wrapper carrying a custom SSRContext (auto-created if absent).

TypeScript
interface RenderOptions {
  context?: SSRContext;
}
  • Exported as a type from the main entry and /server.

CorePendingAsync#

A core-managed pending async component: its component id plus a promise resolving to its rendered HTML once its keyed useData/useStream data resolves. Populated by render-core in streaming mode when no plugin overrides.

TypeScript
interface CorePendingAsync {
  id: number;
  promise: Promise<string>;
}
  • Exported as a type from the main entry and /server.

StreamCallbacks#

Callback set for renderToStreamWithCallbacks(): onShellReady(shell html), onAsyncChunk(per resolved async component), onComplete(), onError(err).

TypeScript
interface StreamCallbacks {
  onShellReady: (html: string) => void;
  onAsyncChunk: (chunk: string) => void;
  onComplete: () => void;
  onError: (error: Error) => void;
}
  • Exported as a type from /server.

SSRHelper#

The ssr object exposed as ctx.ssr on every ComponentSetupContext — two environment flags for the rare branch that must know where it is running. Async data loading lives in the useData/useStream composables (from sigx), not here.

TypeScript
interface SSRHelper {
  readonly isServer: boolean;     // running on the server
  readonly isHydrating: boolean;  // hydrating server-rendered DOM on the client
}
  • Exported as a type from the main entry.

HeadConfig & friends#

Config objects passed to useHead()/renderHeadToString(). titleTemplate uses %s as the title placeholder; meta is deduped by name/property/http-equiv/charset.

TypeScript
interface HeadConfig {
  title?: string;
  titleTemplate?: string;
  meta?: HeadMeta[];
  link?: HeadLink[];
  script?: HeadScript[];
  htmlAttrs?: { lang?: string; dir?: string; [key: string]: string | undefined };
  bodyAttrs?: { class?: string; [key: string]: string | undefined };
}

HeadMeta, HeadLink and HeadScript are the per-tag descriptors (boolean script attrs like async/defer render as bare attributes; innerHTML becomes the script body). All exported as types from the main entry.

SSRSignalFn#

signal() function type augmented with an optional name used as the hydration serialization key. Shared by server tracking signals and client restoring signals.

TypeScript
type SSRSignalFn = {
  <T extends Primitive>(initial: T, name?: string): PrimitiveSignal<T>;
  <T extends object>(initial: T, name?: string): Signal<T>;
}
  • Exported as a type from the main entry and /server (re-exported from /client).

HydrateFn#

The hydrate function signature (mirrors the MountFn pattern).

TypeScript
type HydrateFn<TContainer = any> = (element: any, container: TContainer, appContext: AppContext) => (() => void) | void
  • Exported from /client alongside ssrClientPlugin.

ComponentFactory / InternalVNode#

ComponentFactory is the minimal component-factory shape consumed by hydrateComponent; InternalVNode is a VNode extended with internal hydration bookkeeping (subtree refs, reactive effect, props/slots), exposed for plugin authors. Both exported as types from /client.

Module augmentations#

The package augments @sigx/runtime-core via declare module to integrate SSR into the core framework types. These apply automatically on import: getSSRProps on directive definitions, hydrate() on App (via ssrClientPlugin), and the ssr helper on ComponentSetupContext.

The client:* directive types (client:load, client:visible, …) are not part of this package — they ship with @sigx/ssr-islands via its /jsx subpath.