From 9c88438e58cfefc32f9d3fb80dace326bb04642b Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Thu, 20 Nov 2025 17:34:14 -0700 Subject: [PATCH] docs --- .../docs/06-runtime/05-hydratable.md | 68 ++++--------------- .../svelte/tests/runtime-legacy/shared.ts | 1 - 2 files changed, 13 insertions(+), 56 deletions(-) diff --git a/documentation/docs/06-runtime/05-hydratable.md b/documentation/docs/06-runtime/05-hydratable.md index d6f5d9a1eb..5b87f0ce5f 100644 --- a/documentation/docs/06-runtime/05-hydratable.md +++ b/documentation/docs/06-runtime/05-hydratable.md @@ -2,7 +2,7 @@ title: Hydratable data --- -In Svelte, when you want to render asynchonous content data on the server, you can simply `await` it. This is great! However, it comes with a major pitall: when hydrating that content on the client, Svelte has to redo the asynchronous work, which blocks hydration for however long it takes: +In Svelte, when you want to render asynchonous content data on the server, you can simply `await` it. This is great! However, it comes with a pitall: when hydrating that content on the client, Svelte has to redo the asynchronous work, which blocks hydration for however long it takes: ```svelte

{user.name}

@@ -45,63 +45,21 @@ const rand = hydratable('random', () => Math.random()); If you're a library author, be sure to prefix the keys of your `hydratable` values with the name of your library so that your keys don't conflict with other libraries. -## Imperative API +## Serialization -If you're writing a library with separate server and client exports, it may be more convenient to use the imperative API: - -```ts -import { hydratable } from 'svelte'; - -const value = hydratable.get('foo'); // only works on the client -const hasValue = hydratable.has('foo'); -hydratable.set('foo', 'whatever value you want'); // only works on the server -``` - -## Custom serialization - -By default, Svelte uses [`devalue`](https://npmjs.com/package/devalue) to serialize your data on the server so that decoding it on the client requires no dependencies. If you need to serialize additional things not covered by `devalue`, you can provide your own transport mechanisms by writing custom `encode` and `decode` methods. - -### `encode` - -Encode receives a value and outputs _the JavaScript code necessary to create that value on the client_. For example, Svelte's built-in encoder looks like this: - -```js -import * as devalue from 'devalue'; - -/** - * @param {any} value - */ -function encode (value) { - return devalue.uneval(value); -} - -encode(['hello', 'world']); // outputs `['hello', 'world']` -``` - -### `decode` - -`decode` accepts whatever the JavaScript that `encode` outputs resolves to, and returns whatever the final value from `hydratable` should be. - -### Usage - -When using the isomorphic API, you must provide either `encode` or `decode`, depending on the environment. This enables your bundler to treeshake the unneeded code during your build: +All data returned from a `hydratable` function must be serializable. Not to fear, though -- this doesn't mean you're limited to JSON! Svelte uses [`devalue`](https://npmjs.com/package/devalue) for serialization, which means it can serialize all sorts of things, including `Map`, `Set`, `URL`, and `BigInt`. Check the documentation page for a full list. In addition to these, thanks to some Svelte magic, you can also fearlessly use promises: ```svelte -``` - -For the imperative API, you just provide `encode` or `decode` depending on which method you're using: - -```ts -import { hydratable } from 'svelte'; -import { encode, decode } from '$lib/encoders'; -const random = hydratable.get('random', { decode }); -hydratable.set('random', Math.random(), { encode }); +{await promises.one} +{await promises.two} ``` diff --git a/packages/svelte/tests/runtime-legacy/shared.ts b/packages/svelte/tests/runtime-legacy/shared.ts index 96164886f4..3469f4ab93 100644 --- a/packages/svelte/tests/runtime-legacy/shared.ts +++ b/packages/svelte/tests/runtime-legacy/shared.ts @@ -566,7 +566,6 @@ async function run_test_variant( } } catch (err) { if (config.runtime_error) { - console.log(err); assert.include((err as Error).message, config.runtime_error); } else if (config.error && !unintended_error) { assert.include((err as Error).message, config.error);