Svelte journey | SvelteKit: Page options, Link Options, Environment variables

chillyhill

Denys Sych

Posted on January 13, 2024

Svelte journey | SvelteKit: Page options, Link Options, Environment variables

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.

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 the window 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 in src/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>
    
    
  • csr — to disable client-side rendering (no JS is served to the client);

    • Same story as with ssr and not server suffixed files;
  • 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 in src/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 as always/index.html whereas a URL like /never will be saved as never.html.

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>

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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 for data-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');

Enter fullscreen mode Exit fullscreen mode

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 be rel="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 with server.js;
    • Any files inside src/lib/server;

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 of static one;
  • Dynamic variables are accessible via env object:
import { env } from '$env/dynamic/private';
// env.API_TOKEN

Enter fullscreen mode Exit fullscreen mode

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';

Enter fullscreen mode Exit fullscreen mode

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

💖 💪 🙅 🚩
chillyhill
Denys Sych

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