DEV Community

Cover image for nice URLs with SvelteKit
Kolja
Kolja

Posted on

nice URLs with SvelteKit

TL;DR

If you want URLs like these:

  • for topics:
  awesome.app/best-topic-in-the-world--t5173
Enter fullscreen mode Exit fullscreen mode
  • for user:
  awesome.app/sherlock-holmes--u5173
Enter fullscreen mode Exit fullscreen mode

Then your routes folder has to look like this:

routes/
│   
├─[topic]--t[id]/
│ ├─ +page.server.ts
│ └─ +page.svelte
│   
└─ [user]--u[id]/
   ├─ +page.server.ts
   └─ +page.svelte
Enter fullscreen mode Exit fullscreen mode

Unique URLs

One of the most important properties of a URL is its uniqueness. For our examples, this is technically relatively easy to implement, since each topic and each user in the database also has a unique ID. Mostly this is achieved with a consecutive number. But it can also be a string of random letters and numbers. Theoretically it can also be the name of the topic or the user, but then there must not be two topics or users with the same name, otherwise the uniqueness is no longer given.

For example, URLs can look like this:

  • for topics: awesome.app/topic/5173
  • for user: awesome.app/user/5173

Technically okay, but when we see the link, we would like to know a bit more about what awaits us behind it.

Advanced routing in SvelteKit

SvelteKit has an advanced routing documentation, but the closest approach to my case is this:

If the folder is enclosed with square brackets, this part of the URL is available as a parameter.

So this folder structure:

routes/
│   
├─ topic/
│  └─ [id]/ 
│     ├─ +page.server.ts
│     └─ +page.svelte
└─ ...
Enter fullscreen mode Exit fullscreen mode

Will give us the the id from the URL inside the +page.server.ts files:

// routes/topic/+page.server.ts
export const load = (async ({ params }) => {
  console.log('topic id: ', params.id)

  // prisma example
  const topic = await prisma.topic.findUnique({
    where: {id: parseInt(params.id)} 
  })
  return { topic: topic }
}
Enter fullscreen mode Exit fullscreen mode

And we can use an URL like this: awesome.app/topic/5173

But what could be more obvious than to combine the information for the human and the information for the server?

This method is by far nothing new in the internet, but for SvelteKit I didn't find any examples of it in the documentation.

The sensation

This method also works with multiple parameters in one folder name!

routes/
│ 
├─ [topic]--t[id]/
│ 
└─ [user]--u[id]/
Enter fullscreen mode Exit fullscreen mode

So if we divide our human--server URL by a unique string (--t or --u in this example), we get two parameters for one route.

The first one is for readability and the second one is for the database query. What is in the first parameter doesn't matter at all for processing on the server, as long as our separator is not included.

Now we can use URLs like this: awesome.app/best-topic-in-the-world--t5173 and get two parameters inside the +page.server.ts

// routes/[topic]--t[id]/+page.server.ts
export const load = (async ({ params }) => {
  console.log('topic id: ', params.id)
  console.log('topic slug: ', params.topic)
}

// output
// topic id:  "5173"                       <- always a string!
// topic slug: "best-topic-in-the-world"   <- usecase?
Enter fullscreen mode Exit fullscreen mode

Happy advanced Routing with SvelteKit

Disclaimer:

I wrote this article a few weeks ago. In the meantime the SvelteKit Docs got some more examples, but not exactly this case.

Any constructive feedback is welcome :-)

Top comments (0)