Table of Contents
Creating the Segments
Making breadcrumbs base on routes is straightforward. In SvelteKit, +page.server.ts
, +page.ts
, +layout.server.ts
, and +layout.ts
load functions have an event parameter with an async parent()
method that returns data from parent +layout.server.ts
and +layout.ts
load functions.
By placing a breadcrumbs
array in the root layout, you can use event.parent()
and Array.concat
to append breadcrumbs at each route segment which requires a breadcrumb. And you can use data from that route segment to make the breadcrumb value and href dynamic.
Here is an example used on my Adventurers League Log Sheet app.
…/+layout.server.ts
ts export const load = async ( event ) => {
return {
breadcrumbs : [] as { name : string ; href : string }[] ,
} ;
} ;
…/characters/+layout.server.ts
ts export const load = async ( event ) => {
const parent = await event . parent () ;
return {
breadcrumbs : parent . breadcrumbs . concat (
{
name : " Characters " ,
href : " /characters "
}
)
} ;
} ;
…/characters/[characterId]/+layout.server.ts
ts import { getCharacter } from " $/server/data/characters " ;
import { error , redirect } from " @sveltejs/kit " ;
export const load = async ( event ) => {
const parent = await event . parent () ;
if ( event . params . characterId === " new " ) throw redirect ( 301 , " /characters/new/edit " ) ;
const character = await getCharacter ( event . params . characterId ) ;
if ( ! character ) throw error ( 404 , " Character not found " ) ;
return {
breadcrumbs : parent . breadcrumbs . concat (
{
name : character . name ,
href : ` /characters/ ${ character . id } `
}
)
} ;
} ;
Now the resulting array in data.breadcrumbs
for /characters/[characterId]
is:
js [
{ name : ' Characters ' , href : ' /characters ' } ,
{ name : ' Rimurus ' , href : ' /characters/cl7gfkggq002009mluw41peqd ' }
]
The Breadcrumbs Component
From there, you can create a breadcrumbs component like this:
Breadcrumbs.svelte
svelte < script lang = " ts " >
import { page } from " $app/stores " ;
import Icon from " ./Icon.svelte " ;
let breadcrumbs = ( $ page . data . breadcrumbs as { name : string , href ?: string }[]) . map (( bc , i ) => ({
name : bc . name ,
href : ! bc . href || i === $ page . data . breadcrumbs . length - 1 ? null : bc . href ,
})) ;
</ script >
< div class = " breadcrumbs mb-4 hidden flex-1 text-sm sm:flex " >
< ul >
< li >
< Icon src = " home " class = " w-4 " />
</ li >
{ # each breadcrumbs as bc }
{ # if bc . href }
< li >
< a href = { bc . href} class = " text-secondary " >
{ bc . name}
</ a >
</ li >
{ : else }
< li class = " overflow-hidden text-ellipsis whitespace-nowrap dark:drop-shadow-md " >
{ bc . name}
</ li >
{ / if }
{ / each }
</ ul >
</ div >