SvelteKit¶
SvelteKit allows static site building, server-rendered sites, and even hybrid static-and-server-rendered web apps. It also has extremely fast hot reloading in development mode because of the way it bundles JavaScript. It adds key features like routing, layouts, and state management to Svelte.
By default, SvelteKit will render any component first on the server and send it to the client as HTML. It will then render the component again in the browser to make it interactive in a process called hydration. For this reason, you need to ensure that components can run in both places. SvelteKit will then initialize a router that takes over subsequent navigation.
Directory Structure¶
This is the default structure extended by best practice of myself:
static # static content like icons
src # source code
lib # reusable library files
components # components to build pages
stores # data stores
routes # pages and api code
theme # light and dark themes
docs # documentation in markdown
site # generated html documentation
node_modules # libraries
build # generated site
Routing¶
This is defined by the file system structure under src/routes
. Two types of routes are possible here:
- Pages - which are
*.svelte
files which render HTML on the server or client. - Data - which are
*.js
or*.ts
files which mostly return JSON data for the pages.
The routes can be files or index of directory:
/about
->src/routes/about.svelte
/about
->src/routes/about/index.svelte
Dynamic parameters are encoded using [brackets]
. For example, a blog post might be defined by src/routes/blog/[slug].svelte
. A file or directory also can have multiple dynamic parts, like [id]-[category].svelte
. (Parameters are 'non-greedy'; in an ambiguous case like x-y-z
, id would be x
and category would be y-z
.)
Files starting with _
are hidden from the router, but can be imported by other files.
If multiple paths are matching the most specific one will be tried first, then data endpoints and then pages. The first which returns something will handle the request.
Pages¶
This consist of svelte templates.
Data Endpoints¶
Also called endpoints, will return a { status, headers, body }
object representing the response, where status
is an HTTP status code:
- 2xx — successful response (default is 200)
- 3xx — redirection (should be accompanied by a location header)
- 4xx — client error
- 5xx — server error
Layouts¶
A special page file is a layout which is called src/routes/__layout.svelte
because it will automatically be used for the general layout of the pages within this directory and below. Layout will inherit from the above but you can use __layout.reset.svelte
to prevent this.
Errors¶
If a page fails to load an __error.svelte
file will be called in the specific layout.
Hooks¶
The file src/hooks.ts
exports four functions, that run on the server:
handle
- runs every time SvelteKit receives a request — whether that happens while the app is running, or during prerendering — and determines theresponse
. It receives the request object and a function calledresolve
, which invokes SvelteKit's router and generates a response accordingly. This allows you to modify response headers or bodies, or bypass SvelteKit entirely.handleError
- if an error is thrown during rendering, this function will be called with the error and the request that caused it. This allows you to send data to an error tracking service, or to customize the formatting before printing the error to the console.getSession
- takes the request object and returns a session object that is accessible on the client and therefore must be safe to expose to users. It runs whenever SvelteKit server-renders a page.externalFetch
- allows you to modify a fetch request for an external resource that happens inside a load function that runs on the server.
Path Alias¶
To make it easier to include files from the main directories you can add specific aliases for them:
import path from 'path';
const config = {
kit: {
...
vite: {
resolve: {
alias: {
$lib: resolve('./src/lib'),
$components: resolve('./src/lib/components'),
$stores: resolve('./src/lib/stores')
}
}
}
}
};
{
"compilerOptions": {
...
"paths": {
"$lib/*": ["src/lib/*"],
"$components/*": ["src/lib/components/*"],
"$stores/*": ["src/lib/stores/*"]
}
},
...
}
By default only $lib
as alias to src/lib
is defined. but you may shorten your includes further with the other aliases.
Modules¶
$app/env¶
import { amp, browser, dev, mode, prerendering } from "$app/env";
amp
- istrue
orfalse
depending on the corresponding value in your project configurationbrowser
- istrue
orfalse
depending on whether the app is running in the browser or on the serverdev
- istrue
in development mode,false
in productionmode
- is the Vite mode, which is development in dev mode or production during build unless configured otherwise inconfig.kit.vite.mode
.prerendering
- is true when prerendering, false otherwise
$app/navigation¶
import { goto, invalidate, prefetch, prefetchRoutes } from "$app/navigation";
goto(href, { replaceState, noscroll, keepfocus, state })
- returns a Promise that resolves when SvelteKit navigates to the specifiedhref
. The second argument is optional:replaceState
(boolean, defaultfalse
) Iftrue
, will replace the current history entry rather than creating a new one withpushState
noscroll
(boolean, defaultfalse
) Iftrue
, the browser will maintain its scroll position rather than scrolling to the top of the page after navigationkeepfocus
(boolean, defaultfalse
) Iftrue
, the currently focused element will retain focus after navigation. Otherwise, focus will be reset to the bodystate
(object, default{}
) the state of the new/updated history entryinvalidate(href)
- causes any load functions belonging to the currently active page to re-run if they fetch the resource in question. It returns a Promise that resolves when the page is subsequently updated.prefetch(href)
- programmatically prefetches the given page, which means a) ensuring that the code for the page is loaded, and b) calling the page's load function with the appropriate options. This is the same behavior that SvelteKit triggers when the user taps or mouses over an<a>
element withsveltekit:prefetch
. If the next navigation is to href, the values returned from load will be used, making navigation instantaneous. Returns a Promise that resolves when the prefetch is complete.prefetchRoutes(routes)
- programmatically prefetches the code for routes that haven't yet been fetched. Typically, you might call this to speed up subsequent navigation. If no argument is given, all routes will be fetched; otherwise, you can specify routes by any matching pathname such as /about (to match src/routes/about.svelte) or /blog/* (to match src/routes/blog/[slug].svelte). Unlike prefetch, this won't call load for individual pages. Returns a Promise that resolves when the routes have been prefetched.
$app/paths¶
import { base, assets } from "$app/paths";
base
- a root-relative (i.e. begins with a/
) string that matchesconfig.kit.paths.base
, or the empty string if unspecifiedassets
- an absolute URL that matchesconfig.kit.paths.assets
, if specified, otherwise equal to base
If a value for config.kit.paths.assets
is specified, it will be replaced with '/\_svelte_kit_assets'
during svelte-kit dev or svelte-kit preview, since the assets don't yet live at their eventual URL.
$app/stores¶
import { getStores, navigating, page, session } from "$app/stores";
getStores
is a convenience function aroundgetContext
that returns{ navigating, page, session }
. This is needed to get them asynchronously.
The stores themselves attach to the correct context at the point of subscription. Import them at page initialization or use getStores
to safely get them asynchronously instead.
navigating
is a readable store showing current navigation like{ from, to }
, where from and to both mirror the page store value. When navigating finishes, its value reverts tonull
.page
is a readable store whose value reflects the object passed to load functions — it containshost
,path
,params
andquery
of the current page view.session
is a writable store whose initial value is whatever was returned fromgetSession
. It can be written to, but this will not cause changes to persist on the server — this is something you must implement yourself.
Own stores¶
Put them into src/stores
and thanks to the path alias you can directly import them using $stores/xxx
.
Prefetch¶
To speed up UI response you can add prefetch which will cause SvelteKit to run the page's load function as soon as the user hovers over the link (on a desktop) or touches it (on mobile), rather than waiting for the click event to trigger navigation. Typically, this buys us an extra couple of hundred milliseconds, which is the difference between a user interface that feels laggy, and one that feels snappy.
This can be done on a link:
<a sveltekit:prefetch href="blog/page1">First blog page</a>
You can also programmatically invoke prefetch from $app/navigation
.