patternjavascriptsvelteModerate
SvelteKit layout data inheritance and typed $page store
Viewed 0 times
SvelteKit 1.x+
layout datapage store$pageparent()data inheritancesveltekit types$types
Error Messages
Problem
Data loaded in a layout's load function is not accessible in child pages, or the $page store is used without TypeScript types, causing property access errors.
Solution
Layout load data is automatically merged and accessible in all child pages:
// src/routes/+layout.server.ts
export async function load({ locals }) {
// This data is available to ALL child pages
return {
session: locals.session,
notifications: await getNotifications(locals.user?.id)
};
}
// src/routes/dashboard/+page.server.ts
export async function load({ parent }) {
// Access layout data via parent()
const { session } = await parent();
if (!session) throw redirect(303, '/login');
const stats = await getDashboardStats(session.userId);
return { stats };
}
// src/routes/dashboard/+page.svelte
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
// Option 1: data prop (recommended)
export let data: PageData;
const { stats } = data;
// Option 2: $page store (for accessing from anywhere)
$: ({ session } = $page.data); // includes layout data too
</script>
// src/routes/+layout.server.ts
export async function load({ locals }) {
// This data is available to ALL child pages
return {
session: locals.session,
notifications: await getNotifications(locals.user?.id)
};
}
// src/routes/dashboard/+page.server.ts
export async function load({ parent }) {
// Access layout data via parent()
const { session } = await parent();
if (!session) throw redirect(303, '/login');
const stats = await getDashboardStats(session.userId);
return { stats };
}
// src/routes/dashboard/+page.svelte
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
// Option 1: data prop (recommended)
export let data: PageData;
const { stats } = data;
// Option 2: $page store (for accessing from anywhere)
$: ({ session } = $page.data); // includes layout data too
</script>
Why
SvelteKit merges layout load data and page load data into a single data object available as the data prop. $page.data reflects this merged object and is reactive. The $types module provides auto-generated TypeScript types for each route's data shape.
Gotchas
- Call await parent() in page load to access layout data — forgetting this causes missing layout data
- Layout data is cached and does not re-run on client-side navigation within the same layout unless invalidated
- Use invalidate('app:session') or invalidateAll() to force a layout load refresh
- $page.data types are inferred automatically — import PageData from './$types' for explicit typing
Code Snippets
Invalidating SvelteKit layout data after a mutation
// Force refresh of layout data
import { invalidate, invalidateAll } from '$app/navigation';
// Invalidate specific load dependency
await invalidate('app:session');
// Invalidate everything and re-run all load functions
await invalidateAll();Context
When accessing layout-level data in child pages and components in SvelteKit
Revisions (0)
No revisions yet.