Reputation: 219
It appears to me, that the data set by the return of an outer (for example the global) layout.server.ts
file is accessible in two ways by it's children and nested components:
// outer layout.server.ts
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async () => {
return {
myData: ["foo", "bar"]
}
}
Version 1 through $page.data
:
<script lang="ts">
// version $page.data in +page.svelte
import { page } from '$app/stores';
</script>
{$page.data}
and version 2 through $props()
:
<script lang="ts">
// version $props() in +page.svelte
import type { LayoutData } from './$types';
let data: LayoutData = $props();
</script>
{data}
I am mainly interested in setting session data for the user and make it globally available in the whole application and all it's nested components without passing it from each server file. Just once in the global layout.server.ts
and then every page and component nested inside can reach the passed data.
It appears to me, that on the client side both versions are accessing the same object, that is set on server side, as it's only set once there.
Is there a best practice / good reasons for doing one or the other version on client side? Or would it make sense to define a specific store for the session data (in my example myData: ["foo", "bar"])
to make the code more readable / convenient imports / ...?
I'm only intersted in Svelte5 / SvelteKit2 answers or higher.
Upvotes: 0
Views: 400
Reputation: 8345
Don't know if I'm doing it the best way, but here's what I do:
logged-in-account.js
, in which I export the writeable store loggedInAccount
that contains null
(default)layout.server.ts
file I send back info about the account the user is logged in to+layout.svelte
file I obtain that account (if it exists), and then I immediately put it in the loggedInAccount
store exported from logged-in-account.js
$loggedInAccount
In VS Code, whenever I start writing $l
, VS Code suggests to import loggedInAccount
from the logged-in-account.js
, so it's really convenient to use.
I have wondered if it would be better/more correct to use a context instead of a global store like this, but that suggestion I get from VS Code makes it so easy to use a global store, so I think I would stick to using the global store even if it's a bit incorrect/not optimal (I assume VS Code can't produce equally good suggestions and type safety when using getContext()
).
Upvotes: 1
Reputation: 185280
The page store is passed via context, so it is available in the entire component subtree, it is mainly there for convenience, so data does not need to be sent through props at every level. Since this is a store, it may also be less granular in its updates.
The data
prop is only available in +layout
& +page
files, not regular components since it is passed directly to those by SvelteKit.
I generally prefer using the props where available and only use the store in regular components, especially deeply nested ones.
Upvotes: 1