You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* defer for client-side navigations
* docs
* changeset
* needs lots of cleanup, but works for client-side navigations
* remove defer
* deduplicate
* extract common logic into generator and reuse
* ssr
* update changelog
* fixes
* update docs
* try this
* this fucking timing stuff
* fingers crossed
* incapable of getting ten lines of code right without intellisense
* remove unpredictable uses tracking in favor of docs and warning
* too many braces
* these tests are killing me
* combine streaming and promise unwrapping docs
* add comment about non-streaming platforms
* typo
* move warning to load_server_data, make it more situation-specific
* lol wut
* symmetry
* tweak
* simplify
* use conventional names
* add a Deferred interface, remove belt and braces (could mask legitimate bugs)
* if done is true, value is guaranteed to be undefined
* remove outdated comments
* we can just reuse the object
* use text/plain for easier inspecting
* make var local
* add comment
* hoist reviver
* hoist replacer
* separate synchronously serialized data from subsequent chunks
* remove logs
* simplify
* lint
* put everything in a single non-module script
* rename tests
* lint
* small tweak to aid minifiability
* oops
* for now, skip streaming tests with vite preview
* remove only
* squelch erroneous access warnings
* only set etag when no streaming
* warn if streaming when csr === false
* rename file
* doh
* Update documentation/docs/20-core-concepts/20-load.md
Co-authored-by: Geoff Rich <[email protected]>
* Update documentation/docs/20-core-concepts/20-load.md
Co-authored-by: Geoff Rich <[email protected]>
* Update documentation/docs/20-core-concepts/20-load.md
* Update documentation/docs/20-core-concepts/20-load.md
* Update documentation/docs/20-core-concepts/20-load.md
* add some juicy keywords
* error handling
* fix bad link
* fix some stuff
* generous timeouts
---------
Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Geoff Rich <[email protected]>
Copy file name to clipboardExpand all lines: documentation/docs/20-core-concepts/20-load.md
+38-13Lines changed: 38 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -174,7 +174,7 @@ Universal `load` functions are called with a `LoadEvent`, which has a `data` pro
174
174
175
175
A universal `load` function can return an object containing any values, including things like custom classes and component constructors.
176
176
177
-
A server `load` function must return data that can be serialized with [devalue](https://github.com/rich-harris/devalue) — anything that can be represented as JSON plus things like `BigInt`, `Date`, `Map`, `Set` and `RegExp`, or repeated/cyclical references — so that it can be transported over the network.
177
+
A server `load` function must return data that can be serialized with [devalue](https://github.com/rich-harris/devalue) — anything that can be represented as JSON plus things like `BigInt`, `Date`, `Map`, `Set` and `RegExp`, or repeated/cyclical references — so that it can be transported over the network. Your data can include [promises](#streaming-with-promises), in which case it will be streamed to browsers.
178
178
179
179
### When to use which
180
180
@@ -420,36 +420,59 @@ export function load({ locals }) {
420
420
421
421
In the browser, you can also navigate programmatically outside of a `load` function using [`goto`](modules#$app-navigation-goto) from [`$app.navigation`](modules#$app-navigation).
422
422
423
-
## Promise unwrapping
423
+
## Streaming with promises
424
424
425
-
Top-level promises will be awaited, which makes it easy to return multiple promises without creating a waterfall:
425
+
Promises at the _top level_ of the returned object will be awaited, making it easy to return multiple promises without creating a waterfall. When using a server `load`, _nested_ promises will be streamed to the browser as they resolve. This is useful if you have slow, non-essential data, since you can start rendering the page before all the data is available:
426
426
427
427
```js
428
-
/// file: src/routes/+page.js
429
-
/**@type{import('./$types').PageLoad}*/
428
+
/// file: src/routes/+page.server.js
429
+
/**@type{import('./$types').PageServerLoad}*/
430
430
exportfunctionload() {
431
431
return {
432
-
a:Promise.resolve('a'),
433
-
b:Promise.resolve('b'),
434
-
c: {
435
-
value:Promise.resolve('c')
432
+
one:Promise.resolve(1),
433
+
two:Promise.resolve(2),
434
+
streamed: {
435
+
three:newPromise((fulfil) => {
436
+
setTimeout(() => {
437
+
fulfil(3)
438
+
}, 1000);
439
+
})
436
440
}
437
441
};
438
442
}
439
443
```
440
444
445
+
This is useful for creating skeleton loading states, for example:
446
+
441
447
```svelte
442
448
/// file: src/routes/+page.svelte
443
449
<script>
444
450
/** @type {import('./$types').PageData} */
445
451
export let data;
446
-
447
-
console.log(data.a); // 'a'
448
-
console.log(data.b); // 'b'
449
-
console.log(data.c.value); // `Promise {...}`
450
452
</script>
453
+
454
+
<p>
455
+
one: {data.one}
456
+
</p>
457
+
<p>
458
+
two: {data.two}
459
+
</p>
460
+
<p>
461
+
three:
462
+
{#await data.streamed.three}
463
+
Loading...
464
+
{:then value}
465
+
{value}
466
+
{:catch error}
467
+
{error.message}
468
+
{/await}
469
+
</p>
451
470
```
452
471
472
+
On platforms that do not support streaming, such as AWS Lambda, responses will be buffered. This means the page will only render once all promises resolve.
473
+
474
+
> Streaming data will only work when JavaScript is enabled. You should avoid returning nested promises from a universal `load` function if the page is server rendered, as these are _not_ streamed — instead, the promise is recreated when the function re-runs in the browser.
475
+
453
476
## Parallel loading
454
477
455
478
When rendering (or navigating to) a page, SvelteKit runs all `load` functions concurrently, avoiding a waterfall of requests. During client-side navigation, the result of calling multiple server `load` functions are grouped into a single response. Once all `load` functions have returned, the page is rendered.
@@ -502,6 +525,8 @@ export async function load() {
502
525
503
526
A `load` function that calls `await parent()` will also re-run if a parent `load` function is re-run.
504
527
528
+
Dependency tracking does not apply _after_ the `load` function has returned — for example, accessing `params.x` inside a nested [promise](#streaming-with-promises) will not cause the function to re-run when `params.x` changes. (Don't worry, you'll get a warning in development if you accidentally do this.) Instead, access the parameter in the main body of your `load` function.
529
+
505
530
### Manual invalidation
506
531
507
532
You can also re-run `load` functions that apply to the current page using [`invalidate(url)`](modules#$app-navigation-invalidate), which re-runs all `load` functions that depend on `url`, and [`invalidateAll()`](modules#$app-navigation-invalidateall), which re-runs every `load` function.
`Placing %sveltekit.body% directly inside <body> is not recommended, as your app may break for users who have certain browser extensions installed.\n\nConsider wrapping it in an element:\n\n<div style="display: contents">\n %sveltekit.body%\n</div>`
0 commit comments