SvelteKitのレイアウト(+layout.svelte)を深掘りした話
SvelteKitの +layout.svelte の応用パターンを整理します。ネストしたレイアウト・レイアウトデータの取得・ルートグループ・レイアウト無効化を解説します。
レイアウトの基本的な仕組みのおさらい
src/routes/
+layout.svelte ← 全ページ共通のレイアウト
+page.svelte ← / のコンテンツ
posts/
+layout.svelte ← /posts 配下だけに適用されるレイアウト
+page.svelte ← /posts のコンテンツ
[id]/
+page.svelte ← /posts/[id] のコンテンツ
子のレイアウト・ページは親のレイアウトの {@render children()} の位置に差し込まれます。
① レイアウトデータを load で渡す
+layout.server.ts を使うと全ページで共通のデータを取得できます。ログインユーザー情報の取得が典型例です。
// src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async ({ locals }) => {
return {
user: locals.user ?? null,
};
};
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import type { Snippet } from 'svelte';
import type { LayoutData } from './$types';
type Props = {
data: LayoutData;
children: Snippet;
};
let { data, children }: Props = $props();
</script>
<header>
{#if data.user}
<span>{data.user.name}</span>
<a href="/logout">ログアウト</a>
{:else}
<a href="/login">ログイン</a>
{/if}
</header>
<main>
{@render children()}
</main>
各ページの +page.svelte では data.user を自分でロードしなくても、親レイアウトが取得した値を引き継げます。
② ルートグループ — URLに影響しないグループ化
(グループ名) という形式のディレクトリはURLに含まれません。レイアウトだけを切り替えたいときに使います。
src/routes/
(public)/ ← URLには含まれない
+layout.svelte ← ログイン不要ページ用レイアウト
+page.svelte ← /
about/
+page.svelte ← /about
(authed)/ ← URLには含まれない
+layout.svelte ← ログイン済みページ用レイアウト
dashboard/
+page.svelte ← /dashboard
settings/
+page.svelte ← /settings
<!-- src/routes/(authed)/+layout.svelte -->
<script lang="ts">
import { redirect } from '@sveltejs/kit';
import type { Snippet } from 'svelte';
import type { LayoutData } from './$types';
type Props = {
data: LayoutData;
children: Snippet;
};
let { data, children }: Props = $props();
if (!data.user) {
redirect(302, '/login');
}
</script>
{@render children()}
ログイン必須ページをまとめてグループ化することで、認証チェックを1か所に集約できます。
③ レイアウトを無効化する
特定のページだけ親のレイアウトを使いたくない場合、ファイル名に @ を付けます。
src/routes/
+layout.svelte
login/
+page@.svelte ← ルートレイアウトを無効化(レイアウトなしで表示)
+page@.svelte は全レイアウトをスキップして素のページとして表示されます。ログインページや全画面表示のページで使います。
まとめ
| 機能 | 書き方 | 用途 |
|---|---|---|
| 共通レイアウト | +layout.svelte |
ヘッダー・フッターなど |
| 共通データ取得 | +layout.server.ts |
ログインユーザー情報など |
| URLに影響しないグループ | (グループ名)/ |
認証あり・なしでレイアウトを分ける |
| レイアウト無効化 | +page@.svelte |
ログインページなど |