🥾

【SvelteKit 入門】ルーティング

2022/10/15に公開

本記事で扱うファイル

+page.svelte +server.js


シリーズまとめ(随時追加・更新)

【SvelteKit 入門】はじめに
【SvelteKit 入門】作業の前に
【SvelteKit 入門】アダプター設定・ホスティング・コンテナ運用
【SvelteKit 入門】ルーティング now reading
【SvelteKit 入門】データハンドリング(+page.js)
SvelteKit + microCMS でブログ構築

慣れている方は読むだけで大丈夫かと思います。
手を動かしながら検証したい方は、空プロジェクトを作って下さい。

## テンプレートは空プロジェクト
? Which Svelte app template?
    SvelteKit demo app
>   Skeleton project
    Library skeleton project

基本

ルーティングの前提は以下2つ。

  • 全体のルートに対応しているディレクトリは /src/routes/
  • ディレクトリ名がURLに対応 & 頭文字「+」ファイルが実体

これらを押さえておけば、あとは具体例で見るだけで理解できます。

1. +page.svelteでページ表示

ディレクトリ内に Svelte記法で書かれた+page.svelteを配置すれば、それがページとなります。

/src/routes/
  ├ +page.svelte      ───>  http://localhost:5173/
  ├ index.svelte      ─┐
  └ +index.svelte     ─┴─>  無視される

routes下に 「ディレクトリ & +page.svelte を追加すると、その分だけ URL が生えます。

/src/routes/
  ├ about/
  │   └ +page.svelte  ->  http://localhost:5173/about/
  ├ blog/
  │   └ +page.svelte  ->  http://localhost:5173/blog/
  └ +page.svelte      ->  http://localhost:5173/

// +page.svelte が無いと 404 となる

シンプルにページを表示させたいだけならこれでOKです。

2. []ディレクトリでダイナミックルーティング

/src/routes/
  ├ blog/
  │   ├ [postId]/        <-  ??!!
  │   │   └ +page.svelte
  │   └ +page.svelte       ->  http://localhost:5173/blog/
  ...

ディレクトリ名を[]で囲むと、ワイルドカード的なルーティングが行われます。
上記例だと、/blog/123/blog/hoge/blog/[postID]にルーティングされ、123hogeは中のコードから呼び出せます。
(その際は「URLのpostId部分くれ」と呼び出します)

/src/routes/
  ├ blog/
  │   ├ [postId]/
  │   │   └ +page.svelte   ->  http://localhost:5173/blog/xxx(該当無しの場合)
  │   ├ about/
  │   │   └ +page.svelte   ->  http://localhost:5173/blog/about(優先)
  │   └ +page.svelte       ->  http://localhost:5173/blog/
  ...

ただしこのように[]ナシのディレクトリがある場合はそちらが優先されます。
まずは一致するディレクトリを検索し、マッチしなければ[]のディレクトリに回します。

ex. カスタム404

404 not foundページを自分で実装したい場合いくつか手法がありますが、先程のダイナミックルーティングを使うのが一番簡単です。

/src/routes/
  ├ [hoge]/
  │   └ +page.svelte       ->  ここに 404ページ の内容を記述
  ├ page1/                 ->  http://localhost:5173/page1
  ├ page2/                 ->  http://localhost:5173/page2
  ...

しかしこれでは/abc/defといった下の階層が拾えません。そこで スプレッド構文 を使います。

[]の中を文字列ではなく[...hoge]のようにスプレッド構文にすると下の階層も対象となり、変数にはスラッシュで分割した配列が入ります。

/blog/[hoge]/       【○】 /blog/123          '123' が格納
                    【○】 /blog/abc          'abc' が格納
                    【×】 /blog/abc/def

/blog/[...hoge]/    【○】 /blog/123
                    【○】 /blog/abc
                    【○】 /blog/abc/def       [ 'abc', 'def' ] が格納

つまり、スプレッド構文の[]ディレクトリを/src/routes/に配置しておけば 全てのURLとマッチする ことになり、該当パスが無い全アクセスの受け皿となります。

/src/routes/
  ├ [...hoge]/
  │   └ +page.svelte       ->  ここに 404ページ の内容を記述
  ├ page1/                 ->  http://localhost:5173/page1
  ├ page2/                 ->  http://localhost:5173/page2
  ...

// これで全てのパスが拾える

3. +server.jsでエンドポイント

ディレクトリ下に+page.svelteを置くとページが表示されるURLとなりますが、+server.jsを置くと エンドポイント として動作します。

/src/routes/
  ├ api/
  │   └ +server.js         ->  /api(エンドポイント)
  ├ home/
  │   └ +page.svelte       ->  /home(ページ表示)
  └ +page.svelte           ->  /

ページを表示するのではなく、何かデータを返却するためのURLという事です。
リクエストの種類はGET,POSTだけでなく、全てに対応しています。

/src/routes/
  ├ api/
  │   └ [slug].json/
  │       └ +server.js     ->  /api/xxx.json(エンドポイント)
  ├ home/
  │   └ +page.svelte       ->  /home
  └ +page.svelte           ->  /

また、SvelteKit では返ってくるデータに合わせて 拡張子つきのエンドポイントにする ことを推奨している(必須ではない)ので、サンプルコードを見ていたら上記のようなディレクトリ構造を見るかもしれません。

ex. +page.xx

ディレクトリ下でルーティングに直接関わるのは+page.svelte +server.js(他は補助ファイル)という認識で問題ありません。しかし実は、この+page.svelteを補助するという方向ではなく すり替える という方向の拡張手法も存在します。

使うシーンは無いかもしれませんが、サンプルコード等を見て「?!」とならないように触れておきます。

svelte.config.js
const config = {
  extensions: [".svelte", ".md"],
  kit: {
  ...
};

このように svelte.config.jsextensions項目を追記することで、ページ表示ファイルとして.svelte以外を認識させる事が可能です。
当然ここの設定以外の準備(このケースでは Markdownファイルが変換できるようパッケージのインストール等)も同時にする必要がありますが、インデックスファイルが+page.svelte以外になる という状況が生まれます。

もしどこかのコードを読んでいてディレクトリ下に+page.svxのようなファイルがあれば、「あぁ、拡張してあるのか」と思えばOKです。

まとめ(+大事な話)

SvelteKit では更に複雑な制御も可能ですが、ここまでの内容で十分実装レベルです。
仕組み自体は比較的シンプルですが、見慣れないファイル名が出てきましたね。

ルーティングでは2つしか出てきませんでしたが、この先レイアウト・データハンドリングで増えるので混乱しがちです。特徴的なファイル名が多いのは SvelteKit の短所とも言えるでしょう。

・・・しかしそれには当然目的があります。

役割を持ったファイルが多いという事は、理解し適切に扱えさえすれば その時点で実装がある程度済んでいる と同義です。

「いつ」「どこで」「何を目的に」プログラムが動作するのかが記述ファイルに基づくので、コードにそれを記述する必要が無い。 圧倒的な記述量の少なさを支える設計思想の一つです。

それに必須ファイルはそこまで多くないので、慣れるまでは補助ファイルを無視しても問題無いかと思います。その感覚で他の記事も読んでみてください。

Discussion