こんにちは。よっしーです(^^)
今日は、SvelteKitでのルーティングについて解説しています。
背景
SvelteKitでのルーティングについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
高度なレイアウト
デフォルトでは、レイアウト階層はルート階層を反映します。しかし、場合によってはそれが望ましくないこともあります。
(group)
例えば、1つのレイアウトを持つべき「アプリ」ルート(例:/dashboard
や/item
)と、異なるレイアウトを持つべき「マーケティング」ルート(/about
や/testimonials
)があるかもしれません。これらのルートを、括弧で囲まれた名前のディレクトリでグループ化できます。通常のディレクトリとは異なり、(app)
と(marketing)
は内部のルートのURLパス名に影響を与えません:
src/routes/
│ (app)/
│ ├ dashboard/
│ ├ item/
│ └ +layout.svelte
│ (marketing)/
│ ├ about/
│ ├ testimonials/
│ └ +layout.svelte
├ admin/
└ +layout.svelte
また、(group)
の直下に+page
を置くこともできます。例えば、/
が(app)
または(marketing)
ページであるべき場合などです。
このグループ化の方法により、以下のような利点があります:
- 関連するルートを論理的にグループ化できます。
- 共通のレイアウトを特定のグループのルートに適用できます。
- ルートの組織化がより明確になり、大規模なアプリケーションの管理が容易になります。
- URLの構造に影響を与えることなく、内部的な構造を整理できます。
この機能は、複雑なアプリケーション構造を持つプロジェクトで特に有用です。開発者は、ユーザーに見えるURLパスを変更することなく、アプリケーションの内部構造を柔軟に組織化できます。
レイアウトからの脱却
ルートレイアウトはアプリのすべてのページに適用されます — もし省略された場合、デフォルトで<slot />
になります。一部のページが他とは異なるレイアウト階層を持つようにしたい場合、共通のレイアウトを継承すべきではないルートを除いて、アプリ全体を1つ以上のグループ内に配置することができます。
上記の例では、/admin
ルートは(app)
または(marketing)
のレイアウトを継承しません。
これにより、以下のような柔軟性が得られます:
- 特定のルートを共通のレイアウトから除外できます。
- 独立したセクション(例:管理パネル)に対して完全に異なるレイアウト構造を持つことができます。
- アプリケーションの異なる部分に対して異なるデザインやナビゲーション構造を適用できます。
この手法は以下のような場合に特に有用です:
- 管理セクションが、メインのアプリケーションとは全く異なるデザインや機能を持つ場合
- 特定のページ(例:ランディングページやエラーページ)が、標準のアプリケーションレイアウトを必要としない場合
- アプリケーション内で完全に独立したセクションを作成したい場合
開発者はこの機能を活用することで、アプリケーション全体の構造を柔軟に設計し、各セクションに最適なレイアウトを適用することができます。これにより、ユーザー体験の向上とコードの管理性の改善が可能になります。
+page@
ページは、ルートごとに現在のレイアウト階層から脱却することができます。前の例の(app)
グループ内に/item/[id]/embed
ルートがあると仮定しましょう:
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page.svelte
│ │ │ └ +layout.svelte
│ │ └ +layout.svelte
│ └ +layout.svelte
└ +layout.svelte
通常、これはルートレイアウト、(app)
レイアウト、item
レイアウト、[id]
レイアウトを継承します。@
の後にセグメント名を付けることで(ルートレイアウトの場合は空文字)、これらのレイアウトのいずれかにリセットできます。この例では、以下のオプションから選択できます:
+page@[id].svelte
–src/routes/(app)/item/[id]/+layout.svelte
から継承+page@item.svelte
–src/routes/(app)/item/+layout.svelte
から継承+page@(app).svelte
–src/routes/(app)/+layout.svelte
から継承+page@.svelte
–src/routes/+layout.svelte
から継承
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page@(app).svelte
│ │ │ └ +layout.svelte
│ │ └ +layout.svelte
│ └ +layout.svelte
└ +layout.svelte
+layout@
ページと同様に、レイアウト自体も同じ技術を使用して親レイアウト階層から脱却できます。例えば、+layout@.svelte
コンポーネントは、そのすべての子ルートの階層をリセットします。
src/routes/
├ (app)/
│ ├ item/
│ │ ├ [id]/
│ │ │ ├ embed/
│ │ │ │ └ +page.svelte // (app)/item/[id]/+layout.svelteを使用
│ │ │ ├ +layout.svelte // (app)/item/+layout@.svelteから継承
│ │ │ └ +page.svelte // (app)/item/+layout@.svelteを使用
│ │ └ +layout@.svelte // (app)/+layout.svelteをスキップし、ルートレイアウトから継承
│ └ +layout.svelte
└ +layout.svelte
このレイアウトリセット機能により、以下のような利点があります:
- 特定のページやセクションに対して、カスタムレイアウトを適用できます。
- 深くネストされたルートでも、必要に応じて上位のレイアウトに「戻る」ことができます。
- アプリケーション内で異なるデザインやレイアウト構造を柔軟に使用できます。
この機能は、複雑なアプリケーション構造を持つプロジェクトや、特定のページに対して異なるレイアウトを適用したい場合に特に有用です。開発者は、アプリケーションの全体的な構造を維持しながら、必要に応じて特定のページやセクションをカスタマイズできます。
レイアウトグループをいつ使用するか
すべてのユースケースがレイアウトのグループ化に適しているわけではありません。また、それらを使用する必要性を感じる必要もありません。あなたのユースケースが複雑な (group)
のネストを招く可能性がある場合や、単一の例外のために (group)
を導入したくない場合もあるでしょう。目的を達成するために、コンポーション(再利用可能な load
関数や Svelte コンポーネント)や if 文などの他の手段を使用することも全く問題ありません。以下の例は、ルートレイアウトに戻り、他のレイアウトも使用できるコンポーネントと関数を再利用するレイアウトを示しています:
src/routes/nested/route/+layout@.svelte
<script>
import ReusableLayout from '$lib/ReusableLayout.svelte';
export let data;
</script>
<ReusableLayout {data}>
<slot />
</ReusableLayout>
src/routes/nested/route/+layout.js
import { reusableLoad } from '$lib/reusable-load-function';
/** @type {import('./$types').PageLoad} */
export function load(event) {
// 必要に応じて、追加のロジックをここに記述
return reusableLoad(event);
}
この方法には以下のような利点があります:
- 柔軟性:特定のページや一連のページに対して、カスタムレイアウトを適用できます。
- 再利用性:共通のコンポーネントや関数を複数のレイアウトで再利用できます。
- シンプルさ:複雑な
(group)
のネストを避けることができます。 - 保守性:レイアウトロジックを集中管理できます。
レイアウトグループを使用するか、このようなコンポジションベースのアプローチを使用するかの判断は、以下の要因に基づいて行うべきです:
- プロジェクトの規模と複雑さ
- レイアウトの再利用パターン
- コードの保守性と可読性
- チームの好みとスキルセット
最終的に、最も適切なアプローチは、特定のプロジェクトの要件と制約に基づいて選択されるべきです。SvelteKitは柔軟性を提供しているので、開発者はプロジェクトに最適なソリューションを選択できます。
おわりに
今日は、 SvelteKitでのルーティングについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント