Skip to main content
In SvelteKit, regular <a> elements are used to navigate between routes. You can customize their behavior with data-sveltekit-* attributes to make your app feel faster.

Overview

SvelteKit intercepts clicks on <a> elements whose href is owned by your app and handles navigation without a full page reload. You can customize this with data attributes.
These options also apply to <form> elements with method="GET".

data-sveltekit-preload-data

Before the browser registers a click, SvelteKit can detect hovers and touch events to get a head start on importing code and fetching data.

hover

Preloading starts when mouse hovers over link. On mobile, begins on touchstart.

tap

Preloading starts on touchstart or mousedown event.

Default configuration

The default template applies hover preloading to all links:
src/app.html
<body data-sveltekit-preload-data="hover">
	<div style="display: contents">%sveltekit.body%</div>
</body>

Custom preloading

<a data-sveltekit-preload-data="tap" href="/stonks">
	Get current stonk values
</a>
You can also programmatically invoke preloadData from $app/navigation:
import { preloadData } from '$app/navigation';

preloadData('/about');
Data will never be preloaded if the user has enabled reduced data usage (navigator.connection.saveData === true).

data-sveltekit-preload-code

Preload just the code for a route without fetching data.
1

eager

Links are preloaded immediately
2

viewport

Links are preloaded when they enter the viewport
3

hover

Code is preloaded on hover (data is not)
4

tap

Code is preloaded on tap/mousedown (data is not)
<a data-sveltekit-preload-code="viewport" href="/about">
	About
</a>
viewport and eager only apply to links present in the DOM immediately after navigation. Links added later (in {#if ...} blocks) won’t preload until triggered by hover or tap.

data-sveltekit-reload

Force a full-page navigation instead of client-side routing:
<a data-sveltekit-reload href="/path">Path</a>
  • Loading resources that SvelteKit shouldn’t handle
  • Integrating with legacy server-rendered pages
  • Forcing a complete page refresh
Links with rel="external" receive the same treatment and are ignored during prerendering.

data-sveltekit-replacestate

Replace the current history entry instead of creating a new one:
<a data-sveltekit-replacestate href="/path">Path</a>
Useful for modal dialogs or multi-step forms where you don’t want each step in the browser history.

data-sveltekit-keepfocus

Keep focus on the current element after navigation:
<form data-sveltekit-keepfocus>
	<input type="text" name="query">
</form>
Use sparingly and only on elements that still exist after navigation:
  • Avoid on <a> tags (focus would be on the link, not previous element)
  • Only use if the element persists after navigation
  • Consider accessibility implications for screen readers

data-sveltekit-noscroll

Prevent scrolling to the top after navigation:
<a href="path" data-sveltekit-noscroll>Path</a>
By default, SvelteKit:
  • Scrolls to 0,0 (top-left) after navigation
  • Scrolls to element with matching ID if link includes #hash
  • Preserves scroll position on back/forward navigation

Combining options

You can use multiple attributes together:
<a 
	data-sveltekit-preload-code="viewport"
	data-sveltekit-preload-data="tap"
	data-sveltekit-noscroll
	href="/dashboard"
>
	Dashboard
</a>

Inheritance and overriding

Attributes can be applied to parent elements and overridden on children:
<nav data-sveltekit-preload-data="hover">
	<!-- These links preload on hover -->
	<a href="/a">A</a>
	<a href="/b">B</a>
	
	<!-- This link doesn't preload -->
	<a data-sveltekit-preload-data="false" href="/c">C</a>
	
	<!-- This section uses tap preloading -->
	<div data-sveltekit-preload-data="tap">
		<a href="/d">D</a>
	</div>
</nav>

Conditional attributes

Apply attributes conditionally in Svelte:
<script>
	let shouldPreload = $state(true);
</script>

<div data-sveltekit-preload-data={shouldPreload ? 'hover' : false}>
	<!-- Links here conditionally preload -->
</div>

Performance considerations

Pros: Faster perceived navigation (200-300ms head start)Cons: Can cause unnecessary requests if users don’t clickBest for: Most content pages with stable data
Pros: Only loads when user shows clear intentCons: Slightly less head start (only 50-100ms)Best for: Pages with rapidly changing data or expensive queries
Pros: Minimal bandwidth, code is cacheableCons: Still need to fetch data on navigationBest for: Pages where data must be fresh
Pros: No wasted requestsCons: Slower navigationBest for: Auth-protected routes or rate-limited APIs

Programmatic preloading

Preload routes in your JavaScript code:
import { preloadData } from '$app/navigation';

// Preload when showing a tooltip
function showTooltip() {
	preloadData('/user/profile');
}

API Reference

View the complete $app/navigation API