why not just pass the props resulting from the SSR to the client?
In order to do this, the props need to be serializable. You couldn't — for example — do something like this:
<script context="module">
export async function load({ fetch }) {
const data = await fetch('/data.json').then(r => r.json());
const model = create_model(data);
return {
props: { model }
};
}
</script>
<script>
export let model;
</script>
<h1>{$model.title}</h1>
Or you might need to dynamically import one component in one case, and a different component in another case, and pass that through as a prop.
There's another disadvantage to serializing the load
output (which is what happened with SvelteKit's predecessor, Sapper) — in some cases, you might end up serializing a lot more data than you need to:
<script context="module">
export async function load({ fetch }) {
const compressed = await fetch('/compressed-data.json').then(r => r.json());
const data = decompress(compressed);
return {
props: { data }
};
}
</script>
So SvelteKit runs load
on both server and client. But it doesn't mean you're making unnecessary network requests. Anything you fetch
in your load
function is baked into the server-rendered HTML, meaning a) everything is contained in one request, b) the data used for server and client renders is guaranteed to be consistent, and c) any strings that appear in the fetched data and also appear in the markup are essentially 'free' because of gzip (or brotli).
What if a database request needs to be done during SSR?
You shouldn't be talking directly to the database in load
, you should be creating an endpoint and requesting data with fetch
. (We may add a method for auto-generating these endpoints in future, but it's not currently on the roadmap.)