さとまたwiki

データ読み込み

load関数でページにデータを渡す

load関数とは?

日常での例え:レストランのキッチン

お客さん(ブラウザ)が「このページください」と注文

キッチン(load関数)が裏で材料(データ)を準備

準備できたら、盛り付けて(ページに渡して)提供

なぜload関数が必要?

ページを表示する前にデータが必要な時に使います:

  • ブログ記事一覧をデータベースから取得
  • ログイン中のユーザー情報をチェック
  • 外部APIからデータを取得

メリット:サーバーで実行されるので、APIキーやDB接続が安全!

サーバーサイドload

+page.server.ts

サーバー上でデータを取得

typescript
// src/routes/posts/+page.server.ts
export async function load() {
  const posts = await db.post.findMany();

  return {
    posts
  };
}

// +page.svelte で使う
// let { data } = $props();
// data.posts でアクセス
プレビュー
// サーバーでのみ実行
// - DBに直接アクセス可能
// - APIキーが漏れない

ページでデータを受け取る

$propsでdataを取得

svelte
<!-- src/routes/posts/+page.svelte -->
<script>
  let { data } = $props();
</script>

<h1>投稿一覧</h1>
<ul>
  {#each data.posts as post}
    <li>{post.title}</li>
  {/each}
</ul>
プレビュー

投稿一覧

  • 投稿タイトル1
  • 投稿タイトル2
  • 投稿タイトル3

パラメータとURL情報

load関数の引数

params, url, cookies など

typescript
// src/routes/blog/[slug]/+page.server.ts
export async function load({ params, url, cookies }) {
  // URLパラメータ
  const { slug } = params;

  // クエリパラメータ
  const page = url.searchParams.get('page') || '1';

  // Cookie
  const token = cookies.get('session');

  const post = await getPost(slug);

  return { post, page };
}
プレビュー
params.slug // URLパラメータ
url.searchParams // クエリ
cookies.get() // Cookie

ユニバーサルload

+page.ts

サーバーとクライアント両方で実行

typescript
// src/routes/posts/+page.ts
export async function load({ fetch }) {
  // fetchはSvelteKitが提供する特別な関数
  // サーバーでもクライアントでも動作する
  const response = await fetch('/api/posts');
  const posts = await response.json();

  return { posts };
}

// +page.server.ts との違い:
// - サーバーとクライアント両方で実行可能
// - DB直接アクセスはできない
// - ナビゲーション時はクライアントで実行
プレビュー
// +page.server.ts → サーバーのみ
// +page.ts → サーバー & クライアント

レイアウトでのデータ読み込み

+layout.server.ts

子ルート全体で共有するデータ

typescript
// src/routes/+layout.server.ts
export async function load({ cookies }) {
  const sessionId = cookies.get('session');
  const user = sessionId ? await getUser(sessionId) : null;

  return {
    user  // 全ページで使える
  };
}

// src/routes/+layout.svelte
<script>
  let { data, children } = $props();
</script>

{#if data.user}
  <p>ようこそ、{data.user.name}さん</p>
{/if}

{@render children()}
プレビュー
// レイアウトのloadは
// 子ページ全てで使える

エラーハンドリング

error関数

エラーをスローしてエラーページを表示

typescript
// src/routes/blog/[slug]/+page.server.ts
import { error } from '@sveltejs/kit';

export async function load({ params }) {
  const post = await getPost(params.slug);

  if (!post) {
    error(404, {
      message: '記事が見つかりません'
    });
  }

  return { post };
}

// +error.svelte でエラーを表示
プレビュー

404

記事が見つかりません

+error.svelte

エラーページの定義

svelte
<!-- src/routes/+error.svelte -->
<script>
  import { page } from '$app/stores';
</script>

<h1>{$page.status}</h1>
<p>{$page.error?.message}</p>

<a href="/">ホームに戻る</a>
プレビュー

404

ページが見つかりません

ホームに戻る

リダイレクト

redirect関数

別ページへリダイレクト

typescript
// src/routes/dashboard/+page.server.ts
import { redirect } from '@sveltejs/kit';

export async function load({ cookies }) {
  const session = cookies.get('session');

  if (!session) {
    // 未ログインならログインページへ
    redirect(303, '/login');
  }

  const user = await getUser(session);
  return { user };
}
プレビュー
redirect(303, '/login')
// 303: See Other(POST後のリダイレクト)
// 307: Temporary Redirect