40

I am a newbie on Svelte and in coding in general. I'd prefer to learn SvelteKit (Svelte@Next) rather than sapper since that seems to be where Svelte is heading.

For my personal project, I need to support dynamic routing based on url slugs. How do I do that in SvelteKit? For example, if I have /blog directory and need to pull content based on its "id", how would I do that?

The part that I am having difficulty with is accessing the URL slug parameter.

Thanks in advance.

2
  • 4
    Considering SvelteKit has not been released yet (and is still changing), any answer to this question might be incorrect by the time it is actually released. Commented Jan 28, 2021 at 6:41
  • 1
    Today, Sapper uses 'preload' function to access its URL params. Once SvelteKit is fully up and running, it will likely render all Sapper content old and somewhat irrelevant. If how the URL parameters are accessed in SvelteKit changes in its early days, the answer here could very easily be updated. Commented Jan 28, 2021 at 7:42

5 Answers 5

52

As of SvelteKit 1.0 the path should be a directory in brackets, e.g. for /blog/<slug> you will add the following:

src/routes/blog/[slug]
  |_ +page.js
  |_ +page.svelte

Then in src/routes/blog/[slug]/+page.js you can add something like

export const load = ({ params }) => {
    return {
        slug: params.slug
    }
}

which will return it as a data property to +page.svelte, so you can write something like:

<script>
    export let data;
</script>

<h1>{data.slug}</h1>

Reference: https://kit.svelte.dev/docs/routing

Sign up to request clarification or add additional context in comments.

Comments

32

You can create a file at src/routes/blog/[slug]/+page.svelte

And paste the following code

<script>
    import { page } from '$app/stores';
</script>

{$page.params.slug}

Then navigate to your app http://localhost:3000/blog/123

You should see your result

result svelte kit slug

In order to create content for the http://localhost:3000/blog page, you can modify src/routes/blog/+page.svelte

3 Comments

Thanks for the answer, I'm curious what does $ mean here? [ in $page variable ]
From my understanding, in SvelteKit, page is generated as a store element. And in svelte, if you want to access store elements you need to prefix them with $. page documentation : kit.svelte.dev/docs#loading-input-page
check @isapir 's answer below for updated.
4

Caveat - the info in my reply probably may not be valid as SvelteKit matures, but from experiments I have done thus far, this works:

Parameter based routing is similar to the sveltejs/sapper-template. You should learn how Sapper does it first. Lets say I have a route blog with a single param slug (/blog/page-1 & /blog/page-2)

  1. Create a route component in routes/blog named [slug].svelte
  2. Copy the content from the sveltejs/sapper-template example.
  3. Rename the preload function to load with a single parameter such as ctx
  4. Alter the return object to append your slug property to props
export async function load(ctx) {
  let slug = ctx.page.params.slug
  return { props: { slug }}
}

If your blog has multiple params for the slug (/blog/2021/01/29/this-is-a-slug), you can remove [slug].svelte and create a file name [...data].svelte and change your load method to:

export async function load(ctx) {
  let [year, month, day, slug] = ctx.page.params.data;
  return { props: { data: { year, month, day, slug }}}
}

Don't forget to define your data property as an object. Here's a typescript example:

<script lang="ts">
    export let data: { slug:  string, year: number, month: number, day: number };
</script>

From there use the values as {data.slug}, etc

Happy hacking

2 Comments

When I try to get the different parameters from [...data], I am unable. All I can get is just one string with the rest of the parameters. I am working with Sveltekit.
Thanks for mentioning the [...data]. This way I was able to create a [...path] directory and match all URLs. When a page is loaded, params.path is for example '' for homepage, or 'use-cases/something' for a nested page.
3

I also had some issues with the Typescript import so here is a complete Typescript example.

Structure:

src/routes/coins/[coin_name]
  |_ +page.ts
  |_ +page.svelte

+page.ts:

import type { PageLoad } from './$types';

export const load: PageLoad = ({ params }) => {
    return {
        name: params.coin_name
    }
}

export interface CoinPage{
    name: string
}

+page.svelte and the use of the data:

<script lang="ts">
    import type { CoinPage } from "./+page";

    export let data:CoinPage;
</script>

<h1>{data.name}</h1>

Comments

2

I upvoted @isapir's answer because it helped, but here's how I did it with the most recent Svelte with a little change...

I have /routes/characters/[slug]/+page.ts, I always seem to forget the leading '+' which causes an error with params, but here's working code:

export const load = ({ params }) => {
    return {
        slug: params.slug
    }
}

Then in /routes/characters/[slug]/+page.svelte:

<script lang="ts">
    let { data } = $props();
</script>

<h1>Character id: {data.slug}</h1>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.