Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Dynamic routes and parameters

Every blog post has its own address: /blog/hello-svelte, /blog/runes. Creating a folder for each post is impractical. Instead you make a dynamic route: a part of the address in square brackets becomes a parameter, and one page serves all such addresses.

A folder with a parameter

Create the folder src/routes/blog/[slug] — the square brackets are part of the folder name. Inside it, create a server file:

// src/routes/blog/[slug]/+page.server.js
import { getPost } from '$lib/server/posts.js';
 
export function load({ params }) {
  const post = getPost(params.slug);
  return { post };
}

For the address /blog/runes, params.slug is the string 'runes'. The property name matches the text in the brackets: a folder [id] would give params.id.

The post page

Put +page.svelte next to it:

<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
  let { data } = $props();
</script>
 
<article>
  <h1>{data.post.title}</h1>
  <p>{data.post.body}</p>
</article>
 
<a href="/blog">All posts</a>

Open /blog and click a title — the post page opens with its text. We already wrote links like href="/blog/{post.slug}" in the list in the previous lesson.

Post not found

For the address /blog/nothing the getPost function returns undefined, and the page breaks on data.post.title. The right answer is a 404 error with the error function from the @sveltejs/kit package:

// src/routes/blog/[slug]/+page.server.js
import { error } from '@sveltejs/kit';
import { getPost } from '$lib/server/posts.js';
 
export function load({ params }) {
  const post = getPost(params.slug);
 
  if (!post) {
    error(404, 'Post not found');
  }
 
  return { post };
}

Now /blog/nothing shows the default error page with code 404 and the text "Post not found". How to design that page yourself is covered in the lesson on errors. The error function stops load by itself, so in SvelteKit 2 you do not write throw before it.

Other kinds of parameters

FolderMatchesParameter
[slug]/blog/runesparams.slug = 'runes'
[[lang]]/ and /enoptional, may be missing
[...path]/docs/a/b/cparams.path = 'a/b/c'

Parameters always arrive as strings. If the address holds a number, convert it yourself: Number(params.id).

Common mistake

Reading the parameter under a different name. The folder is called [slug], but the code says params.id — the value is undefined, getPost finds nothing, and every post opens as a 404. The name after params. must always match the text in the square brackets of the folder name.

Thanks for reading!

Donate to the site — we work hard for you.