aknott
aknott

Reputation: 219

Svelte5/SvelteKit2 - $page.data vs let data: LayoutData = $props() in page.svelte?

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

Answers (2)

Peppe L-G
Peppe L-G

Reputation: 8345

Don't know if I'm doing it the best way, but here's what I do:

  1. I have a file named logged-in-account.js, in which I export the writeable store loggedInAccount that contains null (default)
  2. In my root layout.server.ts file I send back info about the account the user is logged in to
  3. In my root +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
  4. In whichever file I need to access the logged in account, I just write $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

brunnerh
brunnerh

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

Related Questions