mcpField
S
sveltekit-advanced

sveltekit-advanced

github.com/full-stack-skills開発473 回インストール5 週間前に更新
リポジトリ

sveltekit-advanced について

sveltekit-advancedは、SvelteKitの高度な機能を扱う開発者向けリファレンススキルです。サーバーとクライアントの状態管理、リモート関数、フック、環境変数、エラー処理、ルーティング状態などを解説します。

主な機能

  1. 01サーバー/クライアント状態の指針
  2. 02リモート関数APIのリファレンス
  3. 03環境変数とフックの設定
  4. 04エラー処理パターン
  5. 05Service Workerとサーバー専用モジュール
  6. 06スナップショットと浅いルーティング

活用シーン

  1. 01アプリケーション状態の配置先を選ぶ
  2. 02型安全なクライアント/サーバー呼び出しを構築
  3. 03リクエストフックとエラーレスポンスを設定
  4. 04ブラウザー側への秘密情報の流出を防ぐ

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/full-stack-skills/svelte-skills --skill sveltekit-advanced

インストール後、Claude Code で/sveltekit-advancedを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
examples/
app-modules.md
env-vars.md
errors.md
hooks.md
link-options.md
README.md
remote-functions.md
service-worker.md
shallow-snapshots.md
state-management.md
references/
app-modules.md
env-vars.md
errors.md
hooks.md
link-options.md
README.md
remote-functions.md
server-only.md
service-worker.md
shallow-snapshots.md
state-management.md

詳細

SvelteKit Advanced

SvelteKit の高度な機能に関するリファレンスです。サーバー/クライアント間の状態管理、リモート関数 API、環境変数(旧式と明示的な方法)、フック(サーバー/共有/ユニバーサル)、エラー処理、リンクオプション、サービスワーカー、サーバー専用モジュール、スナップショット、浅いルーティング、$app/* モジュールを扱います。

出典:SvelteKit の公式 llms.txt ドキュメント。

このスキルを使う場面

次のような場合にこのスキルを使います。

  • 状態をどこに置くか(サーバーコンテキスト、URL、スナップショット、ストア)を選ぶ。
  • query/form/command/prerender を使って、型安全なクライアント/サーバー RPC を構築する。
  • 環境変数を安全に読み取る(プライベートとパブリック、静的と動的)。
  • フック(handle、handleFetch、handleError、handleValidationError、reroute、transport、init)を使ってリクエスト処理をカスタマイズする。
  • 予期されるエラー/予期しないエラーをスローし、フォールバックのエラーページをカスタマイズし、App.Error でエラーの形式を型定義する。
  • data-sveltekit-* 属性を使ってリンクの動作を設定する。
  • オフライン対応や事前キャッシュのためにサービスワーカーを追加する。
  • .server.* または $lib/server/ を使って、シークレットの漏えいを防ぐ。
  • スナップショットで一時的な DOM 状態を保持するか、浅いルーティングでルート履歴エントリを保持する。
  • $app/* モジュール(forms、navigation、state、paths、server、environment、types)を使う。

ルーティング、フォームアクション(旧式)、load、基本的なセットアップ、環境変数以外のアダプター設定、CSS/スタイリングには、このスキルを使わないでください。

重要なセクション

1. 状態管理
  • 共有サーバー状態は禁止 — モジュールレベルの変数(let user;)はリクエスト間で漏えいします。Cookie を使って認証し、DB に保存してください。
  • 純粋な load 関数 — 副作用(グローバルストアなど)を含めないでください。代わりにデータを返します。
  • リクエストごとの状態にはコンテキストを使用 — setContext('user', () => data.user)(関数を渡すことで、境界を越えてリアクティビティが維持されます)。SSR 中に子で更新されたコンテキストを読み取っても、親には伝播しません(親はすでにレンダリング済みです)。
  • コンポーネントの状態はナビゲーション後も保持される — data から導出した const は一度しか計算されません。データの変更時に再計算する値には $derived(...) を使います。
  • URL の状態 — フィルターや並べ替えには検索パラメーターを使います。再読み込み後も保持され、SSR に反映されます。
  • スナップショット — 履歴エントリにひも付けられた破棄可能な UI 状態(例:「アコーディオンが開いているか」)。
2. リモート関数(2.27 以降、実験的機能)

svelte.config.js でオプトインします。

kit: { experimental: { remoteFunctions: true } },
compilerOptions: { experimental: { async: true } }

*.remote.js からエクスポートする種類:

種類用途主な機能
query動的なサーバーデータを読み取る重複排除、refresh()、loading/error/current
query.batch複数のクエリを 1 回の呼び出しにまとめる(input, idx) => Output を返す
query.liveリアルタイムの非同期イテラブルconnected、reconnect()。最初の値は SSR 用にシリアライズされます
formプログレッシブエンハンスメント対応の <form><form {...createPost}>、createPost.fields.x.as('text')、validate()、enhance()、for(id)、preflight(schema)
commandイベントハンドラーから命令的に変更するレンダリング中には呼び出せません
prerenderビルド時のデータinputs、dynamic: true
  • 任意の Standard Schema(Zod/Valibot)で検証します。
  • 引数と戻り値は devalue でシリアライズされます。
  • リモート関数内では Cookie 用に getRequestEvent() を使用できます。
  • redirect(...) は query/form/prerender では使用できますが、command では使用できません。
  • 単一実行のミューテーション:サーバーハンドラーでは getPosts().refresh() または getPost(id).set(...) を使います。クライアントが要求した更新には requested(getPosts, 1).refreshAll() を使います(上限は DoS 対策です)。
3. 環境変数

レガシーの $env/*(SvelteKit 2.63 より前のデフォルト):

モジュールスコープタイミング
$env/dynamic/privateサーバーのみ実行時(process.env に類似)
$env/dynamic/publicパブリック(PUBLIC_*)実行時
$env/static/privateサーバーのみビルド時(インライン化)
$env/static/publicパブリックビルド時(インライン化)

明示的な環境変数(オプトイン、v3 でデフォルト):

svelte.config.js で有効にします:kit.experimental.explicitEnvironmentVariables = true。次に src/env.ts を作成します:

import { defineEnvVars } from '@sveltejs/kit/hooks';
import * as v from 'valibot';
import { building } from '$app/env';

export const variables = defineEnvVars({
  API_KEY: {},                              // private
  GOOGLE_ANALYTICS_ID: { public: true },    // public
  SHOW_DEBUG_OVERLAY: { public: true, static: true },  // inlined, dead-code-eliminated
  SECRET: { schema: building ? v.optional(v.string()) : v.string() },
  CACHE_TTL_SECONDS: { description: 'How long...' }
});

$app/env/private または $app/env/public からインポートします。$app/environment は $app/env に名称変更されました。

4. フック

任意のファイルが 3 つあります:src/hooks.server.js、src/hooks.client.js、src/hooks.js。

サーバー(hooks.server.js):

  • handle({ event, resolve }) — すべてのリクエストで実行されます。Response を返すか、resolve(event, opts) を呼び出します。resolve の opts:transformPageChunk、filterSerializedResponseHeaders、preload。複数の場合は sequence(...) を使用します。
  • handleFetch({ request, fetch, event }) — クロスオリジンリクエストを内部 API に書き換えます。兄弟サブドメイン間で Cookie を転送します。
  • handleValidationError({ event, issues }) — リモート関数の引数が不正な場合の 400 レスポンスをカスタマイズします。

共通(hooks.server.js と hooks.client.js):

  • handleError({ error, event, status, message }) — 予期しないエラーのみを対象とします。{ message, ... } を返すと、page.error になります。例外をスローしてはいけません。サーバーの型:HandleServerError。クライアントの型:HandleClientError。クライアントの event は NavigationEvent です。
  • init() — 起動時に 1 回実行されます。DB 接続などに便利です。

ユニバーサル(hooks.js):

  • reroute({ url, fetch }) — URL を別のルートに変換します(例:i18n)。純粋で冪等な処理です。2.18 以降は非同期にできます。
  • transport — サーバーとクライアントの境界を越える型(例:Vector)用のカスタムエンコーダー/デコーダーです。
5. エラー
  • 予期されるエラー — @sveltejs/kit の error(404, 'Not found')(または error(404, { message, code }))です。最も近い +error.svelte をレンダリングし、ステータスコードを設定します。page.error は渡されたオブジェクトです。
  • 予期しないエラー — その他すべての例外です。公開されず(一般的な Internal Error)、handleError を経由します。
  • レンダリングエラー — experimental.handleRenderingErrors でオプトインします。エラーは page.error 経由ではなく、error prop として直接 +error.svelte に渡されます。
  • レスポンス — %sveltekit.status% と %sveltekit.error.message% を含むカスタムの src/error.html を使用します。ルートの +layout.server.js で発生したエラーにはフォールバックページが使用されます(ルートに +error.svelte がある場合)。
  • 型安全性 — src/app.d.ts で App.Error インターフェースを宣言します:
declare global {
  namespace App {
    interface Error { message: string; code: string; id: string; }
  }
}
6. リンクオプション

<a>(または親要素)に data-sveltekit-* 属性を設定します。<form method="GET"> にも適用されます。

属性値効果
preload-datahover(デフォルト)、tapホバー/タップ時に load データをプリロード
preload-codeeager、viewport、hover、tapルートコードのみをプリロード
reloadbooleanページ全体のナビゲーションを強制(rel="external" も同様)
replacestateboolean履歴エントリーを追加せず置き換え
keepfocusbooleanナビゲーション後も同じ要素にフォーカスを維持
noscrollbooleanナビゲーション後にページ先頭へスクロールする動作を無効化

data-sveltekit-preload-data="false" を使用すると、サブツリー内で無効にできます。navigator.connection.saveData の設定が尊重されます。

7. サービスワーカー

src/service-worker.js(または src/service-worker/index.js)を配置します。バンドルされ、自動登録されます。設定で無効にすると、手動で登録できます。

$service-worker から利用できるもの:base、build、files、prerendered、version。

標準的なパターンは、インストール時に build + files をキャッシュし、フェッチ時にネットワーク優先で、失敗した場合はキャッシュにフォールバックする方法です。Cache-Control: no-store を含むレスポンス(ライブクエリ)はスキップします。開発時、build/prerendered は空の配列です。

8. サーバー専用モジュール
  • $env/static/private と $env/dynamic/private — サーバー専用です。
  • $app/server — サーバー専用です。
  • 独自のモジュール — .server.js サフィックスを付けるか、$lib/server/ の下に配置します。

ブラウザーコードから不正にインポートすると、ビルド時にエラーになります。型のみの場合は import type を使用します。テストでは検出が無効になります(process.env.TEST === 'true')。

9. スナップショットと浅いルーティング

スナップショット — +page.svelte または +layout.svelte から snapshot = { capture, restore } をエクスポートします。ページ更新前に sessionStorage にキャプチャされ、履歴ナビゲーション時に復元されます。JSON でシリアライズ可能である必要があります。巨大なオブジェクトは返さないでください。

浅いルーティング — pushState(url, state) / replaceState(url, state) は、ナビゲーションせずに履歴エントリーを作成します。page.state から読み取ります。preloadData(href) を使って load データを取得し、その後 pushState(href, { selected: result.data }) を実行すると、モーダル内に別の +page.svelte を表示できます。最初の SSR 時と初回描画時、page.state は常に {} です。

すぐにできる修正

症状修正
リクエスト間でユーザーデータが漏れるモジュールレベルの変数を使わず、Cookie と DB を使用します
ナビゲーション時に load データが更新されないdata から導出した値には const ではなく $derived(...) を使用します
Cannot import $lib/server/...共有型を import type に移します
ライブクエリストリームが停止する.reconnect() で再接続します。SW で no-store レスポンスをキャッシュしないでください
error(404, ...) で空白ページが表示されるルートに最も近い場所に +error.svelte を追加します
サーバー専用の環境変数がクライアントに漏れる$env/static/private または .server 命名を使用します
バリデーションの 400 エラーが汎用メッセージになるhandleValidationError を実装します
ナビゲーション時にコンポーネントの状態が失われる{#key page.url.pathname}<X/>{/key} で囲み、強制的に再マウントします

注意点

  • load は純粋である必要があります — グローバルストアへの書き込みは行わず、代わりにデータを返します。
  • SSR 中のコンテキスト更新は上位に伝播しません — ハイドレーション時のちらつきを避けるため、状態を下位に渡します。
  • query.batch は個々の入力を出力にマッピングする単一の関数を返します。結果の配列を直接返すわけではありません。
  • SSR での query.live は最初に yield された値のみを返し、その後終了します。
  • command はレンダリング中に呼び出せません — イベントハンドラーから呼び出します。
  • requested には limit が必要です — DoS 対策のためです。明示的に安全な場合に限り、Infinity を渡してください。
  • SvelteKit 2.x では error() に throw は不要です。
  • SSR と初回描画時、page.state は {} です — 重要な描画でこれに依存しないでください。
  • reroute は純粋かつ冪等である必要があります — クライアントでは結果が URL ごとにキャッシュされます。
  • 開発環境では Service Worker の build / prerendered は空です — 本番ビルドでテストしてください。
  • 兄弟サブドメインへの Cookie 転送には、手動での handleFetch が必要です — SvelteKit は、どの親ドメインの Cookie がどのサブドメインに属するかを判別できません。
  • handleError は例外をスローしてはいけません — リスクのある処理は try/catch で囲みます。

よくある質問

Q: $app/state と $app/stores の違いは何ですか? A: $app/state(2.12 以降)はルーンベースで、リアクティブです。$app/stores は従来のストアベースのバージョンです。Svelte 5 では $app/state を使用してください。

Q: query と prerender の違いは何ですか? A: 動的データには query、ビルド時に固定され、CDN から配信できるデータには prerender を使用します。完全にプリレンダリングされたページでは query を使用できません。

Q: form と command の違いは何ですか? A: form はプログレッシブエンハンスメントに対応しており、JS なしでも動作し、<form> に展開されます。command は JS 専用で、イベントハンドラーから呼び出します。form を優先してください。

Q: $env/dynamic と $env/static の違いは何ですか? A: dynamic は実行時に読み取ります(例:process.env)。static はビルド時にインライン化されます(デッドコードの削除が可能になります)。ビルド時に値が判明している場合は static を使用してください。

Q: $env/static/private と $env/dynamic/private の違いは何ですか? A: アクセス制限は同じで、違いは値を読み取るタイミングです。Static では DCE が可能になり、dynamic では実行時の上書きが可能です(例:MY_FLAG=1 npm run dev)。

Q: +page.svelte から $lib/server モジュールを使用できますか? A: いいえ。サーバー専用モジュールは、間接的な場合も含めてクライアントコードからインポートできません。SvelteKit はビルド時にエラーを出します。

Q: 送信後も検索入力欄にフォーカスを維持するにはどうすればよいですか? A: <form> に data-sveltekit-keepfocus を追加してください。

Q: load から 404 をスローするにはどうすればよいですか? A: import { error } from '@sveltejs/kit'; error(404, 'Not found'); を使用してください(SvelteKit 2 では throw を使わないでください)。

Q: Sentry を使用すべきですか? A: はい。hooks.server.js と hooks.client.js の両方の handleError で初期化してください。サーバーでは HandleServerError、クライアントでは NavigationEvent を含む HandleClientError を使用します。

例

トピックファイル
context + URL + derived による状態管理examples/state-management.md
リモート query/form/command/batch/liveexamples/remote-functions.md
環境変数(従来の方法 + 明示的な方法)examples/env-vars.md
サーバー + ユニバーサルフックexamples/hooks.md
想定内/想定外のエラー + App.Errorexamples/errors.md
data-sveltekit-* リンクオプションexamples/link-options.md
サービスワーカーのプリキャッシュ + オフラインexamples/service-worker.md
$app/* モジュール(forms、navigation、state、paths、server)examples/app-modules.md
スナップショット + 浅いルーティングexamples/shallow-snapshots.md

参考資料

トピックファイル
状態管理references/state-management.md
リモート関数references/remote-functions.md
環境変数references/env-vars.md
フックreferences/hooks.md
エラーreferences/errors.md
リンクオプションreferences/link-options.md
サービスワーカーreferences/service-worker.md
サーバー専用モジュールreferences/server-only.md
$app/* モジュールreferences/app-modules.md
スナップショットと浅いルーティングreferences/shallow-snapshots.md

コメント