В SvelteKit элементы <a>
(а не специфические для фреймворка компоненты <Link>
) используются для навигации между маршрутами вашего приложения. Если пользователь нажимает на ссылку, href
которая "принадлежит" приложению (в отличие, например, от ссылки на внешний сайт), SvelteKit переходит на новую страницу, импортируя ее код и вызывая все функции load
, необходимые для получения данных.
Вы можете настроить поведение ссылок с помощью атрибутов data-sveltekit-*
. Они могут быть применены к самому элементу <a>
или к родительскому элементу.
Эти опции также применяются к элементам <form>
с method="GET"
.
Before the browser registers that the user has clicked on a link, we can detect that they've hovered the mouse over it (on desktop) or that a touchstart
or mousedown
event was triggered. In both cases, we can make an educated guess that a click
event is coming.
SvelteKit can use this information to get a head start on importing the code and fetching the page's data, which can give us an extra couple of hundred milliseconds — the difference between a user interface that feels laggy and one that feels snappy.
We can control this behaviour with the data-sveltekit-preload-data
attribute, which can have one of two values:
"hover"
means that preloading will start if the mouse comes to a rest over a link. On mobile, preloading begins ontouchstart
"tap"
means that preloading will start as soon as atouchstart
ormousedown
event is registered
The default project template has a data-sveltekit-preload-data="hover"
attribute applied to the <body>
element in src/app.html
, meaning that every link is preloaded on hover by default:
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
Sometimes, calling load
when the user hovers over a link might be undesirable, either because it's likely to result in false positives (a click needn't follow a hover) or because data is updating very quickly and a delay could mean staleness.
In these cases, you can specify the "tap"
value, which causes SvelteKit to call load
only when the user taps or clicks on a link:
<a data-sveltekit-preload-data="tap" href="/stonks">
Get current stonk values
</a>
You can also programmatically invoke
preloadData
from$app/navigation
.
Data will never be preloaded if the user has chosen reduced data usage, meaning navigator.connection.saveData
is true
.
Even in cases where you don't want to preload data for a link, it can be beneficial to preload the code. The data-sveltekit-preload-code
attribute works similarly to data-sveltekit-preload-data
, except that it can take one of four values, in decreasing 'eagerness':
"eager"
means that links will be preloaded straight away"viewport"
means that links will be preloaded once they enter the viewport"hover"
- as above, except that only code is preloaded"tap"
- as above, except that only code is preloaded
Note that viewport
and eager
only apply to links that are present in the DOM immediately following navigation — if a link is added later (in an {#if ...}
block, for example) it will not be preloaded until triggered by hover
or tap
. This is to avoid performance pitfalls resulting from aggressively observing the DOM for changes.
Since preloading code is a prerequisite for preloading data, this attribute will only have an effect if it specifies a more eager value than any
data-sveltekit-preload-data
attribute that is present.
As with data-sveltekit-preload-data
, this attribute will be ignored if the user has chosen reduced data usage.
Occasionally, we need to tell SvelteKit not to handle a link, but allow the browser to handle it. Adding a data-sveltekit-reload
attribute to a link...
<a data-sveltekit-reload href="/path">Path</a>
...will cause a full-page navigation when the link is clicked.
Links with a rel="external"
attribute will receive the same treatment. In addition, they will be ignored during prerendering.
Sometimes you don't want navigation to create a new entry in the browser's session history. Adding a data-sveltekit-replacestate
attribute to a link...
<a data-sveltekit-replacestate href="/path">Path</a>
...will replace the current history
entry rather than creating a new one with pushState
when the link is clicked.
Sometimes you don't want focus to be reset after navigation. For example, maybe you have a search form that submits as the user is typing, and you want to keep focus on the text input. Adding a data-sveltekit-keepfocus
attribute to it...
<form data-sveltekit-keepfocus>
<input type="text" name="query">
</form>
...will cause the currently focused element to retain focus after navigation. In general, avoid using this attribute on links, since the focused element would be the <a>
tag (and not a previously focused element) and screen reader and other assistive technology users often expect focus to be moved after a navigation. You should also only use this attribute on elements that still exist after navigation. If the element no longer exists, the user's focus will be lost, making for a confusing experience for assistive technology users.
When navigating to internal links, SvelteKit mirrors the browser's default navigation behaviour: it will change the scroll position to 0,0 so that the user is at the very top left of the page (unless the link includes a #hash
, in which case it will scroll to the element with a matching ID).
In certain cases, you may wish to disable this behaviour. Adding a data-sveltekit-noscroll
attribute to a link...
<a href="path" data-sveltekit-noscroll>Path</a>
...will prevent scrolling after the link is clicked.
To disable any of these options inside an element where they have been enabled, use the "off"
value:
<div data-sveltekit-preload-data>
<!-- these links will be preloaded -->
<a href="/a">a</a>
<a href="/b">b</a>
<a href="/c">c</a>
<div data-sveltekit-preload-data="off">
<!-- these links will NOT be preloaded -->
<a href="/d">d</a>
<a href="/e">e</a>
<a href="/f">f</a>
</div>
</div>
To apply an attribute to an element conditionally, do this:
<div data-sveltekit-reload={shouldReload ? '' : 'off'}>
This works because in HTML,
<element attribute>
is equivalent to<element attribute="">