SvelteKit ルーティングでパスパラメータやクエリーパラメーターを使用する
SvelteKit のルーティングで URL パスパラメーターやクエリパラメーターの利用方法について纏めています。
やりたいこと
SvelteKit で URL パスパラメーターやクエリーパラメーターの値をページ内で使用したかったのですが、他の SPA や SSR 系と比較して独特だったので調べて公式ドキュメントの情報を纏めながら実装方法について記しておきます。
環境
- OS
- Microsoft Windows 21H2
- Node.js
- 20.10.0
- svelte
- 4.0.5
- @sveltejs/kit
- 1.20.4
load
関数の作成
SvelteKit では +page.svelte
ファイルと同階層に +page.js
(TypeScript の場合は +page.ts
) ファイルを配置できます。+page.js
は load
関数をエクスポートし、load
関数の戻り値は +page.svelte
で data
プロパティとして受け取ることができます。
+page.svelte
ファイルは、load
関数をエクスポートする+page.js
という兄弟ファイルを持つことができ、load
関数の戻り値は page で data プロパティを介して使用することができます。 - Loading data • Docs • SvelteKit
この load
関数ですが Load
型として以下の通り定義されています。
上記を見ると load
関数は LoadEvent
型の event
を引数として受け取るようです。
なお、実際に +page.ts
内で型を使用する場合は、上記 Load
型は使用せずに Generated Type を使用してください。詳細は後述します。
LoadEvent
は以下のように定義されています。
上記を見ると LoadEvent
はさらに NavigationEvent
を継承していることがわかります。
繰り返しになりますが、実際に +page.ts
内で型を使用する場合は、上記 LoadEvent
型は使用せずに Generated Type を使用してください。詳細は後述します。
NavigationEvent
の定義は以下の通りです。
params: Params;
現在のページのパラメータ - 例えば/blog/[slug]
というルート(route)の場合は、{ slug: string }
オブジェクト
route: {…}
現在のルート(route)に関する情報
id: RouteId;
現在のルート(route)の ID - 例えばsrc/routes/blog/[slug]
の場合は、/blog/[slug]
となる
url: URL;
現在のページのURL
ここまで追うと params
にパスパラメータがキーバリュー形式で格納されていることがわかります。さらに url
に Web API 標準の URL
(URL - Web API | MDN) が格納されているので、クエリーパラメーターもここから取得できそうです。
パスパラメータを取得
前項で、load
関数を用いてパスパラメーターを含む params
やクエリーパラメーターを含む url
が取得できることがわかりました。
実際に load
関数や、load
関数から data
プロパティを受け取るページを実装してみます。ここでは ToDo リストから ToDo の ID を指定して表示するようなケースを想定します。
まず、load
関数をエクスポートする +page.ts
を以下の通り作成します。
load
関数は PageLoad
型としています。前項で Load
型を紹介しましたが、そこでは Params
, InputData
, ParentData
, OutputData
, RouteId
という 5 つのジェネリクスがありました。SvelteKit の Generated Type として、それらのジェネリクスにこのページ特有の型を当てはめて自動生成された型が、PageLoad
型です。
Generated Type については こちらの記事 で詳しく説明していますのでよかったらご参照ください。
.svelte-kit/types/src/todo/[id]/$types.d.ts
を確認してみてください。ジェネリクス Params
には、型 { id: string }
が割り当てられており、その結果 5 行目の id: params.id
のように型安全に取り扱うことができます。
次に +page.svelte
を以下の通り作成します。ただ ID を表示するだけのページです。
+page.ts
の load
関数の戻り値が data
プロパティとして渡されます。
ここでも Generated Type である PageData
を使用します。PageData
は +page.ts
の load
関数の戻り値の型が定義されています。
クエリーパラメーターを取得
クエリーパラメーターのケースも実装してみます。SvelteKit としての使い方はパスパラメータと大きく変わりません。ほぼ URL
の使い方だけの世界です。ToDo リストからステータスをクエリーパラメーターで渡してフィルターするようなケースを想定します。
まず +page.ts
です。 LoadEvent
の url
は Web API 標準の URL
(URL - Web API | MDN) ですので、searchParams
プロパティの URLSearchParams
(URLSearchParams - Web API | MDN) オブジェクトからクエリーパラメーターの値を取得します。
+page.svelte
の方は以下の通りでほとんど同じです。
load
関数をクライアントサイドのみで実行する
公式ドキュメントの以下の記載の通り、load
関数はサーバーでもブラウザでも実行されます。試しに load
関数内に console.log
を仕込むとサーバー側の出力とブラウザ開発者ツールのコンソールの双方に出力されることが確認できます。
+page.js
ファイルのload
関数はサーバーでもブラウザでも実行されます (ただし、export const ssr = false
を設定した場合はブラウザでのみ実行されます)。 - Loading data • Docs • SvelteKit
上記公式ドキュメントの通り、+page.ts
内で ssr = false
をエクスポートするとサーバーで実行されなくなります。
同様に load
関数内に console.log
を仕込むとサーバー側では出力されないことが確認できます。
サーバーサイドで各パラメーターを取り扱う
パスパラメータやクエリーパラメーターの値はサーバーサイドでデータベースへのクエリのパラメーターとして使用するケースが多いと思います。
このようなケースにおいては load
関数はサーバーサイドのみで実行したいはずです。
load
関数をサーバーサイドでのみ実行する場合は +page.ts
の代わりに +page.server.ts
に load
関数を定義します。
サーバーサイドでのみ実行する場合、load
関数の型は ServerLoad
型 (Types • Docs • SvelteKit) となるので注意です。ただしこちらも実際に使用する型は Generated Type である PageServerLoad
型です。
あとがき
SvelteKit でのパスパラメーターやクエリーパラメーターの扱いについて最初少し戸惑いましたが、わかってしまえば簡単でページとデータロードも自然体で分離できて使い勝手よさそうだなと思いました。