Server/Packages/Islands/Plugin setup
@sigx/ssr-islands · Stable

Plugin setup#

islandsPlugin() is an SSRPlugin for @sigx/server-renderer. On the server it intercepts client:* components, captures their signal state, and injects the hydration data; on the client it schedules deferred hydration.

Registering the plugin#

Add it to your SSR instance with .use():

TypeScript
import { createSSR } from '@sigx/server-renderer';
import { islandsPlugin } from '@sigx/ssr-islands';

const ssr = createSSR().use(islandsPlugin());
const html = await ssr.render(<App />);

That single registration wires both the server hooks (during render) and the client hooks (during hydration). On the client you still register the island components and call hydrateIslands() — see Registry & code splitting.

What it does#

During render, the plugin:

  • intercepts every component carrying a client:* directive,
  • captures its signal state (so the client can restore it instead of re-fetching),
  • manages async streaming for islands, and
  • injects a __SIGX_ISLANDS__ JSON script with each island's strategy, props, state and (optionally) chunk URL.

During hydration, it intercepts those same components in the DOM walk and schedules each according to its strategy (load / idle / visible / media / only).

Options#

islandsPlugin(options?) takes an IslandsPluginOptions:

TypeScript
interface IslandsPluginOptions {
    /** Custom client-side hydration strategies, keyed by name. */
    strategies?: Record<string, (el: Element, hydrate: () => void) => void>;
    /** Island manifest mapping component names to their chunk URLs. */
    manifest?: Record<string, { chunkUrl: string; exportName: string }>;
}

Custom strategies#

Add your own scheduling strategy alongside the built-in five. A strategy receives the element and a hydrate callback to invoke when it should run:

TypeScript
const ssr = createSSR().use(islandsPlugin({
    strategies: {
        // hydrate after a fixed delay
        delayed: (el, hydrate) => setTimeout(hydrate, 2000),
    },
}));

Manifest (chunk URLs)#

Pass a manifest so islands carry their chunk URL in the hydration data — the client can then load each chunk on demand without an eager registerComponent() call. The manifest is generated by sigxIslandsPlugin() from @sigx/vite during the build:

TypeScript
import manifest from './dist/island-manifest.json';

const ssr = createSSR().use(islandsPlugin({ manifest }));

With a manifest, each island's chunkUrl and exportName are written into __SIGX_ISLANDS__, and loadIslandComponent() resolves the component straight from its chunk.

Signal-state transfer (low level)#

The plugin handles state capture for you. The underlying helpers are exported for custom server pipelines (from @sigx/ssr-islands or @sigx/ssr-islands/server):

  • createTrackingSignal(signalMap) — a signal() replacement that records signal names and values during async setup.
  • serializeSignalState(signalMap) — serialize the captured map for the client.
  • generateIslandDataScript(islandData) — produce the __SIGX_ISLANDS__ JSON script for a set of islands.

State keys come from generateSignalKey (re-exported from @sigx/server-renderer), so server capture and client restore line up — which is why naming the signals that hold server-loaded state matters — see Rendering & streaming.

Next steps#