Learn

SvelteKit Tutorial

SvelteKit Tutorial

SvelteKit is a framework for rapidly developing robust, performant web applications using Svelte.


Introduction to SvelteKit

SvelteKit is a high-performance web application framework, designed around the core of Svelte. The primary goal of SvelteKit is to provide a streamlined environment for developers to rapidly create robust web applications. If you’re familiar with the React or Vue ecosystems, SvelteKit plays a role akin to Next.js or Nuxt respectively. It offers a wide range of features and functionalities that extend beyond what Svelte alone can provide.

While Svelte excels at writing user interface components, SvelteKit takes this a step further by addressing the complexities associated with constructing a complete web application.

SvelteKit Features

Get Started with SvelteKit

Use npm to create a new SvelteKit application

npm create svelte@latest my-app
cd my-app
npm install
npm run dev

This command scaffolds a new project in the my-app directory with optional basic tooling like TypeScript (make sure to choose your desired stack), installs dependencies, and starts a server on localhost:5173.

The basics:
- Each page in your application is a Svelte component. - You create pages by adding files to the src/routes directory. These files are server-rendered initially for faster page loads, and a client-side app takes over subsequently. - Server-side rendering may not be compatible with libraries that use window or other browser-specific APIs. Use client-side rendering or dynamic imports for these libraries. - Ensure your editor has a Svelte extension for proper syntax highlighting and error reporting.

SvelteKit Project Structure

The SvelteKit project structure is familiar if you’ve worked with modern front-end frameworks like Next.js or Nuxt.js, with a few unique concepts to grasp.

Typical Project Structure

A standard SvelteKit project contains the following structure:

my-project/
├ src/
│ ├ lib/
│ │ ├ server/
│ │ │ └ [your server-only lib files]
│ │ └ [your lib files]
│ ├ params/
│ │ └ [your param matchers]
│ ├ routes/
│ │ └ [your routes]
│ ├ app.html
│ ├ error.html
│ ├ hooks.client.js
│ └ hooks.server.js
├ static/
│ └ [your static assets]
├ tests/
│ └ [your tests]
├ package.json
├ svelte.config.js
├ tsconfig.json
└ vite.config.js

Key Files and Directories

Special Features SvelteKit introduces new concepts, which aren’t common in other frameworks:

Gotchas:

SvelteKit and Web APIs

SvelteKit takes advantage of several standard Web APIs, making it easier for developers familiar with modern web development to use SvelteKit. Time spent learning SvelteKit will also enhance your web development skills.

The Web APIs used by SvelteKit are supported in all modern browsers and in many non-browser environments like Cloudflare Workers, Deno, and Vercel Edge Functions. They’re also polyfilled where necessary during development and in adapters for Node-based environments.

Here are some key Web APIs that SvelteKit makes use of:

1. Fetch API

2. FormData API

The FormData API is used when dealing with HTML native form submissions, creating FormData objects.

3. Stream APIs

SvelteKit uses streams when you need to return a response that’s too large to fit in memory in one go or is delivered in chunks. This includes ReadableStream, WritableStream, and TransformStream.

4. URL APIs

URLs are represented by the URL interface, which shows up in several places, including event.url in hooks and server routes, $page.url in pages, from and to in beforeNavigate and afterNavigate.

5. Web Crypto API

The Web Crypto API is used for tasks like generating UUIDs. It’s available via the crypto global.

Gotchas:


Core Concepts

Routing

Svelte’s Routing system is based on the structure of your codebase, specifically the directories, forming a filesystem-based router. The root route is designated by the directory src/routes, and you can create additional routes by adding more directories, like src/routes/about for an /about route.

Svelte uses a special system for its routes, called route files, recognizable by a + prefix. Each route directory contains one or more of these files.

A +page.svelte file represents a page in your app. Pages are server-rendered by default for the initial request and browser-rendered for subsequent navigation. These components can include any HTML structure and interactive components.

To load data before rendering, +page.js files are used, exporting a load function. This function runs on the server during server-side rendering (SSR) and in the browser during client-side rendering (CSR).

There are options to configure the page’s behavior in +page.js such as prerender, SSR, and CSR configurations.

When a load function must only run on the server, for instance when fetching data from a database or accessing private environment variables, +page.js can be renamed to +page.server.js.

Svelte also provides a way to handle errors during the load process by providing an +error.svelte file. This file customizes the error page on a per-route basis.

Moreover, Svelte supports layouts which are elements visible on every page, like a navigation bar or a footer. These are implemented through +layout.svelte files. Layouts can be nested to accommodate more complex page structures.

+layout.js is the data loading equivalent for layouts, similar to +page.js for pages.

API routes or endpoints are defined using a +server.js file, giving you full control over the response. They correspond to HTTP verbs like GET, POST, PATCH, PUT, DELETE, and OPTIONS and return a Response object.

In summary, Svelte’s Routing system is a dynamic, file-based system where the file and directory structure dictates the routes of your application. The router supports error handling, layouts, and server responses, making it highly flexible for different application needs.

Routing Example src/routes/+page.svelte

<h1>Hello and welcome to my site!</h1>
<a href="/about">About my site</a>

src/routes/about/+page.svelte

<h1>About this site</h1>
<p>TODO...</p>
<a href="/">Home</a>

src/routes/blog/[slug]/+page.svelte

<script>
	/** @type {import('./$types').PageData} */
	export let data;
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>

src/routes/blog/[slug]/+page.js - load data before rendering

import { error } from '@sveltejs/kit';

/** @type {import('./$types').PageLoad} */
export function load({ params }) {
	if (params.slug === 'hello-world') {
		return {
			title: 'Hello world!',
			content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
		};
	}

	throw error(404, 'Not found');
}

+page.server.js - only runs on server

import { error } from '@sveltejs/kit';

/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
    const post = await getPostFromDatabase(params.slug);

    if (post) {
        return post;
    }

    throw error(404, 'Not found');
}

load

form-actions

page-options

state-management


Build and Deploy

building-your-app

adapters

adapter-auto

adapter-node

adapter-static

single-page-apps

adapter-cloudflare

adapter-cloudflare-workers

adapter-netlify

adapter-vercel

writing-adapters


Advanced

advanced-routing

hooks

errors

service-workers

server-only-modules

assets

snapshots

packaging


Best Practices

accessibility

seo


Reference

configuration

cli

modules

types


Appendix

integrations

migrating

additional-resources

glossary


FAQ

other-resources

hmr

read-package-json

packages

integrations