← コース一覧
Next.js
React をベースにしたフルスタックフレームワーク Next.js を、App Router を前提に学びます。ルーティング・レンダリング・データ取得・API とメタデータの4つのセクションに分け、1レッスン1テーマで読み切れる形で解説します。
公式ドキュメント: Next.js Documentation ↗ルーティング
- 1App Router — フォルダがそのままURLになるNext.js の App Router では、app ディレクトリの中のフォルダ構成がそのまま URL になります。app フォルダ直下が「/」、app/about フォルダが「/about」、app/blog/news フォルダが「/blog/news」に対応します。ルーティングの設定ファイルは一切書きません。
- 2page.tsx — フォルダをページにするフォルダを作っただけでは、まだページとして表示されません。フォルダの中に page.tsx という名前のファイルを置き、コンポーネントを default export すると、それがそのフォルダの URL のページの中身になります。
- 3layout.tsx — 共通UIの共有layout.tsx は、同じフォルダ以下のすべてのページを包む共通の枠です。children という props で各ページの中身を受け取り、ヘッダーやナビゲーションなど共通の UI と一緒に表示します。app/layout.tsx は全ページ共通のルートレイアウトで、html タグと body タグをここに書きます。
- 4Link — ページ間の移動ページ間の移動には、a タグの代わりに next/link の Link コンポーネントを使います。書き方は a タグとほぼ同じで、href に移動先のパスを渡すだけです。
- 5実行可動的ルート — [id] でURLの一部を受け取るブログ記事のように「/blog/1」「/blog/2」と無数にあるページは、フォルダ名を角括弧にした app/blog/[id]/page.tsx という1つのファイルでまとめて作れます。角括弧の部分は何にでもマッチし、その値は params から受け取れます。
- 6ルートグループ — ( ) でURLに出ないフォルダを作るフォルダ名を丸括弧で囲むと、そのフォルダは URL に現れない「整理用のフォルダ」になります。app/(marketing)/about/page.tsx の URL は /marketing/about ではなく /about のままです。
- 7loading.tsx — ページ準備中の表示loading.tsx をフォルダに置くと、同じフォルダの page.tsx の準備が終わるまでの間、代わりにこのファイルの中身が自動で表示されます。スピナーや「読み込み中...」のような軽い UI を default export するだけです。
- 8not-found.tsx — 404ページを作る存在しない URL にアクセスされたときに表示するページは、app/not-found.tsx に書きます。default export したコンポーネントが、どのルートにもマッチしなかったときに自動で表示されます。
- 9error.tsx — 実行時エラーの受け皿ページの処理中に予期しないエラーが起きたとき、画面全体が真っ白になる代わりに代替UIを出すには、app の各フォルダに error.tsx を置きます。これはそのフォルダ以下で起きたエラーを受け止めるエラーバウンダリとして働き、エラー時に default export したコンポーネントが表示されます。loading.tsx・not-found.tsx と並ぶ、もう1つの特別なファイルです。
- 10Proxy(旧Middleware) — リクエスト前の共通処理ページが表示される前に共通の処理を挟みたいときは、プロジェクトのルートに proxy.ts を置きます。export した proxy 関数の中で、受け取ったリクエストを見てリダイレクトしたり、ヘッダーを書き換えたり、別のパスへ書き換え(リライト)たりできます。リクエストが完了する前に割り込める点が特徴です。
レンダリング
- 11Server Components — サーバーでHTMLを作るApp Router のコンポーネントは、何も書かなければサーバー側で実行され、HTML に変換されてからブラウザに届く Server Component になります。これまでのレッスンで書いた page.tsx や layout.tsx は、すべて Server Component です。
- 12Client Components — "use client" でブラウザ上で動かすクリックへの反応や useState など、ブラウザ上で動く機能が必要なときは、ファイルの先頭に "use client" と書いて Client Component にします。この1行で、そのファイルのコンポーネントはブラウザでも実行されるようになります。
- 13組み合わせ方 — ServerからClientへpropsを渡すServer Component と Client Component は組み合わせて使います。基本の形は「ページ(Server)がデータを用意し、操作が必要な部品(Client)に props で渡す」です。Client Component は受け取った props を普通の React コンポーネントと同じように使えます。
データ取得
- 14データ取得 — サーバーでの fetchServer Component は async 関数にでき、その中で直接 await fetch(...) と書いてデータを取得できます。取得したデータをそのまま JSX に渡せるので、useEffect やローディング状態の管理を自分で書く必要がありません。
- 15実行可キャッシュの考え方 — 取得結果を使い回す毎回同じデータを取りに行くのは無駄なので、Next.js は取得結果をキャッシュ(保存)して使い回せます。基本の発想は「保存した結果を一定時間そのまま返し、期限が切れたら取り直す(revalidate)」というものです。データの鮮度がどれくらい重要かで保存時間を決めます。
- 16use cache — v16のキャッシュの仕組みNext.js 16 では Cache Components という仕組みが中心になりました。これを有効(next.config.ts に cacheComponents: true)にすると、デフォルトでは何もキャッシュされず動的に動きます。そのうえで、キャッシュしたい関数やコンポーネントの先頭に "use cache" と書いた箇所だけが保存される、という分かりやすい方式です。以前の「fetch が自動でキャッシュされる」挙動とは逆向きなので、古い記事との違いに注意してください。
- 17Server Actions — フォームからサーバー処理を呼ぶServer Action は、先頭に "use server" と書いた async 関数で、フォームの action 属性に直接渡せます。送信されると関数がサーバー側で実行され、入力内容は FormData として受け取れます。
- 18useActionState — フォームの結果と送信中を表示するServer Action は呼べるようになりましたが、ユーザーには「送信できたのか」「処理中なのか」が見えません。React の useActionState フックを使うと、Server Action の戻り値(結果メッセージなど)と送信中かどうかのフラグを画面に表示できます。
- 19再検証 — 更新後にキャッシュを作り直すデータをキャッシュしていると、Server Action などで内容を更新しても、古いキャッシュが残って画面に反映されないことがあります。そこで、更新後にキャッシュを無効化して作り直すのが「再検証(revalidate)」です。代表的な手段が revalidatePath と revalidateTag で、Server Action や Route Handler の中から呼びます。
API とメタデータ
- 20Route Handlers — APIエンドポイントを作るroute.ts というファイルに GET や POST という名前の関数をエクスポートすると、そのフォルダのパスが API エンドポイントになります。app/api/posts/route.ts なら「/api/posts」に GET や POST リクエストを送れるようになり、レスポンスは NextResponse.json(...) で返します。
- 21metadata — ページのタイトルとSEOブラウザのタブや検索結果に出るページのタイトル・説明文は、page.tsx や layout.tsx から metadata という名前のオブジェクトをエクスポートして設定します。Next.js がこれを読み取り、HTML の head 内の title タグや meta タグを自動で生成してくれます。
- 22next/image — 画像の最適化画像の表示には、img タグの代わりに next/image の Image コンポーネントを使います。src・alt に加えて width と height を指定すると、画像の自動圧縮、画面サイズに合わせた変換、画面に入ってからの遅延読み込みをすべて自動でやってくれます。