
こんにちは。よっしーです(^^)
今日は、SvelteKitでのデータ読み込みについて解説しています。
背景
SvelteKitでのデータ読み込みについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
SvelteKitでのデータ読み込み
+page.svelte コンポーネント (およびそれに含まれる +layout.svelte コンポーネント) をレンダリングする前に、多くの場合、データを取得する必要があります。これは、ロード関数を定義することによって行われます。
ユニバーサル vs サーバー
これまで見てきたように、ロード関数には 2 つの種類があります。
- page.js および layout.js ファイルは、サーバーとブラウザーの両方で実行されるユニバーサル ロード関数をエクスポートします。
- page.server.js および layout.server.js ファイルは、サーバー側でのみ実行されるサーバー ロード関数をエクスポートします。
概念的には同じものですが、知っておくべき重要な違いがいくつかあります。
どのロード関数はいつ実行されますか?
サーバーのload関数は常にサーバー上で実行されます。
一方、ユニバーサルなload関数は、デフォルトでは以下のように動作します:
- ユーザーが初めてページを訪れた時、SSR(サーバーサイドレンダリング)中にサーバーで実行されます。
- その後、ハイドレーション中に再度実行され、fetchリクエストの応答を再利用します。
- それ以降の呼び出しはすべてブラウザで行われます。
ただし、ページオプションでこの挙動をカスタマイズすることができます。サーバーサイドレンダリングを無効にすると、SPAとなり、ユニバーサルなload関数は常にクライアント側で実行されます。
ルートにユニバーサルとサーバーの両方のload関数が含まれている場合、サーバーのload関数が先に実行されます。
load関数は通常実行時に呼び出されますが、ページをプリレンダリングする場合はビルド時に呼び出されます。
入力
ユニバーサルとサーバーの両方のload関数は、以下の共通のプロパティとファンクションにアクセスできます:
- リクエストを記述するプロパティ:
params、route、url - 様々な機能:
fetch、setHeaders、parent、depends、untrack
サーバーのload関数はServerLoadEventで呼び出され、これはRequestEventからclientAddress、cookies、locals、platform、requestを継承しています。
ユニバーサルのload関数はLoadEventで呼び出され、これにはdataプロパティがあります。+page.jsと+page.server.js(または+layout.jsと+layout.server.js)の両方にload関数がある場合、サーバーのload関数の戻り値がユニバーサルのload関数の引数のdataプロパティとなります。
出力
ユニバーサルのload関数は、カスタムクラスやコンポーネントのコンストラクタを含む、任意の値を持つオブジェクトを返すことができます。
一方、サーバーのload関数は、ネットワーク経由で転送できるように、devalueでシリアライズ可能なデータを返す必要があります。これには以下が含まれます:
- JSONで表現できるもの
BigInt、Date、Map、Set、RegExpなどの特殊なデータ型- 反復的または循環的な参照
また、サーバーのload関数のデータにプロミスを含めることができ、その場合はブラウザにストリーミングされます。
いつどれを使うか
サーバーのload関数の利点:
- データベースやファイルシステムから直接データにアクセスする必要がある場合に便利
- プライベートな環境変数を使用する必要がある場合に適している
ユニバーサルのload関数の利点:
- 外部APIからデータを
fetchする際、プライベートな認証情報が不要な場合に有用
(SvelteKitがサーバーを経由せず、直接APIからデータを取得できるため) - Svelteコンポーネントのコンストラクタなど、シリアライズできないものを返す必要がある場合に適している
稀に両方を組み合わせて使用する場合:
- 例:サーバーからのデータで初期化されたカスタムクラスのインスタンスを返す必要がある場合
- この場合、サーバーの
load関数の戻り値は直接ページに渡されず、ユニバーサルのload関数のdataプロパティとして渡される
// src/routes/+page.server.js
/** @type {import('./$types').PageServerLoad} */
export async function load() {
return {
serverMessage: 'hello from server load function'
};
}
// src/routes/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ data }) {
return {
serverMessage: data.serverMessage,
universalMessage: 'hello from universal load function'
};
}
おわりに
今日は、 SvelteKitでのデータ読み込みについて解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)


コメント