Skip to content

Instantly share code, notes, and snippets.

@KoljaL
Last active March 2, 2023 23:22
Show Gist options
  • Save KoljaL/574d43325238f9860dd5021b21292143 to your computer and use it in GitHub Desktop.
Save KoljaL/574d43325238f9860dd5021b21292143 to your computer and use it in GitHub Desktop.
Use two parameters in one route with separator string

nice URLs with SvelteKit

TL;DR

If you want URLs like these:

  • for topics:

    awesome.app/best-topic-in-the-world--t5173
    
  • for user:

    awesome.app/sherlock-holmes--u5173
    

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

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
└─ ...

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 }
}

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]/

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?

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment