A Beginner’s Guide to SvelteKit – SitePoint

SvelteKit is an officially supported framework, built around Svelte. It adds key features to a Svelte app — such as routing, layouts and server-side rendering — and makes front-end development outrageously simple.
In this tutorial, we’ll take a beginner-friendly look at both Svelte and SvelteKit and build out a simple web app showing profile pages of imaginary users. Along the way, we’ll look at all the main features that SvelteKit has to offer.
Let’s start by looking at what Svelte brings to the table.
The Benefits of Working with Svelte
Svelte is growing in popularity, and that’s for a good reason. Developing apps with Svelte is based on writing reusable and self-contained components — similar to other popular JavaScript frameworks such as React.
The big difference comes with its build-time compilation — as opposed to a run-time interpretation of the code. In other words, Svelte already compiles your code during the build process and the final bundle only contains JavaScript that your application actually needs. This results in fast web apps with small bundle sizes.
Other frameworks only parse and bundle up the code you’ve written, essentially taking the component tree as is and shipping it to the client. In order for the browser to be able to interpret it and update the UI, a lot more code needs to be delivered and additional work is done on the client side. (You can read here how React handles this process under the hood.)
Other than that, Svelte is an ideal framework for beginners. Everyone who knows how to write HTML and how to include

Note: if you want to have syntax highlighting for Svelte files, there are extensions you can install. This one is good for VS Code.
In this example, we used the element to define meta tags that will be inserted in the of our document. Since we did this in the layout component, it will be applied to the entire app. The robot tag is just an example.
Furthermore, we created a navbar. This is a typical use case for the layout component, as it’s usually intended to be shown on every page of your application.
The navbar has two links: one to the root of the application — which already has content served by the /src/routes/index.svelte component — and one to the about page. The about page was also created by the demo app. Open it and replace its content with the following:

ABOUT


A website to find user profiles

This page is pretty basic. We included some HTML and applied some styling.
Let’s go back to the browser and navigate to the new page. Our modifications should already be visible and you should see something like this:

Let’s navigate between the landing page and the about page. You might realize that changing the page doesn’t refresh the entire application. The navigation feels smooth and instant. This is because SvelteKit applies Client-Side Routing out of the box. Although we used normal tags in our navbar, SvelteKit identifies those as internal links and intercepts them using its built-in client router.
Static Pages and Prerendering
As I described above, SvelteKit uses the concept of adapters to build apps for different environments. Adapters are imported in the svelte.config.cjs file.
When you open this configuration file, you can see that our application currently uses the node adapter. This will optimize the build output for a Node environment and, by default, every page of our application will be rendered upon request by a Node server. However, this seems a little bit too much, considering the current state of our app. Also, you might not want to run a server for your application.
As our app doesn’t currently depend on any dynamic data, it could consist entirely of static files. And there’s an adapter-static that you can install, which turns SvelteKit into a static site generator. It would render your entire app into a collection of static files during the build process. However, this would prevent us from creating additional pages that depend on server-side rendering.
As we don’t want to turn all our pages into static files, we’ll make use of another SvelteKit feature which enables us to prerender individual files of our application. In our case, we’d like the about page to be prerendered, since it consists of static content and rendering the page on every request would be unnecessary. We can achieve this by adding the following code snippet at the top of our /src/routes/about.svelte page:

We can test this out by running npm run build. This will generate a functioning Node server inside the /build folder. As you can see, there’s an HTML file /build/prerendered/about/index.html containing the prerendered HTML for the about page. There’s no HTML file for our landing page since it will be rendered by the Node server upon request.
You can run the generated Node server with node build/index.js.
Endpoints
Now it’s time to fill our page with some dynamic content. We’ll adjust the landing page such that it shows a list of user avatars. To do so, we need to fetch a list of user information from an API endpoint. Most developing teams have a separate back end. That would be the place to go. However, SvelteKit makes it easy to turn your application full stack using endpoint pages. Since we have no back end, we’ll create such a page.
Instead of using a real database, we’ll generate some mock user data. To do so, we’ll use the library faker. Let’s install it with npm install -D faker.
Now, create a file /src/routes/api/index.js in a new /api folder. Since the file has no .svelte extension, it will be treated as an endpoint. The syntax /api/index.js is the same as api.js. The endpoint will become available under /api. Insert the following code:
import faker from "faker";

const generateUsers = () =>
[...Array(50)].map(() => {
const lastName = faker.name.lastName();
return {
avatar: `https://avatars.dicebear.com/api/human/${lastName}.svg`,
lastName,
};
});

export async function get() {
return {
body: generateUsers(),
};
}

This file exports a function get. As you might already have guessed, it corresponds to the HTTP method GET. All it does is return an object with property body that holds an array of user data created with generateUsers.
The function generateUsers returns an array of 50 objects with properties lastName and avatar. lastName is generated using faker. avatar stores a URL that points to the free DiceBear Avatar API. It generates random avatars using a seed value, which is in our case lastName.
If we had a real database, we could replace generateUsers with something like findUsers and access the database inside this function.
That’s all it needs. Go back to the browser (make sure your app is still running in dev mode npm run dev) and navigate to http://localhost:3000/api. This will load the raw data. Note that creating an endpoint like we did is only necessary if you don’t have a separate back-end API to fetch data.
Fetching Data with the load Function
Next, we’ll use the new endpoint to display user data on our landing page. Open the existing /src/routes/index.svelte page and replace its content with the following:


{#each users as { avatar, lastName }}

{lastName}

{lastName}


{/each}

The key challenge to fetching data for dynamic content on a page is that there are two ways a user can navigate to it. The first way is from external sources or after a page refresh. This would cause the application to be loaded from scratch and the page to be served by the server. The second way is from internal navigation, in which case the page would be served by the JavaScript bundle on the client side. In the former, the data is fetched by the server, while in the latter, it’s fetched by the client.
SvelteKit offers a very elegant solution for this — the load function. The load function can run both on the client and on the server side and in both cases will be executed before the component renders. This is why we have to place it inside a

{user.firstName} {user.lastName}

{user.astName}

  • Title: {user.title}
  • Phone: {user.phone}
  • Email: {user.email}

Note again the dynamic parameter [lastName] in the file name. We can access it using the page property that the load function receives.
Again, we use fetch to access our new endpoint /api/[lastName] and pass the user data as property user to the Svelte component. We access this property with export let user and visualize the data with some basic Svelte syntax.
Now you should be able to navigate back to the landing page and click on any user box. This will open the corresponding user page. You should see something like this:

Prefetching
There’s one last feature that I’d like to show, and I am really excited about it. SvelteKit offers the possibility to prefetch data for individual pages.
Let’s go back to our /src/routes/index.svelte page and add the attribute sveltekit:prefetch to the tag. Like so:

This tells SvelteKit to execute the load function of the corresponding page upon hovering the element.
Try it out by opening the network tab in your browser (see below). Every time you hover over one of the user boxes, a request to /api/[lastName] is made and the data for the corresponding user page is fetched. This saves additional milliseconds and ensures a better user experience.

By the way, this is also a great way to see how SvelteKit applies code splitting out of the box. Reload the page and clear the Network log. Note that the very first time you hover over an avatar, one JavaScript and one CSS file is being loaded. This is the code chunk corresponding to our /src/routes/[lastName].svelte page. It gets loaded only once per page session. If you hover over another avatar, only the corresponding data gets loaded, but not again the JavaScript and CSS.
You don’t have to necessarily apply the prefetching attribute to the
tag. If you prefer, you can do the prefetching programmatically using the prefetch function of SvelteKit’s $app/navigation module.
Conclusion
Working with SvelteKit feels very intuitive. All in all, it took me only about an hour to learn all the main features and the results are absolutely astonishing. You get blazing-fast, SEO-optimized web apps that provide you the best user experience that modern build tools can possibly deliver.
By default, SvelteKit renders your page on the server. On the client it gets progressively enhanced by a highly optimized JavaScript bundle to enable client-side routing. With a few lines of code you can prerender individual pages or prefetch data to enable instant page load and navigation. Features like code splitting ensure that Svelte’s advantage of small compilation output doesn’t get mitigated by large app-wide bundles.
Last but not least, SvelteKit gives you complete freedom with respect to all its features. There’s always a way to exclude a feature if you prefer to.
SvelteKit together with Svelte itself is a real game changer to me. And I believe it could be so for many others.

Coded at

Share your love

Leave a Reply