【SvelteKit 入門】ルーティング


#### 本記事で扱うファイル

`+page.svelte` `+server.js`



------

シリーズまとめ（随時追加・更新）

| | |
|:-|:-|
| [【SvelteKit 入門】はじめに](https://qiita.com/jwnr/items/430cd160e90fdfa42336) |  |
| [【SvelteKit 入門】作業の前に](https://qiita.com/jwnr/items/9bb7583b5e3d9f75289c) |  |
| [【SvelteKit 入門】アダプター設定・ホスティング・コンテナ運用](https://qiita.com/jwnr/items/740335cfb7d8e000c749) |  |
| 【SvelteKit 入門】ルーティング | now reading |
| [【SvelteKit 入門】データハンドリング(+page.js)](https://qiita.com/jwnr/items/7934196e9ba2e602e063) |  |
| [SvelteKit + microCMS でブログ構築](https://qiita.com/jwnr/items/c7a153f2d1555cc789fe) |  |


------

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

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


:::note info
やや初心者（フロントエンド慣れしていない方）向けの内容も入れます。
ドメインはローカル開発の「`http://localhost:5173`」をそのまま表記しています。
:::


# 基本

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

- 全体のルートに対応しているディレクトリは `/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]`にルーティングされ、`123`や`hoge`は中のコードから呼び出せます。
（その際は「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/
  ...
```

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

:::note info
`/blog/1`〜`/blog/100`があるサイトで、100個ディレクトリは作成しません。それらを全て１ヶ所で受け取り、記事IDを変数として内部に引き込んでからプログラムでそれぞれの記事として生成するわけですね。
:::



# 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`を補助するという方向ではなく **すり替える** という方向の拡張手法も存在します。

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

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

```

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

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





# まとめ（+大事な話）

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

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

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

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

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

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