SvelteKit: how do I do slug-based dynamic routing?
Asked Answered
T

4

36

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.

Tarsia answered 28/1, 2021 at 2:44 Comment(2)
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.Debacle
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.Tarsia
E
47

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

Eldridgeeldritch answered 26/11, 2022 at 22:2 Comment(0)
C
29

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

Cymene answered 29/7, 2021 at 16:20 Comment(3)
Thanks for the answer, I'm curious what does $ mean here? [ in $page variable ]Vex
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-pageCymene
check @Eldridgeeldritch 's answer below for updated.Polygon
C
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

Camp answered 29/1, 2021 at 20:0 Comment(2)
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.Boatel
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.Beet
A
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>
Autolysis answered 12/1, 2023 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.