Skip to content

API

ogygia/server

The SvelteKit server handle.

On this page

This page is generated from the package’s own .d.ts files on every build, so the signatures, descriptions and examples below always match 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;
  };
  [REF_WIRE_KEY]: {
    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";