🍞

SvelteKitでぱんくずを実装する時のアイデア

2023/05/25に公開

概要

SvelteKitでのぱんくずの実装のアイデアです。

何をしたいか

ざっくり

親階層のぱんくずのデータはそのまま使用して、子階層でその親ページの内容を再度書かなくていいようにする

というのをやります。
子孫ページで親ページのタイトルとかパスをいちいちまた書くのはめんどくさいですよね。
あんなめんどくさいこといちいちやってられません。

親ページ>子ページ>孫ページ>ひ孫ページ

という階層があるサイトがありました。ひ孫ページではそれまでのすべての親ページの情報をぱんくずに表示する必要があります。

めんどくさいですね…
これをSvelteとSvelteKitがデフォルトで持っている機能を使っていい感じに実装したいなと思いました。

デモ

触ったことある人はデモを見ればわかると思うのでみてください。

https://www.sveltelab.dev/her1i0ohl5wajzy

ポイントを説明

SvelteKitには+layout.server.jsなどでload関数からreturnしたデータを+page.svelteなどで使用できる仕様があります。(Next.jsでいうとgetServerSidePropsみたいなやつ)

このload関数ですが、前の階層のload関数でreturnした内容をparent()で取得することができる便利な機能があります。
これめっちゃ便利です。

デモサイトでは親階層の/projects/+layout.server.js

export const load = async ({ params }) => {
   const breadcrumb = [
      { name: 'プロジェクト一覧', path: '/projects' }
   ]
   return { breadcrumb }
}

しています。

その下の階層の/projects/[id]/+layout.server.jsでは

export const load = async ({ params, parent }) => {
   const { id } = params
   const { breadcrumb } = await parent() // Point!!
   const lastPath = breadcrumb[breadcrumb.length - 1].path
   
   return {
      project: {
         id,
         title: `プロジェクト${id}詳細`
      },
      breadcrumb: [
         ...breadcrumb,
         {
            name: '記事詳細',
            path: `${lastPath}/${id}`
         }
      ]
   }
}

のように書いていますが、load関数のなかでconst { breadcrumb } = await parent()しているところがポイントです。

ここで取得されるbreadcrumbparent()関数名から予想がつくと思いますが、一つ前の階層のload関数でreturnしておいたbreadcrumbから取得されます。

これを下の階層に向けてどんどんやっていけば、カレントの階層ではそのページの情報を書くだけでよくなります。
最高ですね〜

というわけでここまでくればぱんくずに渡したいデータは用意できているので、/projects/[id]/edit/+page.svelteなどで

   import { breadcrumbStore } from '$lib/Breadcrumb'
   export let data
   $: ({breadcrumb, project} = data)
   $: breadcrumbStore.set(breadcrumb)

するだけです。

これでめんどくさいぱんくずの表示がちょっと楽になるのではないでしょうか。
他にいい実装方法があったら教えてください〜!

感想

  • Svelteはstoreがデフォルトの機能にあるので他のライブラリを探したりする必要がなくて楽
  • parent()の使い勝手がかなりいい(親ページで使ったデータを子ページで使いたいことが多い)
  • 簡単
  • SvelteLab最高〜〜〜

SvelteKitはいいぞ。

Discussion