Skip to content

API

ogygia/server

The SvelteKit server handle.

On this page

Auto-generated from the package’s own .d.ts on every build — signatures, JSDoc, and examples straight from the source.

import { … } from 'ogygia/server';

Exports document · handle · liftRegions · restoreRegions · scanRegions · ogygiaTransport · DocumentOptions · LiftedRegion · LiftResult · OgygiaHandleOptions · RegionSpan · RegionKind

document

function

Render a region into a complete ogygia document and return it as a Response.

import { document } from 'ogygia/server';
import { region } from 'ogygia';

return document(region(Dashboard, { stats }), { title: 'ogygia profiler' });
function document(of: RegionValue | PromiseLike<RegionValue>, options?: DocumentOptions): Promise<Response>;

handle

function

function handle(options?: OgygiaHandleOptions): Handle;

liftRegions

function

Lift every TOP-LEVEL <ogygia-region> out of html, leaving an <og-lift> placeholder where each was. Hand shell to the foreign renderer (and, to render a lake / hole, its innerHtml — recurse with liftRegions there so islands nested inside it stay protected), then restoreRegions. Islands come back verbatim. A region deeper than top level rides inside its parent's outerHtml.

function liftRegions(html: string): LiftResult;

restoreRegions

function

Splice lifted regions back over their <og-lift> placeholders, transplanting any attributes the foreign renderer stamped on a placeholder (scoped slot marks — a sc-* class, c-id, s-sn) onto the region's opening tag. The placeholder is matched loosely because the renderer annotates it; only opening-tag attributes are merged, never the region's light DOM. An unknown placeholder is left in place rather than dropped.

function restoreRegions(shell: string, regions: readonly LiftedRegion[]): string;

scanRegions

function

Yield every <ogygia-region> in html, in document order, an island's subtree treated as atomic (its nested regions are not yielded). One linear pass, O(html length); allocates no copy of the document. See the module doc for why this exists and how to use it.

function scanRegions(html: string): Generator<RegionSpan, void, undefined>;

ogygiaTransport

const

The SvelteKit transport entry (install once in universal hooks). TWO entries, ONE codec underneath (hub v2 phase Y): Region preserves the legacy region wire shape/tag for compatibility; OgygiaRef carries EVERY OTHER hub kind through the same ref_reducer / ref_reviver the island seams use — so a universal load can put a store, wire class, fn or resumable derived in page.data, and a remote function can take/return one, all by identity. Kit routes remote args + load data through this same transport, so the symmetry is total. Decode is REQUEST-scoped on the server (no document) — client-sent identity never memoizes across requests — and PAGE-scoped in the browser (reunification).

const ogygiaTransport: {
  Region: {
    encode(value: unknown): false | EncodedRegion;
    decode(raw: EncodedRegion): unknown;
  };
  OgygiaRef: {
    encode(value: unknown): Ref | false;
    decode(ref: Ref): unknown;
  };
}

DocumentOptions

interface

interface DocumentOptions {/*…*/}

DocumentOptions.title

<title> — used only when no component set one via <svelte:head> (the component wins).

title?: string;

DocumentOptions.head

Raw extra head HTML (meta tags, fonts, …), appended after the rendered head.

head?: string;

DocumentOptions.status

HTTP status (default 200).

status?: number;

DocumentOptions.headers

Extra/override response headers. content-type and cache-control: no-store are the defaults (under an eligible FREEZE request the cache-control default is left to the verdict).

headers?: HeadersInit;

DocumentOptions.lang

<html lang> (default 'en').

lang?: string;

DocumentOptions.pageState

Seed for $app/state inside islands (page.data/params/url, route.id, form). The router passes it so islands on a rendered page read $page just like on a Kit-served page. Promises in data/form aren't streamed here — a non-serializable leaf drops that one field.

pageState?: {
    url?: {
      href?: string;
    };
    params?: Record<string, string | undefined>;
    route?: {
      id: string | null;
    };
    status?: number;
    data?: unknown;
    form?: unknown;
    error?: unknown;
  };

LiftedRegion

interface

interface LiftedRegion {/*…*/}

LiftedRegion.kind

island bytes must be restored VERBATIM (reshaping them breaks hydration); a lake / hole MAY be reshaped first via LiftedRegion.withInner.

readonly kind: RegionKind;

LiftedRegion.attrs

The opening tag's attributes (wake / endpoint / entry …), lower-cased.

readonly attrs: Readonly<Record<string, string>>;

LiftedRegion.openTag

<ogygia-region …> — the opening tag, verbatim.

readonly openTag: string;

LiftedRegion.innerHtml

The region's inner HTML ('' for a self-closed or unterminated region).

readonly innerHtml: string;

LiftedRegion.closeTag

</ogygia-region> — the closing tag ('' for a self-closed or unterminated region).

readonly closeTag: string;

LiftedRegion.outerHtml

openTag + innerHtml + closeTag.

readonly outerHtml: string;

LiftedRegion.index

Ties this region to its <og-lift data-i="…"> placeholder in the shell.

readonly index: number;

LiftedRegion.withInner

A copy with the inner HTML replaced — for a lake / hole whose inner a caller has rendered. The opening / closing tags and the index are preserved. Do NOT call this for an island.

withInner(innerHtml: string): LiftedRegion;

LiftResult

interface

interface LiftResult {/*…*/}

LiftResult.shell

The document with every TOP-LEVEL region replaced by an <og-lift data-i="…"></og-lift> placeholder — the only part a foreign renderer should be handed.

shell: string;

LiftResult.regions

The lifted regions, in document order, index-aligned to their placeholders.

regions: LiftedRegion[];

OgygiaHandleOptions

interface

Options for handle.

interface OgygiaHandleOptions {/*…*/}

OgygiaHandleOptions.endpoint

Path (relative to Kit base) of the islands endpoint: the handle answers on it, and every hole and live region on a page is minted against it. Default /__ogygia__. Must start with /.

It must be a path your deployment forwards to the app (behind a proxy that forwards only known prefixes, pick one under them, e.g. /_server/api/__ogygia__). Not under Kit's appDir (/_app/…): Kit answers those itself, before any handle runs.

endpoint?: string;

OgygiaHandleOptions.transform

Post-process the HTML ogygia sends — every document (the chunk carrying </head>; a streamed tail passes untouched) and every region answer (a hole, a lake remount) — e.g. a web-component server render. html in, html out, may be async; it is on the response path, so keep it fast.

It may reshape Svelte-owned markup. ogygia marks the HTML before the call and restores in the browser, before anything hydrates, what the transform moved:

  • a custom element marked og-h is one ogygia restores (in Svelte-owned markup, above it, or in a region answer). To reshape it, render its plan: its slot positions as <slot> elements wrapping the moved children, og-shadow="key …" (the keyed sheets for its shadow root), and optionally og-keep="attr …" (attributes you added that survive the restore; never per-render state). One without og-shadow is left exactly as Svelte wrote it.
  • <template data-og-head="key">css</template> is a shadow sheet; <style> / <link> with data-og-head="key" apply to the page. Both go into <head>, once per key.
  • everything else og-* is ogygia's: carry it along wherever you move a node; it is gone from the final DOM.
transform?: (html: string, ctx: {
    kind: TransformKind;
    csr: boolean;
    event: RequestEvent;
  }) => string | Promise<string>;

RegionSpan

interface

interface RegionSpan {/*…*/}

RegionSpan.kind

island = a hydrated region (its bytes are off-limits to any post-SSR reshaping); lake = a frozen (wake="none") subtree, server HTML the browser never re-creates; hole = a deferred region whose current markup is the page's fallback, not a hydration tree.

kind: RegionKind;

RegionSpan.start

Index of the < that opens <ogygia-region …>.

start: number;

RegionSpan.end

Index one past the > that closes </ogygia-region>. [start, end) is the whole element.

end: number;

RegionSpan.innerStart

Index one past the > of the OPENING tag — the first byte of the region's inner HTML.

innerStart: number;

RegionSpan.innerEnd

Index of the < of the CLOSING tag — one past the last byte of the inner HTML. [innerStart, innerEnd) is the inner HTML a reshaping pass may edit for a lake / hole.

innerEnd: number;

RegionSpan.attrs

The opening tag's attributes (unquoted values). Read wake / endpoint / entry here.

attrs: Readonly<Record<string, string>>;

RegionSpan.depth

Nesting depth — 0 for a top-level region, 1 for one directly inside a lake / hole, and so on. Island subtrees are never entered, so a region deeper than 0 is always inside a lake or hole (never inside another island).

depth: number;

RegionKind

type

type RegionKind = 'island' | 'lake' | 'hole';