Lesson 8 of 9 beginner 4 min read

$app/state

Reactive navigation signals (page, navigating, updated) replacing legacy SvelteKit stores.

Interactive Laboratory

Live Runtime

Experiment directly with $app/state concepts in real time

SvelteKit Full-Stack Pipeline
1. Request
Hook
2. Loader
load()
3. Server
SSR HTML
4. Browser
Hydrate

Reactive App State ($app/state)

In SvelteKit 3 and Svelte 5, the legacy $app/stores module ($page, $navigating) is deprecated and replaced by Runes-powered state signals from $app/state.


1. Inspecting Current Route (page)

page is a fine-grained reactive state signal containing URL details, route parameters (page.params), loaded data (page.data), and error status (page.status, page.error):

<!-- src/lib/components/ActiveLink.svelte -->
<script lang="ts">
	import { page } from '$app/state';
 
	let { href, label }: { href: string; label: string } = $props();
 
	// Fine-grained derived reactivity without $ sign prefix!
	let isActive = $derived(page.url.pathname === href);
	let currentUserId = $derived(page.params.userId);
	let currentUser = $derived(page.data.user);
</script>
 
<a {href} class:active={isActive}>
	{label}
</a>

2. Navigation Progress (navigating)

Display global loading spinners or top progress bars when page transitions are in flight:

<!-- src/routes/+layout.svelte -->
<script lang="ts">
	import { navigating } from '$app/state';
 
	let { children } = $props();
</script>
 
{#if navigating.to}
	<div class="fixed top-0 left-0 h-1 w-full animate-pulse bg-primary"></div>
{/if}
 
{@render children()}

3. Detecting Deployed App Updates (updated)

<script lang="ts">
	import { updated } from '$app/state';
</script>
 
{#if updated.current}
	<aside class="update-banner">
		<span>A new version of the app is available!</span>
		<button onclick={() => location.reload()}>Refresh</button>
	</aside>
{/if}