
t0mmy
学習履歴詳細
実践Next JS 3章 App Router の規約 読了
やったこと
- 実践Next JS 3章 App Router の規約 読了
学んだこと
App Router では、予約済みの特殊なファイル(以下構成ファイル)が存在する。
構成ファイルの一覧は、以下を参照。
構成ファイル名は事前に決まっている。
つまり、構成ファイルとして決めれられている名前でファイルを作成すると、Next JS が自動で読み込んで、適用してくれる。
構成ファイルは、 Segment 別に定義できる。
構成ファイルを使用することで、Next JS の機能を活かした効率的な開発を実現できる。
Segment 構成ファイルの役割
構成ファイル名 | 役割 | 備考 |
---|---|---|
loading | ローディング UI を提供 | |
not-found | 404 UI を提供する | next/navigation の notFound() 関数を呼び出すのが通例 |
error | 何らかの例外を捕捉した場合の UI を提供する | use client でのみ機能する |
route | web api を提供する | |
default | Parallel Routes 用ファイル | |
global-error | error 構成ファイルで捕捉できなかった例外用の UI を提供する | use client でのみ機能する |
Segment 構成フォルダ
予約済みの特殊なフォルダ(以下構成フォルダ)も存在する。
構成フォルダにて、Segment 構成をコントロールできる。
Dynamic Route Segment
パスに含まれるパラメータを参照できる。
パラメータ変数は、[slug]
のように []
で埋め込む。
基本
[slug]
という命名規約でフォルダを作成する。
Route(ディレクトリ構成) | URL リクエストの例 | params |
---|---|---|
app/blog/[slug]/page.tsx | /blog/a | {slug:'a'} |
app/blog/[slug]/page.tsx | /blog/b | {slug:'b'} |
Catch-all Segment
[...slug]
という命名規約でフォルダを作成する。
[]
から page.tsx
までの間に存在する全パラメータを、配列として参照できる。
Route(ディレクトリ構成) | URL リクエストの例 | params |
---|---|---|
app/shop/[...slug]/page.tsx | /shop/a | {slug:['a']} |
app/shop/[...slug]/page.tsx | /shop/a/b | {slug:['a,b']} |
Optional Catch-all Segment
[[...slug]]
という命名規約でフォルダを作成する。
Catch-all Segment の挙動に加えて、パラメータなしのリクエストにも対応できる。
Route(ディレクトリ構成) | URL リクエストの例 | params |
---|---|---|
app/shop/[[...slug]]/page.tsx | /shop | {} |
app/shop/[[...slug]]/page.tsx | /shop/a | {slug:['a']} |
app/shop/[[...slug]]/page.tsx | /shop/a/b | {slug:['a,b']} |
Route Groups
以下の両方を満たすようなユースケースで使用する。
- いくつかのコンポーネントを、フォルダでまとめたい
- まとめ用フォルダは URL Path で扱いたくない
Route Groups を使用すると、フォルダの一部を URL Path から除外できる。
フォルダ名を (feature)
のように ()
で囲むことで、Route Groups として認識され、URL Path の Segment として認識されなくなる。
// website を表現する "site" フォルダでまとめたコンポーネント ./src/app/(site)/photos/page.tsx ./src/app/(site)/categories/page.tsx // 情報提供を表現する "static" フォルダでまとめたコンポーネント ./src/app/(static)/company-info/page.tsx ./src/app/(static)/privacy-policy/page.tsx
これにより、URL Path を参照するソースコードを変更することなく、フォルダによるグループ化を実現できる。
また、Route Group フォルダ (()
で囲った名前のフォルダ)にも、構成ファイルを適用できる。
./src/app/(site)/layout.tsx // (site)用 Layout ./src/app/(site)/photos/page.tsx // (site)用 Layoutが適用される ./src/app/(site)/categories/page.tsx // (site)用 Layoutが適用される ./src/app/(static)/layout.tsx // (static)用 Layout ./src/app/(static)/company-info/page.tsx // (static)用 Layoutが適用される ./src/app/(static)/privacy-policy/page.tsx // (static)用 Layoutが適用される
Private Folder とコロケーション
コロケーション (co-location): 特定機能の関連ファイルをまとめること。
Route に影響を与えないフォルダを配置できる。
フォルダ名の先頭に _
をつけるだけ。
特定の Route でしか使用しないコンポーネントを、Route の近くに配置したい場合等で使用する。
/src/app/_components/page.tsx // ルーティング対象外 /src/app/page.tsx // メイン画面
Parallel Routes と Intercepting Routes
いずれも、ソフトナビゲーションを活用した UI の実装で使用する。
Parallel Routes 概要
複数のコンポーネントを、一つのレイアウト内で同時に(または条件付きで)レンダリングできる機能。
Parallel Routes の使い方
@users
のように、先頭が @
で始まるフォルダ名を作成する。
この時、 @users
を Slot と呼ぶ。
- 言い換えると、 Slot は、
@xxx
という命名規約によって機能する
slot 部分を除いた URL Path に一致するページをレンダリングする際に、 Parallel-routes も一緒にレンダリングされる。
./layout.tsx ./@users/accounts/pages.tsx // slot ./accounts/pages.tsx // @users slot にヒットする
Slot は Segment として扱われない。
そのため、URL Path に影響を与えない。
Slot は、 Layout コンポーネントで受け取る。
受け取り方は、React Component の Children と同じように Props として受け取る。
export default Layout = (props:{ children : React.ReactNode; // React Component の Children users: React.ReactNode; // @users というフォルダの情報が渡される }) => { ... }
Slot フォルダ内で default.tsx
を設定してい置くと、 Route Segment が表示されるまでの間、 default.tsx
の内容がレンダリングされるようになる。
ユースケース
@user
Slot と@admin
Slot を作成し、権限に応じてレンダリング先を変更する(条件付きルート)- 後述する Intercepting-routes と組み合わせたモーダルの実装
- など
公式ドキュメント: https://ja.next-community-docs.dev/docs/app-router/building-your-application/routing/parallel-routes
Intercepting Routes の概要
Route を横取りする Route 定義。
正しく言うと、現在のページのコンテキストを維持したまま、現在のレイアウト内でルートをロードできる。
モーダルがリンクを持つイメージ。
ソフトナビゲーション時のみ、 Intercepting-routes は機能する。
- 画面リロードのようなハードナビゲーションでは発動しない
Intercepting Routes の使い方
(..)
で始まる命名規約でフォルダを作成する。
Linux のディレクトリ指定とそっくりな挙動。
(.)
は、同じ階層の Segment とマッチ(..)
は、一つ親の Segment とマッチ(..)(..)
は、二つ親の Segment とマッチ(...)
は、ルートapp
ディレクトリの Segment にマッチ
/feed/(..)photo/[id]/page.tsx // /photo/[id]/page.tsxの中身をインターセプト /photo/[id]/page.tsx
Route のメタデータ
静的、および動的メタデータを定義する API が用意されている。
主に SEO の観点で重要となる。
静的・動的メタデータともに、基本的には Metadata
オブジェクトを、任意の階層で Export することになる。
静的メタデータ
固定のメタデータを出力する。
Metadata
オブジェクトを Export するだけ。
import type { Metadata } from 'next'; export const metadata:Metadata = { title:'hoge', description: 'fuga', }
これで、レンダリング後の HTML に、メタデータが書き出される。
動的メタデータ
generateMetadata 関数経由で Metadata オブジェクトを Exportする。
export generateMetadata = async ({params}):Promise<Metadata> => { /** 任意の非同期処理 */ return { title: asyncData.name, description: asyncData.description, } }
メタデータの継承
Next JS では、親Segment から Route Segment までたどり、各メタデータと結合してくれる。
このため、全てのSegment でメタデータを設定する必要はない。
- 親で定義したメタデータに挿入・上書きしていくイメージ
親から継承したメタデータは、 ResolvingMetadata
変数を使用することで参照できる。
2024年05月19日(日)
2.0時間