From 03f0b7ac606d526097252cf04fe8be40c52e7485 Mon Sep 17 00:00:00 2001 From: Enrico Sacchetti Date: Sat, 23 Dec 2023 21:47:11 -0500 Subject: [PATCH 1/3] docs(load): clarify universal and server load Provide details and examples on how universal and server `load` runs, in what order, and what data gets returned. --- .../docs/20-core-concepts/20-load.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md index 7448cf521c5f..c9c65c2568b6 100644 --- a/documentation/docs/20-core-concepts/20-load.md +++ b/documentation/docs/20-core-concepts/20-load.md @@ -168,6 +168,8 @@ Server `load` functions _always_ run on the server. By default, universal `load` functions run on the server during SSR when the user first visits your page. They will then run again during hydration, reusing any responses from [fetch requests](#making-fetch-requests). All subsequent invocations of universal `load` functions happen in the browser. You can customize the behavior through [page options](page-options). If you disable [server side rendering](page-options#ssr), you'll get an SPA and universal `load` functions _always_ run on the client. +If a route contains both a universal `load` and server `load`, the server `load` will always run first; then the universal `load` runs immediately after. + A `load` function is invoked at runtime, unless you [prerender](page-options#prerender) the page — in that case, it's invoked at build time. ### Input @@ -184,6 +186,35 @@ A universal `load` function can return an object containing any values, includin 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. +When using both a universal and server `load` on the same route, only the data returned in the universal `load` will be returned to the page. You can combine server and universal `load` returned data by spreading the universal `load`'s `data` property: + +```js +/// file: src/routes/+page.server.js +/** @type {import('./$types').PageServerLoad} */ +export async function load({ fetch }) { + const response = await fetch('https://example.com/posts') + const posts = await response.json() + + return { posts } +} +``` + +```js +/// file: src/routes/+page.js +import { browser } from '$app/environment' + +/** @type {import('./$types').PageLoad} */ +export function load({ data }) { + let theme = 'system' + + if (browser) { + theme = localStorage.getItem("theme") ?? 'system'; + } + + return { ...data, theme } // { posts: [/* ... */], theme: 'system' } +} +``` + ### When to use which Server `load` functions are convenient when you need to access data directly from a database or filesystem, or need to use private environment variables. From 58de3b614eb18a415d089b3c8b94a7a53cc15c2b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 8 Jan 2024 16:22:26 -0500 Subject: [PATCH 2/3] Update documentation/docs/20-core-concepts/20-load.md --- documentation/docs/20-core-concepts/20-load.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md index c9c65c2568b6..dbe47016efa4 100644 --- a/documentation/docs/20-core-concepts/20-load.md +++ b/documentation/docs/20-core-concepts/20-load.md @@ -168,7 +168,7 @@ Server `load` functions _always_ run on the server. By default, universal `load` functions run on the server during SSR when the user first visits your page. They will then run again during hydration, reusing any responses from [fetch requests](#making-fetch-requests). All subsequent invocations of universal `load` functions happen in the browser. You can customize the behavior through [page options](page-options). If you disable [server side rendering](page-options#ssr), you'll get an SPA and universal `load` functions _always_ run on the client. -If a route contains both a universal `load` and server `load`, the server `load` will always run first; then the universal `load` runs immediately after. +If a route contains both universal and server `load` functions, the server `load` runs first. A `load` function is invoked at runtime, unless you [prerender](page-options#prerender) the page — in that case, it's invoked at build time. From a0c878363f0bf030f765a579e81e379d64badb9e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 8 Jan 2024 16:22:57 -0500 Subject: [PATCH 3/3] move code sample into "when to use which", simplify --- .../docs/20-core-concepts/20-load.md | 41 ++++++++----------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/documentation/docs/20-core-concepts/20-load.md b/documentation/docs/20-core-concepts/20-load.md index dbe47016efa4..0ce98b176a5b 100644 --- a/documentation/docs/20-core-concepts/20-load.md +++ b/documentation/docs/20-core-concepts/20-load.md @@ -186,43 +186,36 @@ A universal `load` function can return an object containing any values, includin 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. -When using both a universal and server `load` on the same route, only the data returned in the universal `load` will be returned to the page. You can combine server and universal `load` returned data by spreading the universal `load`'s `data` property: +### When to use which + +Server `load` functions are convenient when you need to access data directly from a database or filesystem, or need to use private environment variables. + +Universal `load` functions are useful when you need to `fetch` data from an external API and don't need private credentials, since SvelteKit can get the data directly from the API rather than going via your server. They are also useful when you need to return something that can't be serialized, such as a Svelte component constructor. + +In rare cases, you might need to use both together — for example, you might need to return an instance of a custom class that was initialised with data from your server. When using both, the server `load` return value is _not_ passed directly to the page, but to the universal `load` function (as the `data` property): ```js /// file: src/routes/+page.server.js /** @type {import('./$types').PageServerLoad} */ -export async function load({ fetch }) { - const response = await fetch('https://example.com/posts') - const posts = await response.json() - - return { posts } +export async function load() { + return { + serverMessage: 'hello from server load function' + }; } ``` ```js /// file: src/routes/+page.js -import { browser } from '$app/environment' - +// @errors: 18047 /** @type {import('./$types').PageLoad} */ -export function load({ data }) { - let theme = 'system' - - if (browser) { - theme = localStorage.getItem("theme") ?? 'system'; - } - - return { ...data, theme } // { posts: [/* ... */], theme: 'system' } +export async function load({ data }) { + return { + serverMessage: data.serverMessage, + universalMessage: 'hello from universal load function' + }; } ``` -### When to use which - -Server `load` functions are convenient when you need to access data directly from a database or filesystem, or need to use private environment variables. - -Universal `load` functions are useful when you need to `fetch` data from an external API and don't need private credentials, since SvelteKit can get the data directly from the API rather than going via your server. They are also useful when you need to return something that can't be serialized, such as a Svelte component constructor. - -In rare cases, you might need to use both together — for example, you might need to return an instance of a custom class that was initialised with data from your server. - ## Using URL data Often the `load` function depends on the URL in one way or another. For this, the `load` function provides you with `url`, `route` and `params`.