Welcome,
In this article, we will focus on how to fine-tune preloading and prerendering functionalities, as well as effectively manage environment variables in SvelteKit.
If you’ve been following the series from the beginning, congratulations — you've put in great effort, and this marks the final installment of the series! If not, I would strongly recommend taking a glance through the previous articles; you may still find something interesting.
So, let’s get started.
Page Options
This section explores the fine-tuning of preloading, prerendering, and other functionalities in SvelteKit. It details how to export options and discusses specific page options, such as disabling SSR, client-side rendering, and defining trailing slashes.
- Options can be exported from
+page.js
,+page.server.js
,+layout.js
, and+layout.server.js
, but it actually works when exports happen from+<type>.server.js
:- E.g.,
export const ssr = false
; - Page options can be applied for an individual page or layout;
- To apply globally, export options from the root layout;
- More nested definitions override inherited ones.
- E.g.,
We can export the following options:
-
ssr
— to disable SSR;- If you define
export const ssr = false;
in a non-server file, it may not make much sense. When defined in a plain page or layout, it may not be helpful in case of interaction with browser-related API. For example, when you load an app from/
and navigate to/bar
which uses thewindow
object, it would work. But if you then reload the browser tab on/bar
, you get a 500 Error,window
is undefined, and an error would be thrown; -
ssr = false
insrc/routes/+layout.server.js
transforms the entire app into a SPA.
// bar/+page.svelte <script> export const ssr = false; // will really make a difference in +page.server.js. Here it may be useless </script> <h1>{window.innerWidth}x{window.innerHeight}</h1>
- If you define
-
csr
— to disable client-side rendering (no JS is served to the client);- Same story as with
ssr
and notserver
suffixed files;
- Same story as with
-
prerender
— prepare HTML for a page only once, not dynamically for each request (build static HTML on the build step).false
by default;-
ssr = false
insrc/routes/+layout.server.js
transforms the entire app into a SSG; - Can be configured;
-
-
trailingSlash
— we have two URLs:/foo
and/foo/
. We have a relative URL./bar
. For/foo
, it would be/bar
, for/foo/
, it would be/foo/bar
.- By default, SvelteKit strips trailing slashes out, so
/foo/
will result in a redirect to/foo
; -
export const trailingSlash = 'always' | 'ignore' | 'never'
— never is by default, better leave as is; - Trailing slashes are applied affects pre-rendering. A URL like
/always/
will be saved to disk asalways/index.html
whereas a URL like/never
will be saved asnever.html
.
- By default, SvelteKit strips trailing slashes out, so
Link (Route) Options
Delving into the tuning of page loading accessible by links, this section covers various attributes for preloading tuning.
- Implemented as attributes;
- Cascade application (if applied on some parent → will be applied for all anchor children;
- To prevent cascade behavior, you can set the attribute to false in a required place, e.g.:
<div data-sveltekit-preload-data>
<a href="/a">a</a>
<div data-sveltekit-preload-data="false">
<a href="/b">b</a>
</div>
</div>
Preloading
“Anticipate” that the link would be used → starts to fetch the resource behind the link when the anchor is hovered (or tapped on mobile). Need to add data-sveltekit-preload-data
attribute.
- Attribute’s values can have values:
"hover"
(default) |"tap"
(default for mobile) |"off"
; - Can be placed on
<a />
or any element whose has<a />
as a child; -
<body data-sveltekit-preload-data>
is by default in the generated project;
<nav>
<a href="/">home</a>
<a href="/chart" data-sveltekit-preload-data>Chart</a>
</nav>
Alternative attribute: data-sveltekit-preload-code
— preloads code for the route without loading its data. Possible values:
-
"eager"
— preload everything on the page following navigation; -
"viewport"
— preload everything as it appears in the viewport; -
"hover" | "tap" | "off"
— same as fordata-sveltekit-preload-data
.
Programmatic Preload
The same purpose but can be done in pages and layouts:
import { preloadCode, preloadData } from '$app/navigation';
preloadData('/foo');
preloadCode('/bar');
Other Options
-
data-sveltekit-noscroll
— do not scroll to the top on navigation; -
data-sveltekit-keepfocus
— do not reset focus on navigation; -
data-sveltekit-replacestate
— replace the browser’s history instead of pushing one more step; -
data-sveltekit-reload
— full-page reload (or it can berel="external”
attribute on an anchor)
Environment Variables Access — $env
Module
Variables should be defined in a .env
file, in the root folder.
Private Variables
-
.env.[mode]
files are also supported according to Vite documentation; - In an app, variables are accessible via
$env/static/private
; - Variables from
process.env
are also available from$env/static/private
; - Env. variables only accessible in server modules:
- Any
+page.server.js | +layout.server.js | +server.js,
any files ending withserver.js
; - Any files inside
src/lib/server
;
- Any
Static vs Dynamic
Previously mentioned $env/static/private
— these variables are known at a build time — it helps Svelte to optimize the code, so static
are more preferable.
- Dynamic ones are not known until the app is running. It means no optimizations from Svelte’s side;
- From the dev’s perspective, you just need to use
$env/dynamic/private
import instead ofstatic
one; - Dynamic variables are accessible via
env
object:
import { env } from '$env/dynamic/private';
// env.API_TOKEN
Public Variables
The variables that can be safely exposed to the client side.
- Their naming must start from
PUBLIC_
prefix, e.g.,PUBLIC_MAPBOX_KEY
; - Import them through
$env/static/public
or$env/dynamic/public
:
import { PUBLIC_MAPBOX_KEY } from '$env/static/public';
import { env } from '$env/dynamic/public';
Final words
We've concluded our journey through this impressive toolkit crafted by the Svelte team, known for its exceptional developer experience and user-centric design. While we've covered substantial ground, there's still a wealth of features to discover. I trust this exploration has sparked your interest to delve deeper into the possibilities it offers.
It's a well-designed tool that should bring joy to both creators and consumers — a goal definitely achieved by the Svelte team.
If you want to join the community, there is a Discord server at svelte.dev/chat and Reddit's r/sveltejs.
I hope you've enjoyed this Svelte journey and have gained a general understanding of what the Svelte toolkit is all about.
Take care, go Svelte.
Top comments (0)