Reputation: 391
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.
Upvotes: 38
Views: 54289
Reputation: 29214
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>
Upvotes: 2
Reputation: 2648
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
In order to create content for the http://localhost:3000/blog
page, you can modify src/routes/blog/+page.svelte
Upvotes: 31
Reputation: 31
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>
Upvotes: 3
Reputation: 23483
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
Upvotes: 52
Reputation: 51
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)
[slug].svelte
sveltejs/sapper-template
example.preload
function to load
with a single parameter such as ctx
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
Upvotes: 4