Under The Hood
frontend svelte SvelteKit 2.x

SvelteKit snapshot: Client-Side Scroll & Input Restoration

Last updated
Prerequisites:
SvelteKit navigation and page lifecycle
Understanding of SPA back-navigation behavior
  • sveltekit
  • snapshot
  • restore
  • scroll
  • form-state
  • navigation

Read at your depth

The practical view

SvelteKit's snapshot feature preserves page state across navigations. In a component (usually +page.svelte or +layout.svelte), export a snapshot object: export const snapshot = { capture: () => ({ query: searchTerm }), restore: (value) => { searchTerm = value; } };. When you navigate away and then back (browser back/forward), the captured value is restored. This is ideal for search inputs, filter states, and scroll positions that should survive back-navigation. SvelteKit also preserves scroll position automatically for simple cases; snapshots extend this to arbitrary component state. The captured value must be JSON-serializable (no functions, no DOM nodes).

The same idea in other frameworks

react equivalent
React Router's <ScrollRestoration> and component state keyed by location cover similar ground.

Legacy vs modern

Lost form state on back vs snapshot restoration

Without snapshots, navigating away and back clears the search input; the snapshot capture/restore pair rebuilds it exactly.

before → after
State lost on back-navigation
let query = $state(''); // ❌ OLD: navigating away and back resets this
snapshot capture/restore
export const snapshot = {
  capture: () => ({ query, results }), // ✅ NEW
  restore: (value) => { query = value.query; results = value.results; }, // ✅ NEW
};

Interview gotchas

Context

This probes the constraints and edge cases — interviewers want to know the serialization limit and the hard-refresh/new-tab behavior, which determines whether snapshots are a safe storage mechanism.

The mechanical answer

Snapshots must be JSON-serializable: plain objects, arrays, strings, numbers, booleans, null, and Date (via the structured-clone-compatible history state). You cannot store functions, class instances, DOM nodes, Maps, or cyclic structures. Because the state lives in the browser's history entry, it is only restored on back/forward navigation within the same tab — a hard refresh (F5), opening the URL in a new tab, or sharing the link does NOT restore snapshots (the history state is gone). For those cases you need URL-driven state or persistence (localStorage/sessionStorage). Also, restore runs only if the component with the snapshot export is still the matching page; structural changes to the tree can orphan saved snapshots.

Trap

The naive answer is 'snapshots survive refresh'. They live in history state and do not survive a full page reload. Another trap: trying to save non-serializable values (functions, DOM refs) — the state must be structured-cloneable and will fail or be stripped. Candidates who describe the history-state scoping and the serialization constraint show real understanding.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.