Svelte journey | SvelteKit: Page options, Link Options, Environment variables
Denys Sych
Posted on January 13, 2024
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.
Resources
Posted on January 13, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
January 13, 2024