diff --git a/apps/docs/content/ja/blog/building-apis-with-nextjs.mdx b/apps/docs/content/ja/blog/building-apis-with-nextjs.mdx new file mode 100644 index 00000000..722810be --- /dev/null +++ b/apps/docs/content/ja/blog/building-apis-with-nextjs.mdx @@ -0,0 +1,396 @@ +--- +source-updated-at: 2025-05-29T18:05:49.000Z +translation-updated-at: 2025-06-02T19:21:36.133Z +title: Next.jsでAPIを構築する +description: Next.jsを使用してAPIを構築する方法について学びます。 +author: + - name: Lee Robinson + image: /static/team/lee.jpg +date: 2025-02-28T14:00:00.507Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/building-apis-with-nextjs/twitter-card.png +--- + +このガイドでは、Next.jsでAPIを構築する方法について説明します。プロジェクトのセットアップ、App RouterとRoute Handlersの理解、複数のHTTPメソッドの処理、動的ルーティングの実装、再利用可能なミドルウェアロジックの作成、専用APIレイヤーを構築するタイミングの決定などをカバーします。 + +* [1. はじめに](#1-はじめに) + * [1.1 Next.jsアプリの作成](#11-nextjsアプリの作成) + * [1.2 App RouterとPages Router](#12-app-routerとpages-router) +* [2. Next.jsでAPIを構築する理由(とタイミング)](#2-nextjsでapiを構築する理由とタイミング) +* [3. Route HandlersでAPIを作成](#3-route-handlersでapiを作成) + * [3.1 基本的なファイル設定](#31-基本的なファイル設定) + * [3.2 1つのファイルで複数のHTTPメソッドを扱う](#32-1つのファイルで複数のhttpメソッドを扱う) +* [4. Web APIとの連携](#4-web-apiとの連携) + * [4.1 Request & Responseの直接使用](#41-request--responseの直接使用) + * [4.2 クエリパラメータ](#42-クエリパラメータ) + * [4.3 ヘッダーとクッキー](#43-ヘッダーとクッキー) +* [5. 動的ルート](#5-動的ルート) +* [6. Next.jsをプロキシまたは転送層として使用](#6-nextjsをプロキシまたは転送層として使用) +* [7. 共有「ミドルウェア」ロジックの構築](#7-共有ミドルウェアロジックの構築) +* [8. デプロイと「SPAモード」の考慮事項](#8-デプロイとspaモードの考慮事項) + * [8.1 標準的なNode.jsデプロイ](#81-標準的なnodejsデプロイ) + * [8.2 SPA/静的エクスポート](#82-spa静的エクスポート) + * [8.3 VercelでのAPIデプロイ](#83-vercelでのapiデプロイ) +* [9. APIエンドポイントを作成しない場合](#9-apiエンドポイントを作成しない場合) +* [10. すべてをまとめる](#10-すべてをまとめる) +* [結論](#結論) +* [よくある質問](#よくある質問) + * [Server Actionsについては?](#server-actionsについては) + * [Route HandlersでTypeScriptは使えますか?](#route-handlersでtypescriptは使えますか) + * [認証のベストプラクティスは?](#認証のベストプラクティスは) + +[1. はじめに](#1-はじめに) +----------------------------------------- + +### [1.1 Next.jsアプリの作成](#11-nextjs-appの作成) + +新規プロジェクトを作成する場合は、次のコマンドを使用します: + +```bash filename="ターミナル" +npx create-next-app@latest --api +``` + +> **注:** `--api` フラグを指定すると、新しいプロジェクトの `app/` フォルダにサンプルの `route.ts` が自動的に含まれ、APIエンドポイントの作成方法が示されます。 + +### [1.2 App RouterとPages Router](#12-app-routerとpages-router) + +* **Pages Router**: 従来、Next.jsはAPIに `pages/api/*` を使用していました。このアプローチはNode.jsのリクエスト/レスポンスオブジェクトとExpress風のAPIに依存していました。 +* **App Router (デフォルト)**: Next.js 13で導入されたApp Routerは、Web標準のRequest/Response APIを完全に採用しています。`pages/api/*` の代わりに、`app/` ディレクトリ内の任意の場所に `route.ts` または `route.js` ファイルを配置できます。 + +> **なぜ切り替えるのか?** App Routerの「Route Handlers」はNode.js固有のAPIではなく[Web Platform Request/Response APIs](https://developer.mozilla.org/ja/docs/Web/API)に依存しているため、学習が簡素化され、異なるツール間で知識を再利用できます。 + +[2. Next.jsでAPIを構築する理由(とタイミング)](#2-nextjsでapiを構築する理由とタイミング) +------------------------------------------------------------------------------------------ + +1. **複数クライアント向けの公開API** + + * Next.jsウェブアプリ、別のモバイルアプリ、またはサードパーティサービスが消費する公開APIを構築できます。例えば、ReactウェブサイトとReact Nativeモバイルアプリの両方から `/api/users` をフェッチする場合などです。 +2. **既存バックエンドへのプロキシ** + + * 外部の[マイクロサービス](https://vercel.com/blog/how-vercel-adopted-microfrontends)を単一のエンドポイントの背後に隠したり統合したりしたい場合があります。Next.js Route Handlersは、別の既存バックエンドへのプロキシまたは中間層として機能できます。例えば、リクエストをインターセプトし、認証を処理し、データを変換してから、アップストリームAPIにリクエストを渡すことができます。 +3. **Webhooksと統合** + + * Stripe、GitHub、Twilioなどからの外部コールバックやWebhookを受信する場合、Route Handlersで処理できます。 +4. **カスタム認証** + + * セッション、トークン、その他の認証ロジックが必要な場合、Next.js API層でクッキーを保存したり、ヘッダーを読み取ったり、適切なデータで応答したりできます。 + +> **注:** 独自のNext.jsアプリのためのサーバーサイドデータフェッチのみが必要で(そのデータを外部と共有する必要がない場合)、Server Componentsがレンダリング中に直接データをフェッチするのに十分であれば、別のAPI層は必要ありません。 + +[3. Route HandlersでAPIを作成](#3-route-handlersでapiを作成) +--------------------------------------------------------------------------------- + +### [3.1 基本的なファイル設定](#31-基本的なファイル設定) + +App Router (`app/`) で、ルートを表すフォルダを作成し、その中に `route.ts` ファイルを配置します。 + +例えば、`/api/users` にエンドポイントを作成する場合: + +``` +app +└── api + └── users + └── route.ts +``` + +### [3.2 1つのファイルで複数のHTTPメソッドを扱う](#32-1つのファイルで複数のhttpメソッドを扱う) + +Pages RouterのAPIルート(単一のデフォルトエクスポートがあった)とは異なり、同じファイルから異なるHTTPメソッドを表す複数の関数をエクスポートできます。 + +```ts filename="app/api/users/route.ts" +export async function GET(request: Request) { + // 例えば、ここでDBからデータをフェッチ + const users = [ + { id: 1, name: 'Alice' }, + { id: 2, name: 'Bob' } + ]; + return new Response(JSON.stringify(users), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); +} + +export async function POST(request: Request) { + // リクエストボディを解析 + const body = await request.json(); + const { name } = body; + + // 例: DBに新しいユーザーを挿入 + const newUser = { id: Date.now(), name }; + + return new Response(JSON.stringify(newUser), { + status: 201, + headers: { 'Content-Type': 'application/json' } + }); +} +``` + +これで、`/api/users` にGETリクエストを送信するとユーザーリストが返され、同じURLにPOSTリクエストを送信すると新しいユーザーが追加されます。 + +[4. Web APIとの連携](#4-web-apiとの連携) +----------------------------------------------------- + +### [4.1 Request & Responseの直接使用](#41-request--responseの直接使用) + +デフォルトでは、Route Handlerメソッド(`GET`、`POST`など)は標準の[Request](https://developer.mozilla.org/ja/docs/Web/API/Request)オブジェクトを受け取り、標準の[Response](https://developer.mozilla.org/ja/docs/Web/API/Response)オブジェクトを返す必要があります。 + +### [4.2 クエリパラメータ](#42-クエリパラメータ) + +```ts filename="app/api/search/route.ts" +import { NextRequest } from 'next/server'; + +export function GET(request: NextRequest) { + const searchParams = request.nextUrl.searchParams; + const query = searchParams.get('query'); // 例: `/api/search?query=hello` + + return new Response( + JSON.stringify({ result: `検索クエリ: ${query}` }), + { + headers: { 'Content-Type': 'application/json' }, + }, + ); +} +``` + +### [4.3 ヘッダーとクッキー](#43-ヘッダーとクッキー) + +```ts filename="app/api/auth/route.ts" +import { NextRequest } from 'next/server'; +import { cookies, headers } from 'next/headers'; + +export async function GET(request: NextRequest) { + // 1. 'next/headers'ヘルパーの使用 + const cookieStore = await cookies(); + const token = cookieStore.get('token'); + + const headersList = await headers(); + const referer = headersList.get('referer'); + + // 2. 標準Web APIの使用 + const userAgent = request.headers.get('user-agent'); + + return new Response(JSON.stringify({ token, referer, userAgent }), { + headers: { 'Content-Type': 'application/json' }, + }); +} +``` + +`cookies()` と `headers()` 関数は、Next.jsの他のサーバーサイドコードで共有ロジックを再利用する場合に便利です。Next.jsはまた、基本のWeb APIを拡張した `NextRequest` と `NextResponse` も提供します。 + +[5. 動的ルート](#5-動的ルート) +--------------------------------------- + +動的パス(例: `/api/users/:id`)を作成するには、フォルダ構造で**動的セグメント**を使用します: + +``` +app +└── api + └── users + └── [id] + └── route.ts +``` + +このファイルは `/api/users/123` のようなURLに対応し、`123` がパラメータとしてキャプチャされます。 + +```ts filename="app/api/users/[id]/route.ts" +import { NextRequest } from 'next/server'; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ id: string }> }, +) { + const id = (await params).id; + // 例: ID `id` のユーザーをDBからクエリ + return new Response(JSON.stringify({ id, name: `ユーザー ${id}` }), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); +} + +export async function DELETE( + request: NextRequest, + { params }: { params: Promise<{ id: string }> }, +) { + const id = (await params).id; + // 例: DBからID `id` のユーザーを削除 + return new Response(null, { status: 204 }); +} +``` + +ここで、`params.id` が動的セグメントを提供します。 + +[6. Next.jsをプロキシまたは転送層として使用](#6-nextjsをプロキシまたは転送層として使用) +-------------------------------------------------------------------------------------------------- + +一般的なシナリオは、既存のバックエンドサービスを**プロキシ**することです。リモートサーバーやバックエンドに送信する前に、リクエストを認証したり、ログを記録したり、データを変換したりできます: + +```ts filename="app/api/external/route.ts" +import { NextRequest } from 'next/server'; + +export async function GET(request: NextRequest) { + const response = await fetch('https://example.com/api/data', { + // オプション: ヘッダーの転送、認証トークンの追加など + headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }, + }); + + // レスポンスを変換または転送 + const data = await response.json(); + const transformed = { ...data, source: 'nextjs経由でプロキシ' }; + + return new Response(JSON.stringify(transformed), { + headers: { 'Content-Type': 'application/json' }, + }); +} +``` + +これでクライアントは `/api/external` を呼び出すだけでよく、Next.jsが残りを処理します。これは「Backend for Frontend(BFF)」とも呼ばれます。 + +[7. 共有「ミドルウェア」ロジックの構築](#7-共有ミドルウェアロジックの構築) +----------------------------------------------------------------------------- + +複数のRoute Handlerに同じロジック(認証チェック、ロギングなど)を適用したい場合、ハンドラーをラップする再利用可能な関数を作成できます: + +```ts filename="lib/with-auth.ts" +import { NextRequest } from 'next/server'; + +type Handler = (req: NextRequest, context?: any) => Promise; + +export function withAuth(handler: Handler): Handler { + return async (req, context) => { + const token = req.cookies.get('token')?.value; + if (!token) { + return new Response(JSON.stringify({ error: '認証されていません' }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }); + } + + // 認証済みの場合、元のハンドラーを呼び出し + return handler(req, context); + }; +} +``` + +Route Handlerでは: + +```ts filename="app/api/secret/route.ts" +import { NextRequest } from 'next/server'; +import { withAuth } from '@/lib/with-auth'; + +async function secretGET(request: NextRequest) { + return new Response(JSON.stringify({ secret: 'ここにドラゴンがいます' }), { + headers: { 'Content-Type': 'application/json' }, + }); +} + +export const GET = withAuth(secretGET); +``` + +[8. デプロイと「SPAモード」の考慮事項](#8-デプロイとspaモードの考慮事項) +----------------------------------------------------------------------------------------- + +### [8.1 標準的なNode.jsデプロイ](#81-標準的なnodejsデプロイ) + +標準のNext.jsサーバーデプロイ(next startを使用)では、Route Handlers、Server Components、Middlewareなどの機能を使用でき、動的なリクエスト時情報を活用できます。 + +追加の設定は不要です。詳細は[デプロイ](/docs/app/building-your-application/deploying)を参照してください。 + +### [8.2 SPA/静的エクスポート](#82-spa静的エクスポート) + +Next.jsはまた、サイト全体を[静的シングルページアプリケーション(SPA)](/docs/app/building-your-application/upgrading/single-page-applications)として出力することをサポートしています。 + +次の設定で有効にできます: + +```ts filename="next.config.ts" +import type { NextConfig } from 'next'; + +const nextConfig: NextConfig = { + output: 'export', +}; + +export default nextConfig; +``` + +**静的エクスポートモード**では、Next.jsは純粋な静的HTML、CSS、JSを生成します。**サーバーサイドコード(APIエンドポイントなど)は実行できません**。APIが必要な場合は、別途ホストする(スタンドアロンのNode.jsサーバーなど)必要があります。 + +> **注:** +> +> * **GET Route Handlers** は、動的リクエストデータに依存しない場合[静的エクスポート可能](/docs/app/building-your-application/deploying/static-exports#route-handlers)です。これらはoutフォルダ内の静的ファイルになります。 +> * **他のすべてのサーバー機能**(動的リクエスト、クッキーの書き換えなど)は、純粋なSPAエクスポートでは**サポートされていません**。 + +### [8.3 VercelでのAPIデプロイ](#83-deploying-apis-on-vercel) + +Next.jsアプリケーションをVercelにデプロイする場合、[APIデプロイガイド](https://vercel.com/guides/hosting-backend-apis)を参照してください。これには、Vercel Firewallを通じた[プログラムによるレート制限](https://vercel.com/docs/security/vercel-waf/rate-limiting-sdk)などのVercel機能も含まれます。Vercelはまた、APIアプローチで一般的に必要とされる[Cron Jobs](https://vercel.com/docs/cron-jobs/manage-cron-jobs)も提供しています。 + +[9\. APIエンドポイント作成をスキップする場合](#9-when-to-skip-creating-an-api-endpoint) +------------------------------------------------------------------------------------- + +App Routerの**React Server Components**を使用すると、公開エンドポイントを公開せずにサーバー上で直接データを取得できます: + +```tsx filename="app/users/page.tsx" +// (Server Component) +export default async function UsersPage() { + // このfetchはサーバー上で実行されます(クライアントサイドのコードは不要) + const res = await fetch('https://api.example.com/users'); + const data = await res.json(); + + return ( +
+

ユーザー一覧

+ +
+ ); +} +``` + +データがNext.jsアプリ内でのみ使用される場合、公開APIはまったく必要ないかもしれません。 + +[10\. 全体のまとめ](#10-putting-it-all-together) +----------------------------------------------------------- + +1. **新しいNext.jsプロジェクトを作成**: `npx create-next-app@latest --api` +2. **Route Handlersを追加**: `app/`ディレクトリ内に作成(例: `app/api/users/route.ts`) +3. **HTTPメソッドをエクスポート**: 同じファイル内で`GET`、`POST`、`PUT`、`DELETE`などを定義 +4. **Web標準APIを使用**: `Request`オブジェクトを操作し、`Response`を返す +5. **公開APIを構築**: 他のクライアントがデータを利用する必要がある場合、またはバックエンドサービスをプロキシする場合 +6. **新しいAPIルートをフェッチ**: クライアント側から(例: Client Component内または`fetch('/api/...')`で) +7. **API作成を完全にスキップ**: Server Componentで直接データを取得できる場合 +8. **共有「ミドルウェア」パターンを追加**: 認証やその他の繰り返しロジック用(例: `withAuth()`) +9. **デプロイ**: サーバー機能が必要な場合はNode.js対応環境へ、静的SPAのみの場合は静的エクスポート + +[結論](#conclusion) +------------------------- + +Next.jsの**App Router**と**Route Handlers**を使用すると、**Webプラットフォーム**を直接活用した柔軟でモダンなAPI構築方法が得られます。これで次のことが可能です: + +* **完全な公開APIを作成**: Web、モバイル、サードパーティのクライアントで共有 +* **プロキシ**: 既存の外部サービスへの呼び出しをカスタマイズ +* **再利用可能な「ミドルウェア」層を実装**: 認証、ロギング、その他の繰り返しロジック用 +* **動的ルーティング**: `[id]`セグメントフォルダ構造を使用してリクエストをルーティング + +[よくある質問](#frequently-asked-questions) +--------------------------------------------------------- + +### [Server Actionsについては?](#what-about-server-actions) + +[Server Actions](/docs/app/building-your-application/data-fetching/server-actions-and-mutations)は、クライアントから呼び出せる自動生成された`POST` APIルートと考えることができます。 + +これらはデータの作成、更新、削除などの変更操作用に設計されています。Server Actionは、定義されたAPIルートへの明示的な`fetch`を行うのではなく、通常のJavaScript関数のように呼び出します。 + +ネットワークリクエストは発生しますが、明示的に管理する必要はありません。URLパスは自動生成され、[暗号化](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#security)されているため、ブラウザで`/api/users`のようなルートに手動でアクセスすることはできません。 + +Server Actionsを使用しつつ公開APIも提供する予定の場合は、コアロジックを[Data Access Layer](/blog/security-nextjs-server-components-actions)に移動し、Server ActionとAPIルートの両方から同じロジックを呼び出すことを推奨します。 + +### [Route HandlersでTypeScriptは使えますか?](#can-i-use-typescript-with-route-handlers) + +はい、Route HandlersでTypeScriptを使用できます。例えば、`route`ファイルで`Request`と`Response`の型を定義できます。 + +[Next.jsでのTypeScript使用](/docs/app/api-reference/config/typescript)について詳しく学べます。 + +### [認証のベストプラクティスは?](#what-are-the-best-practices-for-authentication) + +[認証ドキュメント](/docs/app/building-your-application/authentication)で詳しく説明しています。 diff --git a/apps/docs/content/ja/blog/composable-caching.mdx b/apps/docs/content/ja/blog/composable-caching.mdx new file mode 100644 index 00000000..6c907b59 --- /dev/null +++ b/apps/docs/content/ja/blog/composable-caching.mdx @@ -0,0 +1,202 @@ +--- +source-updated-at: 2025-05-29T18:05:49.000Z +translation-updated-at: 2025-06-03T22:46:51.057Z +title: Next.js におけるコンポーザブルなキャッシュ +description: キャッシュ機能 'use cache' の API 設計と利点について学びます +author: + - name: Lee Robinson + image: /static/team/lee.jpg +date: 2025-01-03T14:00:00.507Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/composable-caching/twitter-card.png +--- + +Next.js 向けにシンプルで強力なキャッシュモデルの開発を進めています。前回の投稿では、[キャッシュとの歩み](/blog/our-journey-with-caching)と `'use cache'` ディレクティブに至った経緯についてお話ししました。 + +この投稿では、`'use cache'` の API 設計と利点について説明します。 + +[`'use cache'` とは?](#what-is-use-cache) +-------------------------------------------- + +`'use cache'` は、必要に応じてデータやコンポーネントをキャッシュすることでアプリケーションを高速化します。 + +これは JavaScript の「ディレクティブ」—コードに追加する文字列リテラル—であり、Next.js コンパイラに異なる「境界」に入ることを伝えます。例えば、サーバーからクライアントへの移行などです。 + +これは React の `'use client'` や `'use server'` といったディレクティブと同様の考え方です。ディレクティブはコードの実行場所を定義するコンパイラ指示であり、フレームワークが個々の要素を最適化・調整できるようにします。 + +[動作原理](#how-does-it-work) +-------------------------------------- + +簡単な例から見ていきましょう: + +``` +async function getUser(id) { + 'use cache'; + let res = await fetch(`https://api.vercel.app/user/${id}`); + return res.json(); +} +``` + +内部的には、Next.js は `'use cache'` ディレクティブによりこのコードをサーバー関数に変換します。コンパイル時に、このキャッシュエントリの「依存関係」が検出され、キャッシュキーの一部として使用されます。 + +例えば、`id` はキャッシュキーの一部になります。`getUser(1)` を複数回呼び出すと、キャッシュされたサーバー関数からメモ化された出力が返されます。この値を変更すると、キャッシュに新しいエントリが作成されます。 + +[クロージャ](https://v0.dev/chat/5kD47RIecQK?b=b_rCP4CvfbFFW)を使用したサーバーコンポーネントでのキャッシュ関数の使用例を見てみましょう。 + +``` +function Profile({ id }) { + async function getNotifications(index, limit) { + 'use cache'; + return await db + .select() + .from(notifications) + .limit(limit) + .offset(index) + .where(eq(notifications.userId, id)); + } + + return ; +} +``` + +この例はより複雑です。キャッシュキーの一部となるべきすべての依存関係を見つけられますか? + +引数 `index` と `limit` は理解しやすい—これらの値が変更されると、通知の異なるスライスを選択します。しかし、ユーザー `id` はどうでしょうか?その値は親コンポーネントから来ています。 + +コンパイラは `getNotifications` が `id` にも依存していることを理解でき、その値は自動的にキャッシュキーに含まれます。これにより、キャッシュキーにおける依存関係の不足や誤りによるキャッシュ問題の全カテゴリを防ぎます。 + +[キャッシュ関数を使用しない理由](#why-not-use-a-cache-function) +-------------------------------------------------------------- + +前の例を再考しましょう。ディレクティブの代わりに `cache()` 関数を使用できないでしょうか? + +``` +function Profile({ id }) { + async function getNotifications(index, limit) { + return await cache(async () => { + return await db + .select() + .from(notifications) + .limit(limit) + .offset(index) + // おっと! id をキャッシュキーに含める場所は? + .where(eq(notifications.userId, id)); + }); + } + + return ; +} +``` + +`cache()` 関数はクロージャを調べて `id` の値をキャッシュキーの一部にすべきか判断できません。手動で `id` をキーの一部として指定する必要があります。これを忘れたり、誤ったりすると、キャッシュの衝突や古いデータのリスクが生じます。 + +クロージャはあらゆる種類のローカル変数を捕捉できます。単純なアプローチでは、意図しない変数が誤って含まれたり(または除外されたり)する可能性があります。これにより、誤ったデータがキャッシュされたり、機密情報がキャッシュキーに漏洩してキャッシュ汚染のリスクが生じたりする可能性があります。 + +`'use cache'` はコンパイラにクロージャを安全に扱い、キャッシュキーを正しく生成するための十分なコンテキストを提供します。`cache()` のようなランタイムのみのソリューションでは、すべてを手動で行う必要があり、ミスを犯しやすくなります。対照的に、ディレクティブは静的に分析でき、すべての依存関係を確実に処理できます。 + +[シリアライズ不可能な入力値の扱い](#how-are-non-serialized-input-values-handled) +-------------------------------------------------------------------------------------------- + +キャッシュする入力値には2種類あります: + +* **シリアライズ可能**: ここで「シリアライズ可能」とは、意味を失うことなく安定した文字列ベースの形式に変換できる入力を指します。多くの人が最初に `JSON.stringify` を思い浮かべますが、実際には React のシリアライゼーション(例えばサーバーコンポーネント経由)を使用して、プロミス、循環データ構造、その他の複雑なオブジェクトなど、より広範な入力を処理します。これはプレーンな JSON ができることを超えています。 +* **シリアライズ不可能**: これらの入力はキャッシュキーの一部ではありません。これらの値をキャッシュしようとすると、サーバー「参照」を返します。この参照は Next.js によってランタイム時に元の値に復元されます。 + +`id` をキャッシュキーに含めることを覚えていたとしましょう: + +``` +await cache(async () => { + return await db + .select() + .from(notifications) + .limit(limit) + .offset(index) + .where(eq(notifications.userId, id)); +}, [id, index, limit]); +``` + +これは入力値がシリアライズ可能な場合に機能します。しかし、`id` が React 要素やより複雑な値であった場合、入力キーを手動でシリアライズする必要があります。`id` プロップに基づいて現在のユーザーを取得するサーバーコンポーネントを考えてみましょう: + +``` +async function Profile({ id, children }) { + 'use cache'; + const user = await getUser(id); + + return ( + <> +

{user.name}

+ {/* children を変更してもキャッシュが壊れない...なぜ? */} + {children} + + ); +} +``` + +この動作を順を追って説明します: + +1. コンパイル中、Next.js は `'use cache'` ディレクティブを認識し、キャッシュをサポートする特別なサーバー関数を作成するためにコードを変換します。コンパイル時にキャッシュが行われるわけではなく、Next.js はランタイムキャッシュに必要なメカニズムを設定しています。 +2. コードが「キャッシュ関数」を呼び出すと、Next.js は関数の引数をシリアライズします。JSX のように直接シリアライズできないものは、「参照」プレースホルダーに置き換えられます。 +3. Next.js は指定されたシリアライズされた引数に対してキャッシュされた結果が存在するかチェックします。結果が見つからない場合、関数はキャッシュする新しい値を計算します。 +4. 関数が終了すると、戻り値がシリアライズされます。戻り値のシリアライズ不可能な部分は参照に戻されます。 +5. キャッシュ関数を呼び出したコードは出力をデシリアライズし、参照を評価します。これにより、Next.js は参照を実際のオブジェクトや値と交換でき、`children` のようなシリアライズ不可能な入力は元の、キャッシュされていない値を保持できます。 + +これは、`` コンポーネントだけを安全にキャッシュし、子をキャッシュしないことを意味します。後続のレンダリングでは、`getUser()` は再度呼び出されません。`children` の値は動的であるか、異なるキャッシュ寿命を持つ別個にキャッシュされた要素である可能性があります。これがコンポーザブルなキャッシュです。 + +[これは見覚えが...](#this-seems-familiar) +-------------------------------------------- + +「サーバーとクライアントのコンポジションと同じモデルのように感じる」と思ったなら、まったく正しいです。これは時々「ドーナツ」パターンと呼ばれます: + +* **外側**の部分はデータ取得や重いロジックを処理するサーバーコンポーネント +* 中央の**穴**はインタラクティブ性を持つ可能性のある子コンポーネント + +```tsx filename="app/page.tsx" +export default function Page() { + return ( + + {/* クライアントへの穴を作成 */} + + + ); +} +``` + +`'use cache'` も同じです。ドーナツは外側のコンポーネントのキャッシュされた値で、穴はランタイム時に埋められる参照です。これが `children` を変更してもキャッシュされた出力全体が無効化されない理由です。子は後で埋められる単なる参照です。 + +[タグ付けと無効化については?](#what-about-tagging-and-invalidation) +---------------------------------------------------------------------------- + +キャッシュの寿命はさまざまな[プロファイル](/docs/app/api-reference/functions/cacheLife)で定義できます。デフォルトのプロファイルセットが含まれていますが、必要に応じてカスタム値を定義できます。 + +``` +async function getUser(id) { + 'use cache'; + cacheLife('hours'); + let res = await fetch(`https://api.vercel.app/user/${id}`); + return res.json(); +} +``` + +特定のキャッシュエントリを無効化するには、[キャッシュにタグを付け](/docs/app/api-reference/functions/cacheTag)、`revalidateTag()` を呼び出します。強力なパターンの1つは、データ(例えば CMS から)を取得した後にキャッシュにタグを付けられることです: + +``` +async function getPost(postId) { + 'use cache'; + let res = await fetch(`https://api.vercel.app/blog/${postId}`); + let data = await res.json(); + cacheTag(postId, data.authorId); + return data; +} +``` + +[シンプルで強力](#simple-and-powerful) +------------------------------------------- + +`'use cache'` の目標は、キャッシュロジックの作成をシンプルかつ強力にすることです。 + +* **シンプル**: ローカルな推論でキャッシュエントリを作成できます。キャッシュキーエントリの忘却やコードベースの他の部分への意図しない変更といったグローバルな副作用を心配する必要はありません。 +* **強力**: 静的に分析可能なコードだけでなく、より多くのものをキャッシュできます。例えば、ランタイム時に変更される可能性がある値でも、評価後の出力結果をキャッシュしたい場合があります。 + +`'use cache` は Next.js 内部ではまだ**実験的**です。テストする際の早期フィードバックをお待ちしています。 + +[ドキュメントで詳細を確認](/docs/app/api-reference/directives/use-cache)。 \ No newline at end of file diff --git a/apps/docs/content/ja/blog/create-next-app.mdx b/apps/docs/content/ja/blog/create-next-app.mdx new file mode 100644 index 00000000..0f36bb96 --- /dev/null +++ b/apps/docs/content/ja/blog/create-next-app.mdx @@ -0,0 +1,38 @@ +--- +source-updated-at: 2025-05-29T18:05:49.000Z +translation-updated-at: 2025-06-02T19:18:20.141Z +title: Create Next App の紹介 +description: >- + 本日、新しい Create Next App を紹介できることを嬉しく思います。Create Next App は、1つのコマンドで Next.js を利用したモダンな React アプリケーションをセットアップします。 +author: + - name: Joe Haddad + image: /static/team/timer.jpg + - name: Tim Neutkens + image: /static/team/tim.jpg +date: 2019-10-09T15:02:30.543Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/create-next-app/twitter-card.png +--- + +本日、新しい Create Next App を紹介できることを嬉しく思います。 + +Create Next App は、1つのコマンドで Next.js を利用したモダンな React アプリケーションをセットアップします。 + +開始するには、次のコマンドを実行するだけです: + +```bash filename="Terminal" +npx create-next-app +``` + +Create Next App は、最高の開発者体験を提供するためにゼロから再構築されました: + +* **インタラクティブな体験**: 引数なしで `npx create-next-app` を実行すると、プロジェクトセットアップをガイドするインタラクティブな体験が開始されます。 +* **依存関係ゼロ**: プロジェクトの初期化はわずか**1秒**で可能です。Create Next App には依存関係がなく、**たったの 604 kB** でインストールされます。最適化前の以前のバージョンは **5.38 MB** でした。これは **4.7 MB 以上**の削減です! +* **オフラインサポート**: Create Next App は自動的にオフライン状態を検出し、ローカルのパッケージキャッシュを使用してプロジェクトをブートストラップします。 +* **新しいデフォルトプロジェクトテンプレート**: Create Next App は、モダンな Next.js アプリケーション向けに設計された新しいプロジェクトテンプレートを使用します。Create Next App は Next.js 本体と共にメンテナンスされるため、このテンプレートは常に最新の Next.js バージョンに対応しています! +* **サンプルプロジェクトのサポート**: Create Next App は [Next.js サンプル集](https://github.com/vercel/next.js/tree/canary/examples) のサンプルを使用してアプリケーションをブートストラップできます(例: `npx create-next-app --example api-routes`)。 +* **テスト済み**: このパッケージは Next.js モノレポの一部であり、Next.js 自体と同じ統合テストスイートを使用してテストされています。これにより、各リリースで期待通りに動作することが保証されます。 + +Create Next App は以前は [コミュニティでメンテナンス](https://open.segment.com/create-next-app/) されていましたが、Next.js の第一印象を管理することが重要だと感じました。特に [Next.js サンプル集](https://github.com/vercel/next.js/tree/canary/examples) で推奨しているためです。 + +[Segment](https://segment.com/) と協力してパッケージの所有権を移管し、特に [Fouad Matin](https://twitter.com/fouadmatin) 氏によるこれまでの管理に非常に感謝しています。 \ No newline at end of file diff --git a/apps/docs/content/ja/blog/incremental-adoption.mdx b/apps/docs/content/ja/blog/incremental-adoption.mdx new file mode 100644 index 00000000..9d3bd073 --- /dev/null +++ b/apps/docs/content/ja/blog/incremental-adoption.mdx @@ -0,0 +1,109 @@ +--- +source-updated-at: 2025-05-29T18:05:49.000Z +translation-updated-at: 2025-06-02T19:19:03.000Z +title: Next.js の段階的な導入 +description: >- + Next.js を開発ワークフローに段階的に導入するためのさまざまな戦略について学びましょう。 +author: + - name: Lee Robinson + image: /static/team/lee.jpg +date: 2020-11-18T14:00:00.507Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/incremental-adoption/twitter-card.png +--- + +[Next.js](https://nextjs.org/) は段階的な導入を想定して設計されています。Next.js では、既存のコードをそのまま使いながら、必要な分だけ React を追加できます。小規模から始めて徐々にページを追加していくことで、完全な書き換えを避けつつ機能開発を進めることが可能です。 + +多くの企業は、コスト削減、開発者の生産性向上、顧客への最高の体験提供のために技術スタックの近代化を必要としています。コンポーネント駆動開発は、現代のコードベースのデプロイ速度と再利用性を大幅に向上させました。 + +そして月間 [800万ダウンロード](https://www.npmtrends.com/react) を超える React は、開発者にとって主要なコンポーネント駆動の選択肢です。プロダクション向け React フレームワークである Next.js は、React を段階的に導入することを可能にします。 + +[動機](#motivation) +------------------------- + +モバイル中心の世界において、[Core Web Vitals](/analytics) の改善と追跡は成功に不可欠です。顧客は世界中に分散しており、インターネット速度も様々です。ページの読み込みやアクションの完了にかかる時間が1秒(または1ミリ秒)増えるごとに、売上、インプレッション、コンバージョンに影響が出る可能性があります。 + +技術スタックを近代化する際、次のような課題に直面するかもしれません: + +* アプリケーションに何年も前のレガシーコードがあり、理解が難しく、完全に書き換えるには数年(そして数百万ドル)かかる +* アプリケーションのサイズと複雑さが増すにつれてページ読み込み時間が増加し続け、単純なマーケティングページでも最も複雑なページと同じくらい遅い +* 開発チームを拡大しようとしているが、既存のコードベースに開発者を追加する際に問題が発生している +* 古い CI/CD と DevOps プロセスがあり、開発者の生産性が低下し、新しい変更を安全かつ確実に展開することが困難 +* アプリケーションがモバイルデバイスに対応しておらず、グローバルなページスタイルを更新しようとするとアプリケーションの他の部分が壊れてしまう + +何かをする必要があるとわかっていても、[どこから始めればよいか](https://www.psychologytoday.com/us/blog/mindfully-present-fully-alive/201804/the-only-way-eat-elephant) を理解するのは圧倒的かもしれません。Next.js を段階的に導入することで、上記の問題を解決し始め、アプリケーションを変革できます。既存の技術スタックに Next.js を導入するためのいくつかの戦略について説明しましょう。 + +[戦略](#strategies) +------------------------- + +### [サブパス](#subpath) + +最初の戦略は、サーバーまたはプロキシを設定して、特定のサブパス配下のすべてを Next.js アプリに向ける方法です。例えば、既存のウェブサイトが `example.com` にあり、`example.com/store` が Next.js の e コマースストアを提供するようにプロキシを設定できます。 + +[`basePath`](/docs/pages/api-reference/next-config-js/basePath) を使用すると、Next.js アプリケーションのアセットとリンクを新しいサブパス `/store` で自動的に動作するように設定できます。Next.js では各ページが [独立したルート](/docs/pages/building-your-application/routing) であるため、`pages/products.js` のようなページはアプリケーション内で `example.com/store/products` にルーティングされます。 + +```js filename="next.config.js" +module.exports = { + basePath: '/store', +}; +``` + +`basePath` の詳細については、[ドキュメント](/docs/pages/api-reference/next-config-js/basePath) をご覧ください。 + +(**注:** この機能は Next.js 9.5 以降で導入されました。古いバージョンの Next.js を使用している場合は、試す前にアップグレードしてください。) + +### [リライト](#rewrites) + +2番目の戦略は、ドメインのルート URL を指す新しい Next.js アプリを作成することです。その後、`next.config.js` 内で [`rewrites`](/docs/pages/api-reference/next-config-js/rewrites) を使用して、一部のサブパスを既存のアプリにプロキシできます。 + +例えば、`example.com` から提供される Next.js アプリを次の `next.config.js` で作成したとします。これで、この Next.js アプリに追加したページ(例えば `pages/about.js` を追加した場合は `/about`)へのリクエストは Next.js によって処理され、他のルート(例えば `/dashboard`)へのリクエストは `proxy.example.com` にプロキシされます。 + +```js filename="next.config.js" +module.exports = { + async rewrites() { + return [ + // プロキシを試みる前にすべてのページ/静的ファイルを + // チェックするために、no-op リライトを定義する必要があります + { + source: '/:path*', + destination: '/:path*', + }, + { + source: '/:path*', + destination: `https://proxy.example.com/:path*`, + }, + ]; + }, +}; +``` + +リライトの詳細については、[ドキュメント](/docs/pages/api-reference/next-config-js/rewrites) をご覧ください。 + +### [モノレポとサブドメインを使ったマイクロフロントエンド](#micro-frontends-with-monorepos-and-subdomains) + +Next.js と [Vercel](https://vercel.com) を使えば、[マイクロフロントエンド](https://martinfowler.com/articles/micro-frontends.html) の採用と [モノレポ](https://vercel.com/blog/monorepos) としてのデプロイが簡単になります。これにより、[サブドメイン](https://ja.wikipedia.org/wiki/サブドメイン) を使用して新しいアプリケーションを段階的に導入できます。マイクロフロントエンドの利点: + +* より小さく、凝集度が高く、保守しやすいコードベース +* 分離された自律的なチームによる、よりスケーラブルな組織 +* フロントエンドの一部を段階的にアップグレード、更新、または書き換える能力 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/incremental-adoption/light-arch.png) + +> Vercel にデプロイされたモノレポのアーキテクチャ + +モノレポをセットアップしたら、通常通り Git リポジトリに変更をプッシュすると、接続した Vercel プロジェクトにコミットがデプロイされます。時代遅れの CI/CD プロセスに別れを告げましょう。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/incremental-adoption/dark-comment.png) + +> Git 統合によって提供されるデプロイメント URL の例 + +[結論](#conclusion) +------------------------- + +Next.js は既存の技術スタックへの段階的な導入を想定して設計されています。Vercel プラットフォームは、GitHub、GitLab、Bitbucket とシームレスに統合することで、すべてのコード変更に対してデプロイプレビューを提供し、共同作業を容易にします。 + +* [Fast Refresh](/docs/architecture/fast-refresh) でローカルでの変更を即座にプレビューし、開発者の生産性を向上 +* 変更をプッシュして [ブランチプレビュー](https://vercel.com/github) を作成し、ステークホルダーとの共同作業を最適化 +* PR をマージして [Vercel](https://vercel.com) に本番環境へデプロイ。複雑な DevOps は不要 + +詳細については、[サブパス](/docs/pages/api-reference/next-config-js/basePath) と [リライト](/docs/pages/api-reference/next-config-js/rewrites) のドキュメントを読むか、[マイクロフロントエンドの例をデプロイ](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-zones) してください。 \ No newline at end of file diff --git a/apps/docs/content/ja/blog/june-2023-update.mdx b/apps/docs/content/ja/blog/june-2023-update.mdx new file mode 100644 index 00000000..77505eee --- /dev/null +++ b/apps/docs/content/ja/blog/june-2023-update.mdx @@ -0,0 +1,147 @@ +--- +source-updated-at: 2025-05-29T18:05:49.000Z +translation-updated-at: 2025-06-02T19:19:58.856Z +title: Next.js App Router アップデート +description: >- + Next.jsチームは今後数ヶ月間、パフォーマンス、安定性、開発者体験の向上に注力しています。 +author: + - name: Delba de Oliveira + image: /static/team/delba.jpg + - name: Lee Robinson + image: /static/team/lee.jpg +date: 2023-06-22T14:00:00.507Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/june-2023-update/twitter-card.png +--- + +App RouterはNext.jsの未来のための新しい基盤ですが、体験をさらに向上させる機会があることも認識しています。現在の優先事項について最新情報をお伝えします。 + +今後のNext.jsリリースでは、以下の領域に焦点を当てています: + +* **パフォーマンスの向上** +* **安定性の向上** +* **開発者教育の改善** + +[App Routerについて](#the-app-router) +--------------------------------- + +まず、App Routerがどのように設計されたかの背景を説明することが役立つでしょう。 + +### [Pages Routerを超えてReactと連携する](#growing-beyond-the-pages-router-by-aligning-with-react) + +Next.jsの採用が増え、大規模なアプリケーションが構築されるにつれ、コミュニティからのフィードバックを受け、Pages Routerの限界に達し始めている領域を特定しました。 + +特に、Next.js Pages Routerはストリーミング向けに設計されていませんでした。これは現代のReactにおける基盤的なプリミティブであり、私たちが直面していた制限に対処し、Next.jsの長期的なビジョンを実現するのに役立ちます。 + +データ取得、アセット読み込み、ページメタデータのためのストリーミング対応フレームワークAPIを作成し、Reactの新しいプリミティブを活用するには、Next.jsのコアアーキテクチャに大きな変更が必要でした。 + +私たちは[最新のReact並行機能](https://react.dev/blog/2023/05/03/react-canaries)(サーバーコンポーネント、Suspenseなど)の上に構築する機会を得ました。これらは[ストリーミングアーキテクチャ向けに設計](https://github.com/reactwg/react-18/discussions/37)されています。 + +### [段階的採用は必須](#incremental-adoption-is-non-negotiable) + +コミュニティがNext.jsの最新バージョンに更新するためにアプリケーション全体を一から再構築する必要がないようにしたいと考えました。アプリケーションを時間をかけて進化させるには、段階的採用が最良の戦略だと考えています。 + +* **ルートごとの段階的移行**: アプリケーションを大きく書き換えることなく、単一のルートをApp Routerに移行し、自分のペースで新機能を活用できます。[段階的採用ガイド](/docs/app/building-your-application/upgrading/app-router-migration)を参照するか、[チュートリアル動画](https://www.youtube.com/watch?v=YQMSietiFm0)をご覧ください。 +* **簡単にロールバック可能**: App Routerのパフォーマンスや開発者体験に満足できない場合、特定のルートに対してPages Routerに簡単に戻すことができます。 + +段階的採用をさらに簡単にする機会を探っています。 + +### [安定化への道](#road-to-stability) + +Next.js App Routerの構築を1年以上前に開始し、それ以来、新機能と改善を着実にリリースしてきました。 + +* **初期発表**: 同年5月に、ルーティングとレイアウトをより柔軟にする計画を概説する[RFCをリリース](/blog/layouts-rfc)しました。 +* **早期ベータ版**: Next.js 13でApp Routerの最初のバージョンをリリースし、コミュニティが試用して早期フィードバックを提供できるようにしました。 +* **安定版API**: フィードバックを受け、コアAPIの最終化に注力しました。13.4で、App RouterのコアAPIを安定版としてマークし、より広範な採用に備えました。 + +[現在の焦点](#our-current-focus) +--------------------------------------- + +安定版のマーキングは、コアAPIが確定し、書き換えが必要な大きな破壊的変更が行われないことをコミュニティに伝えるものでした。 + +それ以来、多くの貴重なフィードバックを受け、採用の増加に伴い、バグやさらなる改善の機会が明らかになりました。 + +App Routerの使用体験には**まだ満足していない**ことをお伝えしたいと思います。これは今後の最優先事項です。では、この体験を改善するために行っている作業についてお話ししましょう。 + +### [パフォーマンスの向上](#improving-performance) + +今後数ヶ月間、ローカルでの反復速度、本番ビルド時間、サーバーレスパフォーマンスの3つの側面に焦点を当てます。 + +#### [ローカル開発パフォーマンス](#local-development-performance) + +Next.jsが成熟し、それを使って構築されるアプリケーションのサイズが大きくなるにつれ、基礎となるアーキテクチャの一部をより高速でスケーラブルなツールに置き換えてきました。 + +* **移行の進捗**: Babel(コンパイル)とTerser(ミニフィケーション)を[SWC](/docs/architecture/nextjs-compiler)に置き換えることから始めました。これにより、ローカルでの反復速度と本番ビルド時間が改善されました。 + +* **長期的な投資**: アプリケーションのサイズに関係なく優れたFast Refreshパフォーマンスを維持するには、Next.jsがローカル開発時に可能な限り増分的に動作し、必要なコードのみをバンドルおよびコンパイルする必要があります。 + + これが、現在webpack(バンドリング)を[Turbopack](https://nextjs.org/docs/app/api-reference/turbopack)に置き換えている理由です。Turbopackは、個々の関数レベルまでキャッシュを可能にする低レベルの増分計算エンジン上に構築されています。 + + Turbopackに移行したNext.jsアプリケーションは、サイズが大きくなってもFast Refresh速度の持続的な改善が見込めます。 + + 過去数ヶ月間、TurboチームはTurbopackのパフォーマンスとすべてのNext.js機能およびApp Router APIのサポート改善に注力してきました。 + + Turbopackは現在[ベータ版で利用可能](/docs/architecture/turbopack)です(`next dev --turbo`)。 + +* **現在のアーキテクチャの改善**: 将来への投資に加えて、既存のwebpackアーキテクチャのパフォーマンス改善も継続しています。 + + 特に数千のモジュールをリフレッシュするNext.jsアプリケーションでは、ローカル開発とFast Refreshの不安定さが報告されています。ここでのパフォーマンスと信頼性を改善するために取り組んでいます。例えば、最近では[大規模なアイコンライブラリ](https://github.com/vercel/next.js/pull/50900)を扱うための事前設定(`modularizeImports`)を追加しました。これにより、リクエストごとに数千のモジュールが誤って再読み込みされるのを防ぎます。 + + +#### [ビルド時パフォーマンス](#build-time-performance) + +Turbopackを使用した本番ビルド(`next build --turbo`)にも取り組んでおり、この作業の最初の部分を[実装し始めています](https://github.com/vercel/next.js/pull/51546)。今後のリリースでさらに更新される予定です。 + +#### [本番環境パフォーマンス](#production-performance) + +最後に、Vercelでは、[Next.jsアプリケーションコードで定義された](https://vercel.com/blog/framework-defined-infrastructure)Vercel Functionsのパフォーマンスとメモリ使用量を最適化し、スケーラブルなサーバーレスアーキテクチャの利点を維持しながらコールドスタートを最小限に抑える取り組みをしています。この作業により、Next.jsに新しい[トレーシング機能](/docs/app/building-your-application/optimizing/open-telemetry)(実験的)が導入され、サーバーサイド開発者ツールの初期調査が行われています。 + +[安定性の向上](#improving-stability) +------------------------------------------- + +Pages Routerは6年間存在しています。App Routerのリリースは、わずか6ヶ月間の使用歴しかない新しいAPIの導入を意味しました。短期間で大きな進歩を遂げましたが、コミュニティからのフィードバックや使用方法から学びながら改善する機会がまだあります。 + +コミュニティが積極的にApp Routerを採用し、フィードバックを提供してくれたことに感謝しています。調査中のバグレポートが多数あり、問題を特定し修正を検証するために作成された最小限の再現例に感謝しています。 + +13.4以降、安定性に関する多くの影響の大きいバグを修正し、最新のパッチリリース(`13.4.7`)で利用可能になりました。今後もパフォーマンスと安定性に強く注力していきます。 + +[開発者教育の改善](#improving-developer-education) +--------------------------------------------------------------- + +App Routerと現代のReactの新機能は強力ですが、これらの新しい概念を教えるためには追加の教育とドキュメントが必要です。 + +### [Next.jsの機能](#nextjs-features) + +過去1年間、Next.jsドキュメントを一から書き直す作業を行ってきました。この作業は現在[nextjs.org/docs](/docs)で公開されています。[重要なポイント](https://twitter.com/delba_oliveira/status/1664323492077256704)をいくつか紹介します: + +* **PagesとAppの切り替え**: ドキュメントの左側にあるボタンを使用して、Pages RouterまたはApp Routerのドキュメントを切り替えることができます。さらに、ルーターの選択に基づいて検索結果をフィルタリングできます。 +* **改善されたコンテンツと情報アーキテクチャ**: App Routerドキュメントのほぼすべてのページが刷新され、ページ間の構造と一貫性がより明確になり、Next.jsの動作を視覚的に説明する数百の新しいイラストが追加されました。 +* **さらに追加予定**: ここではさらに作業が必要です。VercelのDeveloper Experienceチームは、追加の学習リソース(App Routerを教える更新された`/learn`コースを含む)と実際のコードベース例([Next.js Commerce](https://github.com/vercel/commerce)の書き換えを含む)を提供するために懸命に取り組んでいます。 + +[ドキュメント](/docs)、[Twitter](https://twitter.com/nextjs)、[YouTube](https://www.youtube.com/c/VercelHQ)などで新しいコンテンツをリリース予定です。 + +### [新しいReact機能](#new-react-features) + +Next.js App Routerで利用可能な新しいReact機能に関する教育についてもフィードバックをいただきました。 + +* **サーバーコンポーネント**: サーバーコンポーネントや[`"use client"`ディレクティブ](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md)のような規約はNext.js固有のものではなく、Reactエコシステムの大きな一部であることに注意することが重要です。 + + 私たちのチーム、Metaのパートナー、その他の独立した貢献者が、これらのトピックに関するより多くの教育を提供するために取り組んでいます。これらの概念は初期段階ですが、Reactエコシステムと[継続的な教育](https://github.com/reactwg/server-components/discussions/5)に自信を持っています。 + +* **クライアントコンポーネント**: 最近のサーバーコンポーネントに関する議論の中で、クライアントコンポーネントが非最適化ではないことに注意することが重要です。クライアントはReactモデルの有効な一部であり、なくなることはありません。 + + クライアントコンポーネントは、既存のNext.jsエコシステムと考えてください。お気に入りのライブラリやツールが引き続き動作します。例えば、よくある質問として、すべてのファイルに`"use client"`を追加してクライアントコンポーネントにする必要があるかどうかがあります。これは必要ありませんが、これらの概念は新しく、学ぶのに時間がかかることを理解しています。[サーバーからクライアントにコードが移動するトップレベルの境界](/docs/getting-started/react-essentials#the-use-client-directive)のみをマークする必要があります。このアーキテクチャにより、[サーバーとクライアントコンポーネントを織り交ぜる](https://github.com/reactwg/server-components/discussions/5)ことができます。 + +* **成長するサードパーティエコシステム**: 教育に加えて、Reactの新機能を中心としたエコシステムはまだ成長中です。例えば、Chakra UIの製作者によるCSS-in-JSライブラリ[Panda CSS](https://panda-css.com/)が、Reactサーバーコンポーネントのサポートを発表しました。 + +* **サーバーアクション(アルファ版)**: [サーバーアクション](/docs/app/building-your-application/data-fetching/server-actions)は、サーバーサイドのデータ変更、クライアントサイドJavaScriptの削減、プログレッシブエンハンスメントフォームを可能にします。まだ本番環境でのサーバーアクションの使用は推奨していません。この機能の未来を形作るのに役立つアルファテスターからの早期フィードバックに感謝しています。 + + +[感謝](#thank-you) +----------------------- + +Next.jsで学び、構築することを選択してくれた多くの方々に感謝しています。 + +パフォーマンス、安定性、開発者体験への焦点は、今後のNext.jsリリースに反映されます。Next.jsの使用が楽しく、あなた(とあなたのチーム)がより生産的になることを望んでいます。 + +いつものように、皆さんのフィードバックに大変感謝しています。Next.jsで問題が発生した場合は、[issueを開く](https://github.com/vercel/next.js/issues/new/choose)か、[新しいディスカッションを開始](https://github.com/vercel/next.js/discussions)してください。調査いたします。 \ No newline at end of file diff --git a/apps/docs/content/ja/blog/layouts-rfc.mdx b/apps/docs/content/ja/blog/layouts-rfc.mdx new file mode 100644 index 00000000..91914d68 --- /dev/null +++ b/apps/docs/content/ja/blog/layouts-rfc.mdx @@ -0,0 +1,910 @@ +--- +source-updated-at: 2025-05-29T19:07:21.000Z +translation-updated-at: 2025-06-02T19:26:41.533Z +title: Layouts RFC(リクエストフォーコメント) +description: >- + ネストされたルートとレイアウト、クライアントとサーバーのルーティング、React 18の機能、そしてサーバーコンポーネント向けに設計されています。 +author: + - name: Delba de Oliveira + image: /static/team/delba.jpg + - name: Lee Robinson + image: /static/team/lee.jpg + - name: Sebastian Markbåge + image: /static/team/seb.jpg + - name: Tim Neutkens + image: /static/team/tim.jpg +date: 2022-05-23T20:30:00.507Z +image: >- + https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/twitter-card.png +--- + +このRFC(Request for Comment)は、Next.jsが2016年に導入されて以来の最大のアップデートを概説しています: + +* **ネストされたレイアウト:** ネストされたルートで複雑なアプリケーションを構築 +* **サーバーコンポーネント向け設計:** サブツリーナビゲーションに最適化 +* **データ取得の改善:** ウォーターフォールを避けつつレイアウトでデータ取得 +* **React 18機能の活用:** ストリーミング、トランジション、サスペンス +* **クライアントとサーバーのルーティング:** SPAのような動作を持つサーバー中心のルーティング +* **100%段階的採用可能:** 破壊的変更なしで徐々に導入可能 +* **高度なルーティングパターン:** 並列ルート、インターセプトルートなど + +新しいNext.jsルーターは、[最近リリースされたReact 18](https://reactjs.org/blog/2022/03/29/react-v18.html)の機能を基盤として構築されます。これらの新機能を簡単に採用し、その利点を活かせるよう、デフォルトと規約を導入する予定です。 + +> このRFCの作業は進行中であり、新機能が利用可能になった際には発表します。フィードバックを提供するには、[Github Discussions](https://github.com/vercel/next.js/discussions/37136)の会話に参加してください。 + +[目次](#目次) +--------------------------------------- + +* [動機](#動機) +* [用語](#用語) +* [現在のルーティングの仕組み](#現在のルーティングの仕組み) +* [`app`ディレクトリの紹介](#appディレクトリの紹介) +* [ルートの定義](#ルートの定義) +* [レイアウト](#レイアウト) +* [ページ](#ページ) +* [Reactサーバーコンポーネント](#reactサーバーコンポーネント) +* [データ取得](#データ取得) +* [ルートグループ(新機能)](#ルートグループ) +* [サーバー中心のルーティング(新機能)](#サーバー中心のルーティング) +* [即時ローディング状態(新機能)](#即時ローディング状態) +* [エラーハンドリング(新機能)](#エラーハンドリング) +* [テンプレート(新機能)](#テンプレート) +* [高度なルーティングパターン(新機能)](#高度なルーティングパターン) +* [結論](#結論) + +[動機](#動機) +------------------------- + +GitHub、Discord、Reddit、および開発者調査から、Next.jsの現在のルーティングの制限に関するコミュニティフィードバックを収集してきました。以下の点が明らかになりました: + +* レイアウト作成の開発者体験は改善の余地がある。ネスト可能で、ルート間で共有でき、ナビゲーション時に状態が保持されるレイアウトを簡単に作成できるべき。 +* 多くのNext.jsアプリケーションはダッシュボードやコンソールであり、より高度なルーティングソリューションの恩恵を受ける。 + +現在のルーティングシステムはNext.jsの開始以来うまく機能してきましたが、よりパフォーマンスが高く機能豊富なWebアプリケーションを開発者が簡単に構築できるようにしたいと考えています。 + +フレームワークのメンテナーとしても、後方互換性がありReactの将来と整合するルーティングシステムを構築したいと考えています。 + +> **注記:** 一部のルーティング規約は、MetaのRelayベースのルーター(サーバーコンポーネントの機能が最初に開発された場所)や、React RouterやEmber.jsなどのクライアントサイドルーターからインスピレーションを得ています。`layout.js`ファイル規約はSvelteKitの作業に触発されました。[Cassidy](https://twitter.com/cassidoo)が[レイアウトに関する以前のRFC](https://github.com/vercel/next.js/discussions/26389)を開いてくれたことにも感謝します。 + +[用語](#用語) +--------------------------- + +このRFCでは、新しいルーティング規約と構文を導入します。用語はReactと標準的なWebプラットフォームの用語に基づいています。RFC全体で、これらの用語が以下の定義にリンクされます。 + +* **ツリー:** 階層構造を視覚化するための規約。例えば、親と子コンポーネントを持つコンポーネントツリー、フォルダ構造など。 +* **サブツリー:** ツリーの一部で、ルート(最初)からリーフ(最後)まで。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/terminology.png) + +* **URLパス:** ドメインの後に続くURLの部分。 +* **URLセグメント:** スラッシュで区切られたURLパスの部分。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/url-anatomy.png) + +[現在のルーティングの仕組み](#現在のルーティングの仕組み) +----------------------------------------------------------- + +現在、Next.jsはファイルシステムを使用して、[Pages](/docs/pages/building-your-application/routing/pages-and-layouts)ディレクトリ内の個々のフォルダとファイルをURLでアクセス可能なルートにマッピングしています。各**ページ**ファイルはReactコンポーネントをエクスポートし、ファイル名に基づいて関連する**ルート**を持ちます。例えば: + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/routing-today.png) + +* **動的ルート:** Next.jsは`[param].js`、`[...param].js`、`[[...param]].js`規約で[動的ルート](/docs/pages/building-your-application/routing/dynamic-routes)(キャッチオールバリエーションを含む)をサポートします。 +* **レイアウト:** Next.jsは、シンプルな[コンポーネントベース](/docs/pages/building-your-application/routing/pages-and-layouts#layout-pattern)のレイアウト、コンポーネント[プロパティパターン](/docs/pages/building-your-application/routing/pages-and-layouts#layout-pattern#per-page-layouts)を使用したページごとのレイアウト、および[カスタムアプリ](/docs/pages/building-your-application/routing/pages-and-layouts#layout-pattern#single-shared-layout-with-custom-app)を使用した単一のグローバルレイアウトをサポートします。 +* **データ取得:** Next.jsは、ページ(ルート)レベルで使用できるデータ取得メソッド([`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props)、[`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props))を提供します。これらのメソッドは、ページが静的生成([`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props))またはサーバーサイドレンダリング([`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props))されるべきかを決定するために使用されます。さらに、[増分的静的再生成(ISR)](/docs/pages/building-your-application/data-fetching/incremental-static-regeneration)を使用して、サイト構築後に静的ページを作成または更新できます。 +* **レンダリング:** Next.jsは、[静的生成](https://nextjs.org/learn/foundations/how-nextjs-works/rendering)、[サーバーサイドレンダリング](https://nextjs.org/learn/foundations/how-nextjs-works/rendering)、[クライアントサイドレンダリング](https://nextjs.org/learn/foundations/how-nextjs-works/rendering)の3つのレンダリングオプションを提供します。デフォルトでは、ページはブロッキングデータ取得要件(`getServerSideProps`)がない限り静的に生成されます。 + +[`app`ディレクトリの紹介](#appディレクトリの紹介) +----------------------------------------------------------------- + +これらの新しい改善を段階的に採用でき、破壊的変更を避けるために、`app`という新しいディレクトリを提案します。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/app-folder.png) + +`app`ディレクトリは`pages`ディレクトリと並行して動作します。アプリケーションの一部を新しい`app`ディレクトリに徐々に移動して、新機能の利点を活用できます。後方互換性のために、`pages`ディレクトリの動作は同じままで、引き続きサポートされます。 + +[ルートの定義](#ルートの定義) +----------------------------------- + +`app`内の**フォルダ**階層を使用してルートを定義できます。**ルート**は、**ルートフォルダ**から最終的な**リーフフォルダ**までの階層に従った、ネストされたフォルダの単一のパスです。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/routes.png) + +例えば、`app`ディレクトリに2つの新しいフォルダをネストすることで、新しい`/dashboard/settings`ルートを追加できます。 + +> **注記:** +> +> * このシステムでは、フォルダを使用してルートを定義し、ファイルを使用してUIを定義します(`layout.js`、`page.js`、およびRFCの後半で`loading.js`などの新しいファイル規約を使用)。 +> * これにより、`app`ディレクトリ内に独自のプロジェクトファイル(UIコンポーネント、テストファイル、ストーリーなど)を配置できます。現在、これは[pageExtensions設定](/docs/pages/api-reference/next-config-js/pageExtensions#including-non-page-files-in-the-pages-directory)でのみ可能です。 + +### [ルートセグメント](#ルートセグメント) + +[サブツリー](#用語)内の各フォルダは**ルートセグメント**を表します。各ルートセグメントは、**[URLパス](#用語)**の対応する**セグメント**にマッピングされます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/route-segments.png) + +例えば、`/dashboard/settings`ルートは3つのセグメントで構成されます: + +* `/`ルートセグメント +* `dashboard`セグメント +* `settings`セグメント + +> **注記**: **ルートセグメント**という名前は、[URLパス](#用語)に関する既存の用語と一致するように選択されました。 + +[レイアウト](#レイアウト) +------------------- + +**新しいファイル規約:** `layout.js` + +これまで、アプリケーションのルートを定義するためにフォルダを使用してきました。しかし、空のフォルダはそれ自体では何もしません。新しいファイル規約を使用して、これらのルートにレンダリングされるUIを定義する方法について説明しましょう。 + +**レイアウト**は、[サブツリー](#用語)内のルートセグメント間で共有されるUIです。レイアウトは[URLパス](#用語)に影響を与えず、ユーザーが兄弟セグメント間をナビゲートしても再レンダリングされません(Reactの状態は保持されます)。 + +レイアウトは、`layout.js`ファイルからReactコンポーネントをデフォルトエクスポートすることで定義できます。コンポーネントは、レイアウトがラップしているセグメントで埋められる`children`プロップを受け入れる必要があります。 + +レイアウトには2つのタイプがあります: + +* **ルートレイアウト:** すべてのルートに適用 +* **通常のレイアウト:** 特定のルートに適用 + +2つ以上のレイアウトをネストして**ネストされたレイアウト**を形成できます。 + +### [ルートレイアウト](#ルートレイアウト) + +`app`フォルダ内に`layout.js`ファイルを追加することで、アプリケーションのすべてのルートに適用されるルートレイアウトを作成できます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/root-layout.png) + +> **注記:** +> +> * ルートレイアウトは、[カスタムApp(`_app.js`)](/docs/pages/building-your-application/routing/custom-app)と[カスタムDocument(`_document.js`)](/docs/pages/building-your-application/routing/custom-document)の必要性を置き換えます。なぜなら、すべてのルートに適用されるからです。 +> * ルートレイアウトを使用して、初期ドキュメントシェル(例:``および``タグ)をカスタマイズできます。 +> * ルートレイアウト(および他のレイアウト)内でデータを取得できます。 + +### [通常のレイアウト](#通常のレイアウト) + +特定のフォルダ内に`layout.js`ファイルを追加することで、アプリケーションの一部にのみ適用されるレイアウトも作成できます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/regular-layouts.png) + +例えば、`dashboard`フォルダ内に`layout.js`ファイルを作成すると、`dashboard`内のルートセグメントにのみ適用されます。 + +### [ネストされたレイアウト](#ネストされたレイアウト) + +レイアウトはデフォルトで**ネスト**されます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/nested-layouts.png) + +例えば、上記の2つのレイアウトを組み合わせるとします。ルートレイアウト(`app/layout.js`)は`dashboard`レイアウトに適用され、`dashboard/*`内のすべてのルートセグメントにも適用されます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/nested-layouts-example.png) + +[ページ](#ページ) +--------------- + +**新しいファイル規約:** `page.js` + +ページは、ルートセグメントに固有のUIです。フォルダ内に`page.js`ファイルを追加することでページを作成できます。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/page.png) + +例えば、`/dashboard/*`ルートのページを作成するには、各フォルダ内に`page.js`ファイルを追加できます。ユーザーが`/dashboard/settings`にアクセスすると、Next.jsは`settings`フォルダの`page.js`ファイルを、[サブツリー](#用語)の上位にあるレイアウトでラップしてレンダリングします。 + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/page-example.png) + +`dashboard`フォルダ内に直接`page.js`ファイルを作成して、`/dashboard`ルートにマッチさせることができます。ダッシュボードレイアウトもこのページに適用されます: + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/page-nested.png) + +このルートは2つのセグメントで構成されます: + +* `/`ルートセグメント +* `dashboard`セグメント + +> **注記:** +> +> * ルートが有効であるためには、リーフセグメントにページが必要です。ない場合、ルートはエラーをスローします。 + +### [レイアウトとページの動作](#レイアウトとページの動作) + +* ファイル拡張子`js|jsx|ts|tsx`は、ページとレイアウトに使用できます。 +* ページコンポーネントは`page.js`のデフォルトエクスポートです。 +* レイアウトコンポーネントは`layout.js`のデフォルトエクスポートです。 +* レイアウトコンポーネントは**必ず**`children`プロップを受け入れる必要があります。 + +レイアウトコンポーネントがレンダリングされると、`children`プロップは、子レイアウト([サブツリー](#用語)のさらに下に存在する場合)またはページで埋められます。 + +親レイアウトが最も近い子レイアウトを選択し、ページに到達するまで続くレイアウト[ツリー](#用語)として視覚化するとわかりやすいかもしれません。 + +**例:** + +![](https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/layouts-rfc/basic-example.png) + +```js filename="app/layout.js" +// ルートレイアウト +// - すべてのルートに適用 +export default function RootLayout({ children }) { + return ( + + +
+ {children} +