# @svelte-lean/query/ssr

> dehydrate(), hydrate(), kitInvalidate(), source() and sources(): server rendering and SvelteKit interop.

Page: https://svelte-lean.vercel.app/query/api/ssr · Markdown: https://svelte-lean.vercel.app/query/api/ssr.md · Index: https://svelte-lean.vercel.app/llms.txt

Server rendering and SvelteKit interop: committed values moved by key from a server load into the page, tags that re-run loads, and endpoints answered by functions instead of HTTP.

> **Note** `./ssr` is experimental: the API can still change in a minor release. Stability per entry point: [Entry points](https://svelte-lean.vercel.app/query.md#entry-points).

## Import

`import`

```ts
import { dehydrate, hydrate, kitInvalidate, source, sources } from '@svelte-lean/query/ssr';
```

## Usage

`src/lib/api/transport.ts`

```ts
// src/lib/api/transport.ts
import { http } from '@svelte-lean/query/http';
import { source, sources } from '@svelte-lean/query/ssr';
import { getMember } from '$api/members';
import type { Member } from '$api/types';

// getMember is answered by a function (a remote function, an RPC call); the rest goes over HTTP.
export const transport = sources(
	[source(getMember, (params, signal) => readMember(Number(params.id), signal))],
	http({ base: '/' })
);
```

## Size

Production Vite builds of a small consumer entry, Svelte external. A marginal row is the bytes the entry adds over the row it names.

| Build | Over | gzip | brotli | Budget (gzip) |
| --- | --- | --- | --- | --- |
| `ssr (marginal)` | `query` | 568 B | 514 B | 700 B |
| `ssr every export (marginal)` | `query` | 1287 B | 1178 B | 1500 B |

Read from `packages/query/artifacts/size.json`. Every entry and its method: [Performance](https://svelte-lean.vercel.app/query/performance.md).

## Functions

No module state: request isolation is one client per request.

### Exports

Runtime exports of the entry.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| # `dehydrate` | `(client: Client, options?: { endpoints? }) => Dehydrated` | – | The successful entries of the client's scope whose access verdict is true, as a plain object. |
| # `hydrate` | `(client: Client, state: Dehydrated \| Promise<Dehydrated> \| null \| undefined) => () => void` | – | Apply records: each only when the entry has no value or an older one. Returns a function that drops the records not used yet. |
| # `kitInvalidate` | `(init: { invalidate }) => Module` | – | Every invalidation calls SvelteKit's invalidate('slq:\<Name\>') and invalidate('slq:\<Name\>:\<id\>'), coalesced per microtask. |
| # `source` | `(endpoint, run: (params, signal) => R \| Promise<R>) => Source` | – | Pairs an endpoint with the function that answers it (a remote function, an RPC call). |
| # `sources` | `(list: Source[], fallback?: Transport) => Transport` | – | A transport that answers the listed endpoints with their functions and the rest with fallback. |

## Types

What dehydrate() returns and what source() makes.

### Dehydrated

A plain object the caller serializes (SvelteKit: devalue).

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| # `v` | `1` | – | Format version. |
| # `entries` | `DehydratedEntry[]` | – | The records. |

### DehydratedEntry

One committed value.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| # `key` | `string` | – | Scope, endpoint id and canonical params (not a digest). |
| # `value` | `unknown` | – | The value. |
| # `updatedAt` | `number` | – | The server's commit time: freshness counts from the server fetch. |
| # `bytes` | `number` | – | Approximate size. |

### Source

What source() returns.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| # `endpoint` | `QueryEndpoint \| MutationEndpoint` | – | The endpoint it answers. |
| # `run` | `(input, signal) => unknown` | – | The function that answers it. |

## Guide

How to use it, with examples: [Server rendering](https://svelte-lean.vercel.app/query/ssr.md). All entry points: [Svelte Lean Query](https://svelte-lean.vercel.app/query.md).
