diff --git a/docs/01-app/01-getting-started/01-installation.mdx b/docs/01-app/01-getting-started/01-installation.mdx index 46b161e7..5a54fc5e 100644 --- a/docs/01-app/01-getting-started/01-installation.mdx +++ b/docs/01-app/01-getting-started/01-installation.mdx @@ -4,13 +4,13 @@ nav_title: 'インストール' description: '`create-next-app` CLIを使用して新しい Next.js アプリケーションを作成し、TypeScript、ESLint、モジュールパスエイリアスを設定します。' --- -{/* このドキュメントの内容は、app router と pages router の両方で共有されています。Pages Router に特有の内容を追加するには、`Content` コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容は、app router と pages router の間で共有されています。Pages Router に特有のコンテンツを追加するには、`Content` コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} ## システム要件 {#system-requirements} 始める前に、システムが次の要件を満たしていることを確認してください: -- [Node.js 18.18](https://nodejs.org/) 以降 +- [Node.js 18.18](https://nodejs.org/) 以上 - macOS、Windows(WSLを含む)、またはLinux ## 自動インストール {#automatic-installation} @@ -132,7 +132,7 @@ export default function Page() { `layout.tsx` と `page.tsx` の両方が、ユーザーがアプリケーションの root (`/`) を訪れたときにレンダリングされます。 App Folder Structure **Good to know**: > > - root レイアウトの作成を忘れた場合、`next dev` で開発サーバーを実行すると、Next.js が自動的にこのファイルを作成します。 -> - プロジェクトの root に [`src` ディレクトリ](/docs/app/building-your-application/configuring/src-directory) を使用して、アプリケーションのコードを設定ファイルから分離することができます。 +> - プロジェクトの root に [`src` フォルダ](/docs/app/api-reference/file-conventions/src-folder) を使用して、アプリケーションのコードを設定ファイルから分離することができます。 @@ -175,7 +175,7 @@ export default function Page() { -次に、`pages/` 内に `_app.tsx` ファイルを追加して、グローバルレイアウトを定義します。[カスタム App ファイル](https://nextjs.org/docs/canary/pages/building-your-application/routing/custom-app) について詳しく学びましょう。 +次に、`pages/` 内に `_app.tsx` ファイルを追加して、グローバルレイアウトを定義します。詳細は [カスタム App ファイル](https://nextjs.org/docs/canary/pages/building-your-application/routing/custom-app) を参照してください。 @@ -200,7 +200,7 @@ export default function App({ Component, pageProps }) { -最後に、`pages/` 内に `_document.tsx` ファイルを追加して、サーバーからの初期レスポンスを制御します。[カスタム Document ファイル](https://nextjs.org/docs/canary/pages/building-your-application/routing/custom-document) について詳しく学びましょう。 +最後に、`pages/` 内に `_document.tsx` ファイルを追加して、サーバーからの初期レスポンスを制御します。詳細は [カスタム Document ファイル](https://nextjs.org/docs/canary/pages/building-your-application/routing/custom-document) を参照してください。 @@ -286,13 +286,13 @@ export default function Page() { > 最小 TypeScript バージョン: `v4.5.2` -Next.js には組み込みの TypeScript サポートがあります。プロジェクトに TypeScript を追加するには、ファイルを `.ts` / `.tsx` にリネームして `next dev` を実行します。Next.js は必要な依存関係を自動的にインストールし、推奨される設定オプションを含む `tsconfig.json` ファイルを追加します。 +Next.js には TypeScript のサポートが組み込まれています。プロジェクトに TypeScript を追加するには、ファイルを `.ts` / `.tsx` にリネームして `next dev` を実行します。Next.js は必要な依存関係を自動的にインストールし、推奨される設定オプションを含む `tsconfig.json` ファイルを追加します。 ### IDE プラグイン {#ide-plugin} -Next.js にはカスタム TypeScript プラグインと型チェッカーが含まれており、VSCode や他のコードエディタで高度な型チェックや自動補完を利用できます。 +Next.js にはカスタム TypeScript プラグインと型チェッカーが含まれており、VSCode や他のコードエディタで高度な型チェックと自動補完を利用できます。 VS Code でプラグインを有効にするには: @@ -301,7 +301,7 @@ VS Code でプラグインを有効にするには: 3. 「Use Workspace Version」を選択 TypeScript Command Palette Base > Cancel -- **Strict**: Next.js の基本的な ESLint 設定に加えて、より厳格な Core Web Vitals ルールセットを含みます。初めて ESLint を設定する開発者に推奨される設定です。 +- **Strict**: Next.js の基本的な ESLint 設定に加え、より厳格な Core Web Vitals ルールセットを含みます。初めて ESLint を設定する開発者に推奨される設定です。 - **Base**: Next.js の基本的な ESLint 設定を含みます。 -- **Cancel**: 設定をスキップします。独自のカスタム ESLint 設定を設定する予定の場合、このオプションを選択します。 +- **Cancel**: 設定をスキップします。独自のカスタム ESLint 設定を行う予定の場合、このオプションを選択します。 `Strict` または `Base` が選択されると、Next.js は自動的に `eslint` と `eslint-config-next` をアプリケーションの依存関係としてインストールし、選択した設定を含む `.eslintrc.json` ファイルをプロジェクトの root に作成します。 @@ -352,9 +352,9 @@ ESLint を実行してエラーをキャッチしたいときは、`next lint` ## 絶対インポートとモジュールパスエイリアスの設定 {#set-up-absolute-imports-and-module-path-aliases} -Next.js には、`tsconfig.json` および `jsconfig.json` ファイルの `"paths"` および `"baseUrl"` オプションのサポートが組み込まれています。 +Next.js は `tsconfig.json` および `jsconfig.json` ファイルの `"paths"` および `"baseUrl"` オプションをサポートしています。 -これらのオプションを使用すると、プロジェクトディレクトリを絶対パスにエイリアス化し、モジュールのインポートをより簡単かつクリーンにすることができます。たとえば: +これらのオプションを使用すると、プロジェクトディレクトリを絶対パスにエイリアス化し、モジュールのインポートをより簡単かつクリーンに行うことができます。たとえば: ```jsx // Before diff --git a/docs/01-app/01-getting-started/02-project-structure.mdx b/docs/01-app/01-getting-started/02-project-structure.mdx index a0885150..b3164308 100644 --- a/docs/01-app/01-getting-started/02-project-structure.mdx +++ b/docs/01-app/01-getting-started/02-project-structure.mdx @@ -25,44 +25,44 @@ description: 'Next.jsにおけるフォルダとファイルの規約の概要 | [`app`](/docs/app/building-your-application/routing) | App Router | | [`pages`](https://nextjs.org/docs/canary/pages/building-your-application/routing) | Pages Router | | [`public`](/docs/app/building-your-application/optimizing/static-assets) | 提供される静的アセット | -| [`src`](/docs/app/building-your-application/configuring/src-directory) | オプションのアプリケーションソースフォルダ | +| [`src`](/docs/app/api-reference/file-conventions/src-folder) | オプションのアプリケーションソースフォルダ | ### トップレベルファイル {#top-level-files} トップレベルファイルは、アプリケーションの設定、依存関係の管理、ミドルウェアの実行、モニタリングツールの統合、環境変数の定義に使用されます。 -| | | -| ------------------------------------------------------------------------------------------- | -------------------------------------- | -| **Next.js** | | -| [`next.config.js`](/docs/app/api-reference/config/next-config-js) | Next.jsの設定ファイル | -| [`package.json`](/docs/app/getting-started/installation#manual-installation) | プロジェクトの依存関係とスクリプト | -| [`instrumentation.ts`](/docs/app/building-your-application/optimizing/instrumentation) | OpenTelemetryとInstrumentationファイル | -| [`middleware.ts`](/docs/app/building-your-application/routing/middleware) | Next.jsリクエストミドルウェア | -| [`.env`](/docs/app/building-your-application/configuring/environment-variables) | 環境変数 | -| [`.env.local`](/docs/app/building-your-application/configuring/environment-variables) | ローカル環境変数 | -| [`.env.production`](/docs/app/building-your-application/configuring/environment-variables) | 本番環境変数 | -| [`.env.development`](/docs/app/building-your-application/configuring/environment-variables) | 開発環境変数 | -| [`.eslintrc.json`](/docs/app/api-reference/config/eslint) | ESLintの設定ファイル | -| `.gitignore` | 無視するGitファイルとフォルダ | -| `next-env.d.ts` | Next.js用のTypeScript宣言ファイル | -| `tsconfig.json` | TypeScriptの設定ファイル | -| `jsconfig.json` | JavaScriptの設定ファイル | +| | | +| ---------------------------------------------------------------------------- | -------------------------------------- | +| **Next.js** | | +| [`next.config.js`](/docs/app/api-reference/config/next-config-js) | Next.jsの設定ファイル | +| [`package.json`](/docs/app/getting-started/installation#manual-installation) | プロジェクトの依存関係とスクリプト | +| [`instrumentation.ts`](/docs/app/guides/instrumentation) | OpenTelemetryとInstrumentationファイル | +| [`middleware.ts`](/docs/app/building-your-application/routing/middleware) | Next.jsリクエストミドルウェア | +| [`.env`](/docs/app/guides/environment-variables) | 環境変数 | +| [`.env.local`](/docs/app/guides/environment-variables) | ローカル環境変数 | +| [`.env.production`](/docs/app/guides/environment-variables) | 本番環境変数 | +| [`.env.development`](/docs/app/guides/environment-variables) | 開発環境変数 | +| [`.eslintrc.json`](/docs/app/api-reference/config/eslint) | ESLintの設定ファイル | +| `.gitignore` | 無視するGitファイルとフォルダ | +| `next-env.d.ts` | Next.js用のTypeScript宣言ファイル | +| `tsconfig.json` | TypeScriptの設定ファイル | +| `jsconfig.json` | JavaScriptの設定ファイル | ### ルーティングファイル {#routing-files} -| | | | -| ----------------------------------------------------------------------------- | ------------------- | ------------------------------------ | -| [`layout`](/docs/app/api-reference/file-conventions/layout) | `.js` `.jsx` `.tsx` | レイアウト | -| [`page`](/docs/app/api-reference/file-conventions/page) | `.js` `.jsx` `.tsx` | ページ | -| [`loading`](/docs/app/api-reference/file-conventions/loading) | `.js` `.jsx` `.tsx` | ローディングUI | -| [`not-found`](/docs/app/api-reference/file-conventions/not-found) | `.js` `.jsx` `.tsx` | 見つからないUI | -| [`error`](/docs/app/api-reference/file-conventions/error) | `.js` `.jsx` `.tsx` | エラーUI | -| [`global-error`](/docs/app/api-reference/file-conventions/error#global-error) | `.js` `.jsx` `.tsx` | グローバルエラーUI | -| [`route`](/docs/app/api-reference/file-conventions/route) | `.js` `.ts` | APIエンドポイント | -| [`template`](/docs/app/api-reference/file-conventions/template) | `.js` `.jsx` `.tsx` | 再レンダリングされるレイアウト | -| [`default`](/docs/app/api-reference/file-conventions/default) | `.js` `.jsx` `.tsx` | パラレルルートのフォールバックページ | +| | | | +| ----------------------------------------------------------------------------- | ------------------- | ---------------------------------- | +| [`layout`](/docs/app/api-reference/file-conventions/layout) | `.js` `.jsx` `.tsx` | レイアウト | +| [`page`](/docs/app/api-reference/file-conventions/page) | `.js` `.jsx` `.tsx` | ページ | +| [`loading`](/docs/app/api-reference/file-conventions/loading) | `.js` `.jsx` `.tsx` | ローディングUI | +| [`not-found`](/docs/app/api-reference/file-conventions/not-found) | `.js` `.jsx` `.tsx` | 見つからないUI | +| [`error`](/docs/app/api-reference/file-conventions/error) | `.js` `.jsx` `.tsx` | エラーUI | +| [`global-error`](/docs/app/api-reference/file-conventions/error#global-error) | `.js` `.jsx` `.tsx` | グローバルエラーUI | +| [`route`](/docs/app/api-reference/file-conventions/route) | `.js` `.ts` | APIエンドポイント | +| [`template`](/docs/app/api-reference/file-conventions/template) | `.js` `.jsx` `.tsx` | 再レンダリングされたレイアウト | +| [`default`](/docs/app/api-reference/file-conventions/default) | `.js` `.jsx` `.tsx` | パラレルルートフォールバックページ | ### ネストされたルート {#nested-routes} @@ -73,11 +73,11 @@ description: 'Next.jsにおけるフォルダとファイルの規約の概要 ### 動的ルート {#dynamic-routes} -| | | -| --------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -| [`[folder]`](/docs/app/building-your-application/routing/dynamic-routes#convention) | 動的ルートセグメント | -| [`[...folder]`](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments) | キャッチオールルートセグメント | -| [`[[...folder]]`](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | オプショナルキャッチオールルートセグメント | +| | | +| --------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| [`[folder]`](/docs/app/building-your-application/routing/dynamic-routes#convention) | 動的ルートセグメント | +| [`[...folder]`](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments) | キャッチオールルートセグメント | +| [`[[...folder]]`](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | オプションキャッチオールルートセグメント | ### ルートグループとプライベートフォルダ {#route-groups-and-private-folders} @@ -86,7 +86,7 @@ description: 'Next.jsにおけるフォルダとファイルの規約の概要 | [`(folder)`](/docs/app/building-your-application/routing/route-groups#convention) | ルーティングに影響を与えずにルートをグループ化 | | [`_folder`](#private-folders) | フォルダとすべての子セグメントをルーティングから除外 | -### パラレルルートとインターセプトルート {#parallel-and-intercepted-routes} +### パラレルルートとインターセプトされたルート {#parallel-and-intercepted-routes} | | | | ---------------------------------------------------------------------------------------------- | ---------------------------- | @@ -153,16 +153,16 @@ description: 'Next.jsにおけるフォルダとファイルの規約の概要 ### 動的ルート {#dynamic-routes} -| | | | -| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | ------------------------------------------ | -| **フォルダの規約** | | | -| [`[folder]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes) | `.js` `.jsx` `.tsx` | 動的ルートセグメント | -| [`[...folder]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#catch-all-segments) | `.js` `.jsx` `.tsx` | キャッチオールルートセグメント | -| [`[[...folder]]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | オプショナルキャッチオールルートセグメント | -| **ファイルの規約** | | | -| [`[file]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes) | `.js` `.jsx` `.tsx` | 動的ルートセグメント | -| [`[...file]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#catch-all-segments) | `.js` `.jsx` `.tsx` | キャッチオールルートセグメント | -| [`[[...file]]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | オプショナルキャッチオールルートセグメント | +| | | | +| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | ---------------------------------------- | +| **フォルダの規約** | | | +| [`[folder]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes) | `.js` `.jsx` `.tsx` | 動的ルートセグメント | +| [`[...folder]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#catch-all-segments) | `.js` `.jsx` `.tsx` | キャッチオールルートセグメント | +| [`[[...folder]]/index`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | オプションキャッチオールルートセグメント | +| **ファイルの規約** | | | +| [`[file]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes) | `.js` `.jsx` `.tsx` | 動的ルートセグメント | +| [`[...file]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#catch-all-segments) | `.js` `.jsx` `.tsx` | キャッチオールルートセグメント | +| [`[[...file]]`](https://nextjs.org/docs/canary/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | オプションキャッチオールルートセグメント | @@ -170,7 +170,7 @@ description: 'Next.jsにおけるフォルダとファイルの規約の概要 ## プロジェクトの組織化 {#organizing-your-project} -Next.jsは、プロジェクトファイルの組織化や配置について特に意見を持ちませんが、プロジェクトを整理するためのいくつかの機能を提供しています。 +Next.jsは、プロジェクトファイルをどのように整理し、配置するかについて**意見を持ちません**。しかし、プロジェクトを整理するためのいくつかの機能を提供しています。 ### コンポーネント階層 {#component-hierarchy} @@ -178,9 +178,9 @@ Next.jsは、プロジェクトファイルの組織化や配置について特 - `layout.js` - `template.js` -- `error.js` (React error boundary) -- `loading.js` (React suspense boundary) -- `not-found.js` (React error boundary) +- `error.js`(React error boundary) +- `loading.js`(React suspense boundary) +- `not-found.js`(React error boundary) - `page.js` またはネストされた `layout.js` ルートセグメントにpage.jsまたはroute.jsファイルが追加されるまでルートが公開されないことを示す図 -そして、ルートが公開されると、`page.js`または`route.js`によって返される**コンテンツのみ**がクライアントに送信されます。 +そして、ルートが公開アクセス可能になった場合でも、クライアントに送信されるのは`page.js`または`route.js`によって返される**コンテンツのみ**です。 page.jsとroute.jsファイルがルートを公開可能にすることを示す図 -これは、`app`ディレクトリ内のルートセグメント内に**プロジェクトファイル**を**安全に配置**でき、誤ってルーティングされることがないことを意味します。 +これは、プロジェクトファイルが`app`ディレクトリ内のルートセグメントに**安全にコロケーション**されても、誤ってルーティングされることがないことを意味します。 page.jsまたはroute.jsファイルを含むセグメントに配置されたプロジェクトファイルがルーティングされないことを示す図 -> **Good to know**: `app`内にプロジェクトファイルを配置することは可能ですが、必須ではありません。必要に応じて、[それらを`app`ディレクトリの外に保管する](#store-project-files-outside-of-app)こともできます。 +> **Good to know**: `app`にプロジェクトファイルをコロケーションすることは**可能**ですが、必ずしもそうする必要はありません。必要に応じて、[プロジェクトファイルを`app`ディレクトリの外に保管する](#store-project-files-outside-of-app)こともできます。 ### プライベートフォルダ {#private-folders} @@ -251,11 +251,11 @@ Next.jsは、プロジェクトファイルの組織化や配置について特 height="849" /> -`app`ディレクトリ内のファイルは[デフォルトで安全に配置できる](#colocation)ため、コロケーションにはプライベートフォルダは必要ありません。ただし、以下の目的で役立ちます: +`app`ディレクトリ内のファイルは[デフォルトで安全にコロケーションできる](#colocation)ため、コロケーションにはプライベートフォルダは必要ありません。ただし、以下の目的で役立つことがあります: - UIロジックをルーティングロジックから分離する - プロジェクト全体およびNext.jsエコシステム内で内部ファイルを一貫して整理する -- コードエディタでファイルを整理およびグループ化する +- コードエディタでファイルをソートおよびグループ化する - 将来のNext.jsファイル規約との潜在的な命名競合を回避する > **Good to know**: @@ -268,7 +268,7 @@ Next.jsは、プロジェクトファイルの組織化や配置について特 ルートグループは、フォルダを括弧で囲むことで作成できます:`(folderName)` -これは、フォルダが組織目的であり、ルートのURLパスに**含まれない**ことを示します。 +これは、フォルダが組織化の目的であり、ルートのURLパスに**含まれるべきではない**ことを示します。 ルートグループを使用したフォルダ構造の例 **Good to know**: 以下の例では、`components`と`lib`フォルダを一般的なプレースホルダーとして使用しています。これらの名前には特別なフレームワークの意味はなく、プロジェクトによっては`ui`、`utils`、`hooks`、`styles`などの他のフォルダを使用することがあります。 #### プロジェクトファイルを`app`の外に保管する {#store-project-files-outside-of-app} -この戦略では、すべてのアプリケーションコードをプロジェクトの**root**にある共有フォルダに保存し、`app`ディレクトリを純粋にルーティング目的のために使用します。 +この戦略では、すべてのアプリケーションコードをプロジェクトの**root**にある共有フォルダに保存し、`app`ディレクトリを純粋にルーティングの目的で使用します。 appの外にプロジェクトファイルを保管するフォルダ構造の例 **🎥 視聴:** Next.js のセルフホスティングについてさらに学ぶ → [YouTube (45 分)](https://www.youtube.com/watch?v=sIVL4JMqRfc) +> **🎥 視聴:** Next.jsのセルフホスティングについてさらに学ぶ → [YouTube (45分)](https://www.youtube.com/watch?v=sIVL4JMqRfc). diff --git a/docs/01-app/03-building-your-application/06-optimizing/08-analytics.mdx b/docs/01-app/02-guides/analytics.mdx similarity index 79% rename from docs/01-app/03-building-your-application/06-optimizing/08-analytics.mdx rename to docs/01-app/02-guides/analytics.mdx index aa67a7f2..446d968a 100644 --- a/docs/01-app/03-building-your-application/06-optimizing/08-analytics.mdx +++ b/docs/01-app/02-guides/analytics.mdx @@ -1,15 +1,16 @@ --- -title: 'Analytics' +title: 'Next.jsアプリケーションに分析を追加する方法' +nav_title: 'Analytics' description: 'Next.js Speed Insightsを使用してページのパフォーマンスを測定および追跡する' --- {/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特化したコンテンツを追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} -Next.jsには、パフォーマンスメトリクスを測定し報告するための組み込みサポートがあります。`useReportWebVitals`フックを使用して自分で報告を管理することもできますし、Vercelが提供する[管理サービス](https://vercel.com/analytics?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)を利用して、メトリクスを自動的に収集し可視化することもできます。 +Next.jsには、パフォーマンス指標を測定し報告するための組み込みサポートがあります。[`useReportWebVitals`](/docs/app/api-reference/functions/use-report-web-vitals)フックを使用して自分で報告を管理することもできますし、Vercelが提供する[管理サービス](https://vercel.com/analytics?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)を利用して、メトリクスを自動的に収集し視覚化することもできます。 ## クライアントインストゥルメンテーション {#client-instrumentation} -より高度な分析と監視のニーズに対応するために、Next.jsは`instrumentation-client.js|ts`ファイルを提供しています。このファイルは、アプリケーションのフロントエンドコードが実行される前に実行されます。これは、グローバルな分析、エラートラッキング、またはパフォーマンス監視ツールを設定するのに理想的です。 +より高度な分析と監視のニーズに対応するために、Next.jsはアプリケーションのフロントエンドコードが実行される前に実行される`instrumentation-client.js|ts`ファイルを提供しています。これは、グローバルな分析、エラートラッキング、またはパフォーマンス監視ツールを設定するのに理想的です。 使用するには、アプリケーションのルートディレクトリに`instrumentation-client.js`または`instrumentation-client.ts`ファイルを作成します: @@ -40,7 +41,7 @@ function MyApp({ Component, pageProps }) { } ``` -詳細は[APIリファレンス](https://nextjs.org/docs/canary/pages/api-reference/functions/use-report-web-vitals)を参照してください。 +詳細は[APIリファレンス](https://nextjs.org/docs/canary/pages/api-reference/functions/use-report-web-vitals)をご覧ください。 @@ -75,13 +76,13 @@ export default function Layout({ children }) { > `useReportWebVitals`フックは`"use client"`ディレクティブを必要とするため、最もパフォーマンスの高いアプローチは、root レイアウトがインポートする別のコンポーネントを作成することです。これにより、クライアントの境界が`WebVitals`コンポーネントに限定されます。 -詳細は[APIリファレンス](/docs/app/api-reference/functions/use-report-web-vitals)を参照してください。 +詳細は[APIリファレンス](/docs/app/api-reference/functions/use-report-web-vitals)をご覧ください。 ## Web Vitals {#web-vitals} -[Web Vitals](https://web.dev/vitals/)は、ウェブページのユーザーエクスペリエンスを捉えることを目的とした一連の有用なメトリクスです。以下のWeb Vitalsがすべて含まれています: +[Web Vitals](https://web.dev/vitals/)は、ウェブページのユーザーエクスペリエンスを捉えることを目的とした有用な指標のセットです。以下のWeb Vitalsがすべて含まれています: - [Time to First Byte](https://developer.mozilla.org/docs/Glossary/Time_to_first_byte) (TTFB) - [First Contentful Paint](https://developer.mozilla.org/docs/Glossary/First_contentful_paint) (FCP) @@ -175,7 +176,7 @@ export function WebVitals() { 上記のコアメトリクスに加えて、ページのハイドレーションとレンダリングにかかる時間を測定する追加のカスタムメトリクスがあります: -- `Next.js-hydration`: ページがハイドレーションを開始して終了するまでの時間(ミリ秒) +- `Next.js-hydration`: ページがハイドレーションを開始し終了するまでの時間(ミリ秒) - `Next.js-route-change-to-render`: ルート変更後にページがレンダリングを開始するまでの時間(ミリ秒) - `Next.js-render`: ルート変更後にページがレンダリングを終了するまでの時間(ミリ秒) @@ -205,7 +206,7 @@ export function reportWebVitals(metric) { ## 結果を外部システムに送信する {#sending-results-to-external-systems} -結果を任意のエンドポイントに送信して、サイト上の実際のユーザーパフォーマンスを測定および追跡できます。例えば: +サイト上の実際のユーザーパフォーマンスを測定および追跡するために、任意のエンドポイントに結果を送信できます。例えば: ```js useReportWebVitals((metric) => { @@ -221,11 +222,11 @@ useReportWebVitals((metric) => { }) ``` -> **Good to know**: [Google Analytics](https://analytics.google.com/analytics/web/)を使用している場合、`id`値を使用することで、メトリクスの分布を手動で構築することができます(パーセンタイルの計算など)。 +> **Good to know**: [Google Analytics](https://analytics.google.com/analytics/web/)を使用している場合、`id`値を使用することで、メトリクスの分布を手動で構築することができます(パーセンタイルを計算するなど) > ```js > useReportWebVitals((metric) => { -> // Google Analyticsを次のように初期化した場合は`window.gtag`を使用 +> // Google Analyticsを次の例のように初期化した場合は`window.gtag`を使用 > // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics > window.gtag('event', metric.name, { > value: Math.round( @@ -237,4 +238,4 @@ useReportWebVitals((metric) => { > }) > ``` > -> [Google Analyticsへの結果の送信について詳しく読む](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics). +> [Google Analyticsへの結果送信](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics)について詳しく読む diff --git a/docs/01-app/03-building-your-application/09-authentication/index.mdx b/docs/01-app/02-guides/authentication.mdx similarity index 75% rename from docs/01-app/03-building-your-application/09-authentication/index.mdx rename to docs/01-app/02-guides/authentication.mdx index 53b9abc3..997d22e5 100644 --- a/docs/01-app/03-building-your-application/09-authentication/index.mdx +++ b/docs/01-app/02-guides/authentication.mdx @@ -1,15 +1,16 @@ --- -title: 'Authentication' -description: 'Next.jsアプリケーションでの認証の実装方法を学びます。' +title: 'Next.jsで認証を実装する方法' +nav_title: '認証' +description: 'Next.jsアプリケーションで認証を実装する方法を学びます。' --- -アプリケーションのデータを保護するためには、認証を理解することが重要です。このページでは、認証を実装するために使用するReactとNext.jsの機能について説明します。 +認証を理解することは、アプリケーションのデータを保護するために重要です。このページでは、認証を実装するために使用するReactとNext.jsの機能について説明します。 始める前に、プロセスを3つの概念に分解すると役立ちます: -1. **[Authentication](#authentication)**: ユーザーが自分が主張する人物であるかどうかを確認します。ユーザーは、ユーザー名とパスワードなど、何かを持っているもので自分の身元を証明する必要があります。 -2. **[Session Management](#session-management)**: リクエスト間でユーザーの認証状態を追跡します。 -3. **[Authorization](#authorization)**: ユーザーがアクセスできるルートとデータを決定します。 +1. **[認証](#authentication)**: ユーザーが自分が主張する人物であるかどうかを確認します。ユーザーは、ユーザー名やパスワードなど、何かを持っていることで自分の身元を証明する必要があります。 +2. **[セッション管理](#session-management)**: リクエスト間でユーザーの認証状態を追跡します。 +3. **[認可](#authorization)**: ユーザーがアクセスできるルートやデータを決定します。 この図は、ReactとNext.jsの機能を使用した認証フローを示しています: @@ -23,7 +24,7 @@ description: 'Next.jsアプリケーションでの認証の実装方法を学 このページの例では、教育目的で基本的なユーザー名とパスワードの認証を説明します。カスタム認証ソリューションを実装することもできますが、セキュリティとシンプルさを向上させるために、認証ライブラリの使用をお勧めします。これらは、認証、セッション管理、認可のための組み込みソリューションを提供し、ソーシャルログイン、多要素認証、役割ベースのアクセス制御などの追加機能も提供します。[Auth Libraries](#auth-libraries)セクションでリストを見つけることができます。 -## Authentication {#authentication} +## 認証 {#authentication} @@ -37,7 +38,7 @@ Server Actionsは常にサーバー上で実行されるため、認証ロジッ #### 1. ユーザーの資格情報をキャプチャする {#1-capture-user-credentials} -ユーザーの資格情報をキャプチャするには、送信時にServer Actionを呼び出すフォームを作成します。たとえば、ユーザーの名前、メールアドレス、パスワードを受け付けるサインアップフォームです: +ユーザーの資格情報をキャプチャするには、送信時にServer Actionを呼び出すフォームを作成します。たとえば、ユーザーの名前、メールアドレス、パスワードを受け入れるサインアップフォーム: @@ -117,7 +118,7 @@ export async function signup(formData) {} Server Actionを使用して、サーバー上でフォームフィールドを検証します。認証プロバイダーがフォーム検証を提供していない場合は、[Zod](https://zod.dev/)や[Yup](https://github.com/jquense/yup)のようなスキーマ検証ライブラリを使用できます。 -Zodを例にとると、適切なエラーメッセージを含むフォームスキーマを定義できます: +Zodを例にとると、適切なエラーメッセージを持つフォームスキーマを定義できます: @@ -128,16 +129,19 @@ import { z } from 'zod' export const SignupFormSchema = z.object({ name: z .string() - .min(2, { message: 'Name must be at least 2 characters long.' }) + .min(2, { message: '名前は2文字以上である必要があります。' }) + .trim(), + email: z + .string() + .email({ message: '有効なメールアドレスを入力してください。' }) .trim(), - email: z.string().email({ message: 'Please enter a valid email.' }).trim(), password: z .string() - .min(8, { message: 'Be at least 8 characters long' }) - .regex(/[a-zA-Z]/, { message: 'Contain at least one letter.' }) - .regex(/[0-9]/, { message: 'Contain at least one number.' }) + .min(8, { message: '8文字以上である必要があります。' }) + .regex(/[a-zA-Z]/, { message: '少なくとも1文字を含める必要があります。' }) + .regex(/[0-9]/, { message: '少なくとも1つの数字を含める必要があります。' }) .regex(/[^a-zA-Z0-9]/, { - message: 'Contain at least one special character.', + message: '少なくとも1つの特殊文字を含める必要があります。', }) .trim(), }) @@ -163,16 +167,19 @@ import { z } from 'zod' export const SignupFormSchema = z.object({ name: z .string() - .min(2, { message: 'Name must be at least 2 characters long.' }) + .min(2, { message: '名前は2文字以上である必要があります。' }) + .trim(), + email: z + .string() + .email({ message: '有効なメールアドレスを入力してください。' }) .trim(), - email: z.string().email({ message: 'Please enter a valid email.' }).trim(), password: z .string() - .min(8, { message: 'Be at least 8 characters long' }) - .regex(/[a-zA-Z]/, { message: 'Contain at least one letter.' }) - .regex(/[0-9]/, { message: 'Contain at least one number.' }) + .min(8, { message: '8文字以上である必要があります。' }) + .regex(/[a-zA-Z]/, { message: '少なくとも1文字を含める必要があります。' }) + .regex(/[0-9]/, { message: '少なくとも1つの数字を含める必要があります。' }) .regex(/[^a-zA-Z0-9]/, { - message: 'Contain at least one special character.', + message: '少なくとも1つの特殊文字を含める必要があります。', }) .trim(), }) @@ -181,7 +188,7 @@ export const SignupFormSchema = z.object({ -フォームフィールドが定義されたスキーマに一致しない場合、認証プロバイダーのAPIやデータベースへの不要な呼び出しを防ぐために、Server Actionで早期に`return`することができます。 +認証プロバイダーのAPIやデータベースへの不要な呼び出しを防ぐために、定義されたスキーマに一致しないフォームフィールドがある場合は、Server Actionで早期に`return`することができます。 @@ -197,7 +204,7 @@ export async function signup(state: FormState, formData: FormData) { password: formData.get('password'), }) - // フォームフィールドが無効な場合、早期にreturnする + // フォームフィールドが無効な場合は早期にreturnする if (!validatedFields.success) { return { errors: validatedFields.error.flatten().fieldErrors, @@ -222,7 +229,7 @@ export async function signup(state, formData) { password: formData.get('password'), }) - // フォームフィールドが無効な場合、早期にreturnする + // フォームフィールドが無効な場合は早期にreturnする if (!validatedFields.success) { return { errors: validatedFields.error.flatten().fieldErrors, @@ -377,7 +384,7 @@ export async function signup(state: FormState, formData: FormData) { if (!user) { return { - message: 'An error occurred while creating your account.', + message: 'アカウントの作成中にエラーが発生しました。', } } @@ -414,7 +421,7 @@ export async function signup(state, formData) { if (!user) { return { - message: 'An error occurred while creating your account.', + message: 'アカウントの作成中にエラーが発生しました。', } } @@ -427,12 +434,12 @@ export async function signup(state, formData) { -ユーザーアカウントの作成またはユーザー資格情報の確認が成功した後、ユーザーの認証状態を管理するためにセッションを作成できます。セッション管理戦略に応じて、セッションはcookieまたはデータベース、またはその両方に保存できます。[Session Management](#session-management)セクションに進んで詳細を学びましょう。 +ユーザーアカウントの作成またはユーザー資格情報の確認が成功した後、ユーザーの認証状態を管理するためのセッションを作成できます。セッション管理戦略に応じて、セッションはcookieまたはデータベース、またはその両方に保存できます。[Session Management](#session-management)セクションに進んで詳細を学びましょう。 > **Tips:** > -> - 上記の例は教育目的で認証ステップを詳細に説明しているため冗長です。独自の安全なソリューションを実装することはすぐに複雑になる可能性があることを強調しています。プロセスを簡素化するために[Auth Library](#auth-libraries)の使用を検討してください。 -> - ユーザーエクスペリエンスを向上させるために、登録フローの早い段階で重複するメールアドレスやユーザー名を確認することを検討してください。たとえば、ユーザーがユーザー名を入力しているときや入力フィールドがフォーカスを失ったときです。これにより、不要なフォーム送信を防ぎ、ユーザーに即時のフィードバックを提供できます。[use-debounce](https://www.npmjs.com/package/use-debounce)などのライブラリを使用して、これらのチェックの頻度を管理することができます。 +> - 上記の例は教育目的で認証ステップを分解しているため冗長です。独自の安全なソリューションを実装することはすぐに複雑になる可能性があることを強調しています。プロセスを簡素化するために[Auth Library](#auth-libraries)の使用を検討してください。 +> - ユーザーエクスペリエンスを向上させるために、登録フローの早い段階で重複するメールアドレスやユーザー名を確認することを検討してください。たとえば、ユーザーがユーザー名を入力しているときや入力フィールドがフォーカスを失ったときに行うことができます。これにより、不要なフォーム送信を防ぎ、ユーザーに即時のフィードバックを提供できます。これらのチェックの頻度を管理するために、[use-debounce](https://www.npmjs.com/package/use-debounce)などのライブラリを使用してリクエストをデバウンスすることができます。 @@ -440,8 +447,8 @@ export async function signup(state, formData) { サインアップおよび/またはログインフォームを実装する手順は次のとおりです: -1. ユーザーがフォームを通じて資格情報を送信します。 -2. フォームはAPIルートによって処理されるリクエストを送信します。 +1. ユーザーはフォームを通じて資格情報を送信します。 +2. フォームはAPIルートで処理されるリクエストを送信します。 3. 検証が成功すると、プロセスが完了し、ユーザーの認証が成功したことを示します。 4. 検証が失敗した場合、エラーメッセージが表示されます。 @@ -530,9 +537,9 @@ export default function LoginPage() { -上記のフォームには、ユーザーのメールアドレスとパスワードをキャプチャするための2つの入力フィールドがあります。送信時に、APIルート(`/api/auth/login`)にPOSTリクエストを送信する関数をトリガーします。 +上記のフォームには、ユーザーのメールアドレスとパスワードをキャプチャするための2つの入力フィールドがあります。送信時に、`/api/auth/login`というAPIルートにPOSTリクエストを送信する関数をトリガーします。 -次に、APIルートで認証を処理するために認証プロバイダーのAPIを呼び出すことができます: +その後、APIルートで認証プロバイダーのAPIを呼び出して認証を処理できます: @@ -552,9 +559,9 @@ export default async function handler( res.status(200).json({ success: true }) } catch (error) { if (error.type === 'CredentialsSignin') { - res.status(401).json({ error: 'Invalid credentials.' }) + res.status(401).json({ error: '無効な資格情報です。' }) } else { - res.status(500).json({ error: 'Something went wrong.' }) + res.status(500).json({ error: '何かがうまくいきませんでした。' }) } } } @@ -574,9 +581,9 @@ export default async function handler(req, res) { res.status(200).json({ success: true }) } catch (error) { if (error.type === 'CredentialsSignin') { - res.status(401).json({ error: 'Invalid credentials.' }) + res.status(401).json({ error: '無効な資格情報です。' }) } else { - res.status(500).json({ error: 'Something went wrong.' }) + res.status(500).json({ error: '何かがうまくいきませんでした。' }) } } } @@ -587,28 +594,28 @@ export default async function handler(req, res) { -## Session Management {#session-management} +## セッション管理 {#session-management} セッション管理は、ユーザーの認証された状態をリクエスト間で保持することを保証します。セッションまたはトークンの作成、保存、更新、削除を含みます。 セッションには2つのタイプがあります: -1. [**Stateless**](#stateless-sessions): セッションデータ(またはトークン)はブラウザのcookieに保存されます。cookieは各リクエストと共に送信され、サーバーでセッションを検証できます。この方法はシンプルですが、正しく実装されないとセキュリティが低くなる可能性があります。 -2. [**Database**](#database-sessions): セッションデータはデータベースに保存され、ユーザーのブラウザには暗号化されたセッションIDのみが送信されます。この方法はより安全ですが、複雑でサーバーリソースを多く使用する可能性があります。 +1. [**ステートレス**](#stateless-sessions): セッションデータ(またはトークン)はブラウザのcookieに保存されます。cookieは各リクエストと共に送信され、サーバーでセッションを検証できます。この方法はシンプルですが、正しく実装されないとセキュリティが低くなる可能性があります。 +2. [**データベース**](#database-sessions): セッションデータはデータベースに保存され、ユーザーのブラウザには暗号化されたセッションIDのみが送信されます。この方法はより安全ですが、複雑でサーバーリソースを多く使用する可能性があります。 -> **Good to know:** どちらの方法も使用できますが、[iron-session](https://github.com/vvo/iron-session)や[Jose](https://github.com/panva/jose)などのセッション管理ライブラリを使用することをお勧めします。 +> **Good to know:** どちらの方法も使用できますが、または両方を使用できますが、[iron-session](https://github.com/vvo/iron-session)や[Jose](https://github.com/panva/jose)などのセッション管理ライブラリを使用することをお勧めします。 -### Stateless Sessions {#stateless-sessions} +### ステートレスセッション {#stateless-sessions} ステートレスセッションを作成および管理するには、次の手順を実行する必要があります: -1. セッションを署名するために使用される秘密鍵を生成し、[環境変数](/docs/app/building-your-application/configuring/environment-variables)として保存します。 +1. セッションを署名するために使用される秘密鍵を生成し、[環境変数](/docs/app/guides/environment-variables)として保存します。 2. セッション管理ライブラリを使用してセッションデータを暗号化/復号化するロジックを記述します。 3. Next.jsの[`cookies`](/docs/app/api-reference/functions/cookies) APIを使用してcookieを管理します。 -上記に加えて、ユーザーがアプリケーションに戻ったときにセッションを[更新(またはリフレッシュ)](#updating-or-refreshing-sessions)し、ユーザーがログアウトしたときにセッションを[削除](#deleting-the-session)する機能を追加することを検討してください。 +上記に加えて、ユーザーがアプリケーションに戻ったときにセッションを[更新(またはリフレッシュ)](#updating-or-refreshing-sessions)する機能を追加し、ユーザーがログアウトしたときにセッションを[削除](#deleting-the-session)することを検討してください。 > **Good to know:** [auth library](#auth-libraries)がセッション管理を含んでいるかどうかを確認してください。 @@ -620,13 +627,13 @@ export default async function handler(req, res) { openssl rand -base64 32 ``` -このコマンドは、秘密鍵として使用できる32文字のランダムな文字列を生成し、[環境変数ファイル](/docs/app/building-your-application/configuring/environment-variables)に保存します: +このコマンドは、秘密鍵として使用できる32文字のランダムな文字列を生成し、[環境変数ファイル](/docs/app/guides/environment-variables)に保存します: ```bash title=".env" SESSION_SECRET=your_secret_key ``` -次に、この鍵をセッション管理ロジックで参照できます: +その後、この鍵をセッション管理ロジックで参照できます: ```js title="app/lib/session.js" const secretKey = process.env.SESSION_SECRET @@ -662,7 +669,7 @@ export async function decrypt(session: string | undefined = '') { }) return payload } catch (error) { - console.log('Failed to verify session') + console.log('セッションの検証に失敗しました') } } ``` @@ -692,7 +699,7 @@ export async function decrypt(session) { }) return payload } catch (error) { - console.log('Failed to verify session') + console.log('セッションの検証に失敗しました') } } ``` @@ -702,7 +709,7 @@ export async function decrypt(session) { > **Tips**: > -> - ペイロードには、ユーザーIDや役割など、後続のリクエストで使用される**最小限の**一意のユーザーデータを含める必要があります。電話番号、メールアドレス、クレジットカード情報などの個人を特定できる情報や、パスワードなどの機密データを含めるべきではありません。 +> - ペイロードには、ユーザーのIDや役割など、後続のリクエストで使用される**最小限の**一意のユーザーデータを含める必要があります。電話番号、メールアドレス、クレジットカード情報などの個人を特定できる情報や、パスワードなどの機密データを含めるべきではありません。 #### 3. Cookieの設定(推奨オプション) {#3-setting-cookies-recommended-options} @@ -710,7 +717,7 @@ export async function decrypt(session) { - **HttpOnly**: クライアント側のJavaScriptがcookieにアクセスするのを防ぎます。 - **Secure**: httpsを使用してcookieを送信します。 -- **SameSite**: cookieがクロスサイトリクエストで送信できるかどうかを指定します。 +- **SameSite**: cookieがクロスサイトリクエストと共に送信できるかどうかを指定します。 - **Max-AgeまたはExpires**: 一定期間後にcookieを削除します。 - **Path**: cookieのURLパスを定義します。 @@ -877,7 +884,7 @@ export async function updateSession() { -> **Tip:** 認証ライブラリがリフレッシュトークンをサポートしているかどうかを確認してください。これにより、ユーザーのセッションを延長することができます。 +> **Tip:** 認証ライブラリがリフレッシュトークンをサポートしているかどうかを確認してください。これにより、ユーザーのセッションを延長できます。 #### セッションの削除 {#deleting-the-session} @@ -912,7 +919,7 @@ export async function deleteSession() { -次に、アプリケーションで`deleteSession()`関数を再利用できます。たとえば、ログアウト時に: +その後、アプリケーション内で`deleteSession()`関数を再利用できます。たとえば、ログアウト時に: @@ -970,7 +977,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { path: '/', }) res.setHeader('Set-Cookie', cookie) - res.status(200).json({ message: 'Successfully set cookie!' }) + res.status(200).json({ message: 'Cookieが正常に設定されました!' }) } ``` @@ -992,7 +999,7 @@ export default function handler(req, res) { path: '/', }) res.setHeader('Set-Cookie', cookie) - res.status(200).json({ message: 'Successfully set cookie!' }) + res.status(200).json({ message: 'Cookieが正常に設定されました!' }) } ``` @@ -1001,7 +1008,7 @@ export default function handler(req, res) { -### Database Sessions {#database-sessions} +### データベースセッション {#database-sessions} データベースセッションを作成および管理するには、次の手順を実行する必要があります: @@ -1011,7 +1018,7 @@ export default function handler(req, res) { -例: +たとえば: @@ -1095,9 +1102,9 @@ export async function createSession(id) { > **Tips**: > > - データの取得を高速化するために、[Vercel Redis](https://vercel.com/docs/storage/vercel-kv)のようなデータベースを使用することを検討してください。ただし、セッションデータをプライマリデータベースに保持し、データリクエストを組み合わせてクエリの数を減らすこともできます。 -> - より高度なユースケースのためにデータベースセッションを使用することを選択するかもしれません。たとえば、ユーザーが最後にログインした時間を追跡したり、アクティブなデバイスの数を追跡したり、ユーザーにすべてのデバイスからログアウトする機能を提供したりすることができます。 +> - より高度なユースケースのためにデータベースセッションを使用することを選択することができます。たとえば、ユーザーが最後にログインした時間やアクティブなデバイスの数を追跡したり、ユーザーにすべてのデバイスからログアウトする機能を提供したりすることができます。 -セッション管理を実装した後、アプリケーション内でユーザーがアクセスできるものとできることを制御するための認可ロジックを追加する必要があります。[Authorization](#authorization)セクションに進んで詳細を学びましょう。 +セッション管理を実装した後、アプリケーション内でユーザーがアクセスできる内容と実行できる操作を制御するための認可ロジックを追加する必要があります。[Authorization](#authorization)セクションに進んで詳細を学びましょう。 @@ -1127,7 +1134,7 @@ export default async function handler( res.status(200).json({ sessionId }) } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) + res.status(500).json({ error: '内部サーバーエラー' }) } } ``` @@ -1150,7 +1157,7 @@ export default async function handler(req, res) { res.status(200).json({ sessionId }) } catch (error) { - res.status(500).json({ error: 'Internal Server Error' }) + res.status(500).json({ error: '内部サーバーエラー' }) } } ``` @@ -1160,31 +1167,31 @@ export default async function handler(req, res) { -## Authorization {#authorization} +## 認可 {#authorization} -ユーザーが認証され、セッションが作成された後、アプリケーション内でユーザーがアクセスできるものとできることを制御するために認可を実装できます。 +ユーザーが認証され、セッションが作成された後、アプリケーション内でユーザーがアクセスできる内容と実行できる操作を制御するために認可を実装できます。 -認可チェックには2つの主要なタイプがあります: +認可チェックには2つの主なタイプがあります: -1. **Optimistic**: cookieに保存されたセッションデータを使用して、ユーザーがルートにアクセスしたりアクションを実行したりする権限があるかどうかを確認します。これらのチェックは、UI要素の表示/非表示や、権限や役割に基づくユーザーのリダイレクトなどの迅速な操作に役立ちます。 -2. **Secure**: データベースに保存されたセッションデータを使用して、ユーザーがルートにアクセスしたりアクションを実行したりする権限があるかどうかを確認します。これらのチェックはより安全で、機密データやアクションへのアクセスが必要な操作に使用されます。 +1. **楽観的**: cookieに保存されたセッションデータを使用して、ユーザーがルートにアクセスしたりアクションを実行したりする権限があるかどうかを確認します。これらのチェックは、UI要素の表示/非表示や、権限や役割に基づいてユーザーをリダイレクトするなどの迅速な操作に役立ちます。 +2. **セキュア**: データベースに保存されたセッションデータを使用して、ユーザーがルートにアクセスしたりアクションを実行したりする権限があるかどうかを確認します。これらのチェックはより安全で、機密データやアクションへのアクセスが必要な操作に使用されます。 どちらの場合も、次のことをお勧めします: -- 認可ロジックを集中化するための[Data Access Layer](#creating-a-data-access-layer-dal)を作成する -- 必要なデータのみを返すために[Data Transfer Objects (DTO)](#using-data-transfer-objects-dto)を使用する -- 楽観的なチェックを行うために[Middleware](#optimistic-checks-with-middleware-optional)をオプションで使用する。 +- 認可ロジックを集中化するために[データアクセス層(DAL)](#creating-a-data-access-layer-dal)を作成する +- 必要なデータのみを返すために[データ転送オブジェクト(DTO)](#using-data-transfer-objects-dto)を使用する +- オプションで[Middleware](#optimistic-checks-with-middleware-optional)を使用して楽観的なチェックを実行する。 -### 楽観的なチェックを行うMiddleware(オプション) {#optimistic-checks-with-middleware-optional} +### Middlewareを使用した楽観的なチェック(オプション) {#optimistic-checks-with-middleware-optional} [Middleware](/docs/app/building-your-application/routing/middleware)を使用して、権限に基づいてユーザーをリダイレクトする場合があります: -- 楽観的なチェックを行うため。Middlewareはすべてのルートで実行されるため、リダイレクトロジックを集中化し、許可されていないユーザーを事前にフィルタリングするのに適しています。 +- 楽観的なチェックを実行するため。Middlewareはすべてのルートで実行されるため、リダイレクトロジックを集中化し、許可されていないユーザーを事前にフィルタリングするのに適しています。 - ユーザー間でデータを共有する静的ルートを保護するため(例:ペイウォールの背後にあるコンテンツ)。 -ただし、Middlewareはすべてのルートで実行され、[prefetched](/docs/app/building-your-application/routing/linking-and-navigating#2-prefetching)ルートも含まれるため、パフォーマンスの問題を防ぐために、cookieからセッションを読み取るだけにする(楽観的なチェック)ことが重要です。データベースチェックを避けることが重要です。 +ただし、Middlewareはすべてのルートで実行され、[prefetched](/docs/app/building-your-application/routing/linking-and-navigating#2-prefetching)ルートも含まれるため、パフォーマンスの問題を防ぐためにcookieからセッションを読み取るだけにする(楽観的なチェック)ことが重要です。データベースチェックを避けることが重要です。 -例: +たとえば: @@ -1208,12 +1215,12 @@ export default async function middleware(req: NextRequest) { const cookie = (await cookies()).get('session')?.value const session = await decrypt(cookie) - // 4. ユーザーが認証されていない場合、/loginにリダイレクトする + // 4. ユーザーが認証されていない場合は/loginにリダイレクトする if (isProtectedRoute && !session?.userId) { return NextResponse.redirect(new URL('/login', req.nextUrl)) } - // 5. ユーザーが認証されている場合、/dashboardにリダイレクトする + // 5. ユーザーが認証されている場合は/dashboardにリダイレクトする if ( isPublicRoute && session?.userId && @@ -1253,12 +1260,12 @@ export default async function middleware(req) { const cookie = (await cookies()).get('session')?.value const session = await decrypt(cookie) - // 5. ユーザーが認証されていない場合、/loginにリダイレクトする + // 5. ユーザーが認証されていない場合は/loginにリダイレクトする if (isProtectedRoute && !session?.userId) { return NextResponse.redirect(new URL('/login', req.nextUrl)) } - // 6. ユーザーが認証されている場合、/dashboardにリダイレクトする + // 6. ユーザーが認証されている場合は/dashboardにリダイレクトする if ( isPublicRoute && session?.userId && @@ -1279,7 +1286,7 @@ export const config = { -Middlewareは初期チェックに役立ちますが、データを保護するための唯一の防御手段として使用すべきではありません。セキュリティチェックの大部分は、データソースにできるだけ近い場所で実行する必要があります。詳細については、[Data Access Layer](#creating-a-data-access-layer-dal)を参照してください。 +Middlewareは初期チェックに役立ちますが、データを保護するための唯一の防御手段として使用すべきではありません。セキュリティチェックの大部分は、データソースにできるだけ近い場所で実行する必要があります。詳細については[データアクセス層(DAL)](#creating-a-data-access-layer-dal)を参照してください。 > **Tips**: > @@ -1289,13 +1296,13 @@ Middlewareは初期チェックに役立ちますが、データを保護する -### Data Access Layer (DAL)の作成 {#creating-a-data-access-layer-dal} +### データアクセス層(DAL)の作成 {#creating-a-data-access-layer-dal} データリクエストと認可ロジックを集中化するためにDALを作成することをお勧めします。 DALには、アプリケーションと対話する際にユーザーのセッションを検証する関数を含める必要があります。少なくとも、関数はセッションが有効かどうかを確認し、ユーザー情報を返すか、リダイレクトする必要があります。 -たとえば、DAL用の別のファイルを作成し、`verifySession()`関数を含めます。次に、Reactの[cache](https://react.dev/reference/react/cache) APIを使用して、Reactのレンダーパス中に関数の戻り値をメモ化します: +たとえば、DAL用の別のファイルを作成し、`verifySession()`関数を含めます。その後、Reactの[cache](https://react.dev/reference/react/cache) APIを使用して、Reactのレンダリングパス中に関数の戻り値をメモ化します: @@ -1342,7 +1349,7 @@ export const verifySession = cache(async () => { -次に、データリクエスト、Server Actions、Route Handlersで`verifySession()`関数を呼び出すことができます: +その後、データリクエスト、Server Actions、Route Handlersで`verifySession()`関数を呼び出すことができます: @@ -1355,7 +1362,7 @@ export const getUser = cache(async () => { try { const data = await db.query.users.findMany({ where: eq(users.id, session.userId), - // 必要なカラムのみを明示的に返す + // 必要な列を明示的に返す columns: { id: true, name: true, @@ -1367,7 +1374,7 @@ export const getUser = cache(async () => { return user } catch (error) { - console.log('Failed to fetch user') + console.log('ユーザーの取得に失敗しました') return null } }) @@ -1384,7 +1391,7 @@ export const getUser = cache(async () => { try { const data = await db.query.users.findMany({ where: eq(users.id, session.userId), - // 必要なカラムのみを明示的に返す + // 必要な列を明示的に返す columns: { id: true, name: true, @@ -1396,7 +1403,7 @@ export const getUser = cache(async () => { return user } catch (error) { - console.log('Failed to fetch user') + console.log('ユーザーの取得に失敗しました') return null } }) @@ -1407,15 +1414,15 @@ export const getUser = cache(async () => { > **Tip**: > -> - DALはリクエスト時にデータを保護するために使用できます。ただし、ユーザー間でデータを共有する静的ルートの場合、データはビルド時にフェッチされ、リクエスト時にはフェッチされません。[Middleware](#optimistic-checks-with-middleware-optional)を使用して静的ルートを保護します。 -> - セキュアなチェックのために、セッションIDをデータベースと比較してセッションが有効かどうかを確認できます。Reactの[cache](https://react.dev/reference/react/cache)関数を使用して、レンダーパス中にデータベースへの不要な重複リクエストを回避します。 -> - 関連するデータリクエストをJavaScriptクラスに統合し、メソッドを実行する前に`verifySession()`を実行することを検討するかもしれません。 +> - DALはリクエスト時にデータを保護するために使用できます。ただし、ユーザー間でデータを共有する静的ルートの場合、データはビルド時に取得され、リクエスト時には取得されません。[Middleware](#optimistic-checks-with-middleware-optional)を使用して静的ルートを保護します。 +> - セキュアなチェックのために、データベースとセッションIDを比較してセッションが有効かどうかを確認できます。Reactの[cache](https://react.dev/reference/react/cache)関数を使用して、レンダリングパス中にデータベースへの不要な重複リクエストを避けます。 +> - 関連するデータリクエストをJavaScriptクラスに統合し、メソッドを実行する前に`verifySession()`を実行することを検討することができます。 -### Data Transfer Objects (DTO)の使用 {#using-data-transfer-objects-dto} +### データ転送オブジェクト(DTO)の使用 {#using-data-transfer-objects-dto} -データを取得する際には、アプリケーションで使用される必要なデータのみを返し、オブジェクト全体を返さないことをお勧めします。たとえば、ユーザーデータをフェッチする場合、ユーザーのIDと名前のみを返し、パスワードや電話番号などを含むユーザーオブジェクト全体を返さないかもしれません。 +データを取得する際には、アプリケーションで使用される必要なデータのみを返し、オブジェクト全体を返さないことをお勧めします。たとえば、ユーザーデータを取得する場合、ユーザーのIDと名前のみを返し、パスワードや電話番号などを含むユーザーオブジェクト全体を返さないかもしれません。 -ただし、返されるデータ構造を制御できない場合や、チームで作業している場合で、クライアントに全体のオブジェクトが渡されるのを避けたい場合は、クライアントに公開しても安全なフィールドを指定するなどの戦略を使用できます。 +ただし、返されるデータ構造を制御できない場合や、チームで作業していてクライアントにオブジェクト全体が渡されるのを避けたい場合は、クライアントに公開するフィールドを指定するなどの戦略を使用できます。 @@ -1435,13 +1442,13 @@ function canSeePhoneNumber(viewer: User, team: string) { export async function getProfileDTO(slug: string) { const data = await db.query.users.findMany({ where: eq(users.slug, slug), - // 特定のカラムをここで返す + // ここで特定の列を返す }) const user = data[0] const currentUser = await getUser(user.id) - // または、クエリに特化したものをここで返す + // またはここでクエリに特化したものを返す return { username: canSeeUsername(currentUser) ? user.username : null, phonenumber: canSeePhoneNumber(currentUser, user.team) @@ -1469,13 +1476,13 @@ function canSeePhoneNumber(viewer, team) { export async function getProfileDTO(slug) { const data = await db.query.users.findMany({ where: eq(users.slug, slug), - // 特定のカラムをここで返す + // ここで特定の列を返す }) const user = data[0] const currentUser = await getUser(user.id) - // または、クエリに特化したものをここで返す + // またはここでクエリに特化したものを返す return { username: canSeeUsername(currentUser) ? user.username : null, phonenumber: canSeePhoneNumber(currentUser, user.team) @@ -1488,16 +1495,16 @@ export async function getProfileDTO(slug) { -データリクエストと認可ロジックをDALに集中化し、DTOを使用することで、すべてのデータリクエストが安全で一貫性があることを保証し、アプリケーションがスケールするにつれて、メンテナンス、監査、デバッグが容易になります。 +データリクエストと認可ロジックをDALに集中化し、DTOを使用することで、すべてのデータリクエストが安全で一貫性があり、アプリケーションがスケールするにつれてメンテナンス、監査、デバッグが容易になります。 > **Good to know**: > -> - DTOを定義する方法はいくつかあります。`toJSON()`を使用する方法、上記の例のように個別の関数を使用する方法、またはJSクラスを使用する方法です。これらはJavaScriptのパターンであり、ReactやNext.jsの機能ではないため、アプリケーションに最適なパターンを見つけるために調査することをお勧めします。 +> - DTOを定義する方法はいくつかあります。`toJSON()`を使用する方法、上記の例のような個別の関数、またはJSクラスなどです。これらはJavaScriptのパターンであり、ReactやNext.jsの機能ではないため、アプリケーションに最適なパターンを見つけるために調査することをお勧めします。 > - [Security in Next.js article](https://nextjs.org/blog/security-nextjs-server-components-actions)でセキュリティのベストプラクティスについて詳しく学びましょう。 ### Server Components {#server-components} -[Server Components](/docs/app/building-your-application/rendering/server-components)での認証チェックは、役割ベースのアクセスに役立ちます。たとえば、ユーザーの役割に基づいてコンポーネントを条件付きでレンダリングする場合: +[Server Components](/docs/app/building-your-application/rendering/server-components)での認証チェックは、役割ベースのアクセスに役立ちます。たとえば、ユーザーの役割に基づいてコンポーネントを条件付きでレンダリングするために: @@ -1550,9 +1557,9 @@ export default function Dashboard() { 代わりに、データソースや条件付きでレンダリングされるコンポーネントに近い場所でチェックを行うべきです。 -たとえば、ユーザーデータをフェッチし、ナビゲーションでユーザー画像を表示する共有レイアウトを考えてみましょう。レイアウトで認証チェックを行う代わりに、レイアウトでユーザーデータ(`getUser()`)をフェッチし、DALで認証チェックを行うべきです。 +たとえば、ユーザーデータを取得し、ナビゲーションにユーザー画像を表示する共有レイアウトを考えてみましょう。レイアウトで認証チェックを行う代わりに、レイアウトでユーザーデータ(`getUser()`)を取得し、DALで認証チェックを行うべきです。 -これにより、アプリケーション内で`getUser()`が呼び出される場所で認証チェックが実行され、開発者がデータにアクセスするためにユーザーが認可されていることを確認するのを忘れることを防ぎます。 +これにより、アプリケーション内で`getUser()`が呼び出される場所で認証チェックが実行され、開発者がデータにアクセスするためにユーザーが認証されていることを確認するのを忘れることを防ぎます。 @@ -1595,7 +1602,7 @@ export const getUser = cache(async () => { const session = await verifySession() if (!session) return null - // セッションからユーザーIDを取得し、データをフェッチする + // セッションからユーザーIDを取得し、データを取得する }) ``` @@ -1607,7 +1614,7 @@ export const getUser = cache(async () => { const session = await verifySession() if (!session) return null - // セッションからユーザーIDを取得し、データをフェッチする + // セッションからユーザーIDを取得し、データを取得する }) ``` @@ -1616,7 +1623,7 @@ export const getUser = cache(async () => { > **Good to know:** > -> - SPAで一般的なパターンは、ユーザーが認可されていない場合にレイアウトやトップレベルコンポーネントで`return null`を返すことです。このパターンは**推奨されません**。Next.jsアプリケーションには複数のエントリーポイントがあり、これによりネストされたルートセグメントやServer Actionsへのアクセスが防止されないためです。 +> - SPAで一般的なパターンは、ユーザーが認証されていない場合にレイアウトやトップレベルコンポーネントで`return null`することです。このパターンは**推奨されません**。Next.jsアプリケーションには複数のエントリーポイントがあり、これによりネストされたルートセグメントやServer Actionsへのアクセスが防止されないためです。 ### Server Actions {#server-actions} @@ -1635,7 +1642,7 @@ export async function serverAction(formData: FormData) { const session = await verifySession() const userRole = session?.user?.role - // ユーザーがアクションを実行する権限がない場合、早期にreturnする + // ユーザーがアクションを実行する権限がない場合は早期にreturnする if (userRole !== 'admin') { return null } @@ -1655,7 +1662,7 @@ export async function serverAction() { const session = await verifySession() const userRole = session.user.role - // ユーザーがアクションを実行する権限がない場合、早期にreturnする + // ユーザーがアクションを実行する権限がない場合は早期にreturnする if (userRole !== 'admin') { return null } @@ -1671,7 +1678,7 @@ export async function serverAction() { [Route Handlers](/docs/app/building-your-application/routing/route-handlers)を公開APIエンドポイントと同じセキュリティ考慮事項で扱い、ユーザーがRoute Handlerにアクセスする権限があるかどうかを確認します。 -例: +たとえば: @@ -1683,19 +1690,19 @@ export async function GET() { // ユーザー認証と役割の確認 const session = await verifySession() - // ユーザーが認証されているか確認 + // ユーザーが認証されているかどうかを確認する if (!session) { - // ユーザーが認証されていない + // ユーザーは認証されていない return new Response(null, { status: 401 }) } - // ユーザーが'admin'役割を持っているか確認 + // ユーザーが'admin'役割を持っているかどうかを確認する if (session.user.role !== 'admin') { // ユーザーは認証されているが、適切な権限を持っていない return new Response(null, { status: 403 }) } - // 認可されたユーザーのために続行 + // 認可されたユーザーのために続行する } ``` @@ -1709,30 +1716,30 @@ export async function GET() { // ユーザー認証と役割の確認 const session = await verifySession() - // ユーザーが認証されているか確認 + // ユーザーが認証されているかどうかを確認する if (!session) { - // ユーザーが認証されていない + // ユーザーは認証されていない return new Response(null, { status: 401 }) } - // ユーザーが'admin'役割を持っているか確認 + // ユーザーが'admin'役割を持っているかどうかを確認する if (session.user.role !== 'admin') { // ユーザーは認証されているが、適切な権限を持っていない return new Response(null, { status: 403 }) } - // 認可されたユーザーのために続行 + // 認可されたユーザーのために続行する } ``` -上記の例は、2段階のセキュリティチェックを備えたRoute Handlerを示しています。最初にアクティブなセッションを確認し、次にログインしているユーザーが'admin'であるかどうかを確認します。 +上記の例は、2段階のセキュリティチェックを備えたRoute Handlerを示しています。まず、アクティブなセッションを確認し、次にログインしているユーザーが'admin'であるかどうかを確認します。 -## Context Providers {#context-providers} +## コンテキストプロバイダー {#context-providers} -認証のためのコンテキストプロバイダーの使用は、[interleaving](/docs/app/building-your-application/rendering/composition-patterns#interleaving-server-and-client-components)のおかげで機能します。ただし、Reactの`context`はServer Componentsではサポートされていないため、Client Componentsにのみ適用されます。 +認証のためにコンテキストプロバイダーを使用することは、[インタリーブ](/docs/app/building-your-application/rendering/composition-patterns#interleaving-server-and-client-components)のおかげで機能します。ただし、Reactの`context`はServer Componentsでサポートされていないため、Client Componentsにのみ適用されます。 これは機能しますが、子Server Componentsは最初にサーバー上でレンダリングされ、コンテキストプロバイダーのセッションデータにアクセスできません: @@ -1786,19 +1793,19 @@ export default function Profile() { } ``` -クライアントコンポーネントでセッションデータが必要な場合(例:クライアントサイドのデータフェッチ)、Reactの[`taintUniqueValue`](https://react.dev/reference/react/experimental_taintUniqueValue) APIを使用して、クライアントに機密セッションデータが公開されないようにします。 +セッションデータがClient Componentsで必要な場合(例:クライアントサイドのデータフェッチング)、Reactの[`taintUniqueValue`](https://react.dev/reference/react/experimental_taintUniqueValue) APIを使用して、クライアントに機密セッションデータが公開されないようにします。 -### Data Access Layer (DAL)の作成 {#creating-a-data-access-layer-dal} +### データアクセス層(DAL)の作成 {#creating-a-data-access-layer-dal} -#### API Routesの保護 {#protecting-api-routes} +#### APIルートの保護 {#protecting-api-routes} -Next.jsのAPI Routesは、サーバーサイドのロジックとデータ管理を処理するために不可欠です。これらのルートを保護し、特定の機能にアクセスできるのは認可されたユーザーのみであることを確認することが重要です。これには通常、ユーザーの認証状態と役割ベースの権限を確認することが含まれます。 +Next.jsのAPIルートは、サーバーサイドのロジックとデータ管理を処理するために不可欠です。これらのルートを保護し、特定の機能にアクセスできるのは認可されたユーザーのみであることを確認することが重要です。これには通常、ユーザーの認証状態と役割ベースの権限を確認することが含まれます。 -API Routeを保護する例を示します: +APIルートを保護する例を示します: @@ -1812,24 +1819,24 @@ export default async function handler( ) { const session = await getSession(req) - // ユーザーが認証されているか確認 + // ユーザーが認証されているかどうかを確認する if (!session) { res.status(401).json({ - error: 'User is not authenticated', + error: 'ユーザーは認証されていません', }) return } - // ユーザーが'admin'役割を持っているか確認 + // ユーザーが'admin'役割を持っているかどうかを確認する if (session.user.role !== 'admin') { res.status(401).json({ - error: 'Unauthorized access: User does not have admin privileges.', + error: '未承認のアクセス:ユーザーは管理者権限を持っていません。', }) return } - // 認可されたユーザーのためにルートを続行 - // ... API Routeの実装 + // 認可されたユーザーのためにルートを続行する + // ... APIルートの実装 } ``` @@ -1840,39 +1847,39 @@ export default async function handler( export default async function handler(req, res) { const session = await getSession(req) - // ユーザーが認証されているか確認 + // ユーザーが認証されているかどうかを確認する if (!session) { res.status(401).json({ - error: 'User is not authenticated', + error: 'ユーザーは認証されていません', }) return } - // ユーザーが'admin'役割を持っているか確認 + // ユーザーが'admin'役割を持っているかどうかを確認する if (session.user.role !== 'admin') { - res.status: 401).json({ - error: 'Unauthorized access: User does not have admin privileges.', + res.status(401).json({ + error: '未承認のアクセス:ユーザーは管理者権限を持っていません。', }) return } - // 認可されたユーザーのためにルートを続行 - // ... API Routeの実装 + // 認可されたユーザーのためにルートを続行する + // ... APIルートの実装 } ``` -この例は、認証と認可のための2段階のセキュリティチェックを備えたAPI Routeを示しています。最初にアクティブなセッションを確認し、次にログインしているユーザーが'admin'であるかどうかを確認します。このアプローチは、リクエスト処理のために認証され、認可されたユーザーに限定された安全なアクセスを保証します。 +この例は、認証と認可の2段階のセキュリティチェックを備えたAPIルートを示しています。まず、アクティブなセッションを確認し、次にログインしているユーザーが'admin'であるかどうかを確認します。このアプローチは、リクエスト処理のために認証され、認可されたユーザーに限定された安全なアクセスを保証します。 -## Resources {#resources} +## リソース {#resources} -Next.jsでの認証について学んだ今、セキュアな認証とセッション管理を実装するのに役立つNext.js互換のライブラリとリソースを紹介します: +Next.jsでの認証について学んだ今、セキュアな認証とセッション管理を実装するのに役立つNext.js互換のライブラリとリソースを以下に示します: -### Auth Libraries {#auth-libraries} +### 認証ライブラリ {#auth-libraries} - [Auth0](https://auth0.com/docs/quickstart/webapp/nextjs/01-login) - [Clerk](https://clerk.com/docs/quickstarts/nextjs) @@ -1885,14 +1892,14 @@ Next.jsでの認証について学んだ今、セキュアな認証とセッシ - [Stytch](https://stytch.com/docs/guides/quickstarts/nextjs) - [WorkOS](https://workos.com/docs/user-management/nextjs) -### Session Management Libraries {#session-management-libraries} +### セッション管理ライブラリ {#session-management-libraries} - [Iron Session](https://github.com/vvo/iron-session) - [Jose](https://github.com/panva/jose) -## Further Reading {#further-reading} +## さらなる学習 {#further-reading} -認証とセキュリティについてさらに学ぶために、次のリソースをチェックしてください: +認証とセキュリティについて学び続けるために、以下のリソースをチェックしてください: - [How to think about security in Next.js](https://nextjs.org/blog/security-nextjs-server-components-actions) - [Understanding XSS Attacks](https://vercel.com/guides/understanding-xss-attacks) diff --git a/docs/01-app/02-guides/ci-build-caching.mdx b/docs/01-app/02-guides/ci-build-caching.mdx new file mode 100644 index 00000000..ebf93581 --- /dev/null +++ b/docs/01-app/02-guides/ci-build-caching.mdx @@ -0,0 +1,169 @@ +--- +title: 'Continuous Integration (CI) ビルドキャッシュの設定方法' +nav_title: 'CI ビルドキャッシュ' +description: 'Next.js ビルドをキャッシュするための CI の設定方法を学びます' +--- + +ビルドパフォーマンスを向上させるために、Next.js はビルド間で共有されるキャッシュを `.next/cache` に保存します。 + +このキャッシュをContinuous Integration (CI) 環境で活用するには、CI ワークフローを適切に設定してビルド間でキャッシュを永続化する必要があります。 + +> CI がビルド間で `.next/cache` を永続化するように設定されていない場合、[No Cache Detected](https://nextjs.org/docs/messages/no-cache) エラーが表示されることがあります。 + +以下は、一般的な CI プロバイダーのキャッシュ設定例です: + +## Vercel {#vercel} + +Next.js のキャッシングは自動的に設定されます。特に操作は必要ありません。Vercel で Turborepo を使用している場合は、[こちらをご覧ください](https://vercel.com/docs/monorepos/turborepo)。 + +## CircleCI {#circleci} + +`.circleci/config.yml` の `save_cache` ステップを編集して `.next/cache` を含めます: + +```yaml +steps: + - save_cache: + key: dependency-cache-{{ checksum "yarn.lock" }} + paths: + - ./node_modules + - ./.next/cache +``` + +`save_cache` キーがない場合は、CircleCI の[ビルドキャッシュ設定に関するドキュメント](https://circleci.com/docs/2.0/caching/)を参照してください。 + +## Travis CI {#travis-ci} + +以下を `.travis.yml` に追加またはマージします: + +```yaml +cache: + directories: + - $HOME/.cache/yarn + - node_modules + - .next/cache +``` + +## GitLab CI {#gitlab-ci} + +以下を `.gitlab-ci.yml` に追加またはマージします: + +```yaml +cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - node_modules/ + - .next/cache/ +``` + +## Netlify CI {#netlify-ci} + +[`@netlify/plugin-nextjs`](https://www.npmjs.com/package/@netlify/plugin-nextjs) を使用して [Netlify Plugins](https://www.netlify.com/products/build/plugins/) を利用します。 + +## AWS CodeBuild {#aws-codebuild} + +以下を `buildspec.yml` に追加(またはマージ)します: + +```yaml +cache: + paths: + - 'node_modules/**/*' # `yarn` または `npm i` の高速化のために `node_modules` をキャッシュ + - '.next/cache/**/*' # アプリケーションの再ビルドを高速化するために Next.js をキャッシュ +``` + +## GitHub Actions {#github-actions} + +GitHub の [actions/cache](https://github.com/actions/cache) を使用して、ワークフローファイルに以下のステップを追加します: + +```yaml +uses: actions/cache@v4 +with: + # `yarn`、`bun` または他のパッケージマネージャーでのキャッシュについては https://github.com/actions/cache/blob/main/examples.md を参照するか、actions/setup-node でのキャッシュを活用できます https://github.com/actions/setup-node + path: | + ~/.npm + ${{ github.workspace }}/.next/cache + # パッケージまたはソースファイルが変更されたときに新しいキャッシュを生成します。 + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + # ソースファイルが変更されてもパッケージが変更されていない場合、以前のキャッシュから再ビルドします。 + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- +``` + +## Bitbucket Pipelines {#bitbucket-pipelines} + +`bitbucket-pipelines.yml` のトップレベル(`pipelines` と同じレベル)に以下を追加またはマージします: + +```yaml +definitions: + caches: + nextcache: .next/cache +``` + +その後、パイプラインの `step` の `caches` セクションで参照します: + +```yaml +- step: + name: your_step_name + caches: + - node + - nextcache +``` + +## Heroku {#heroku} + +Heroku の[カスタムキャッシュ](https://devcenter.heroku.com/articles/nodejs-support#custom-caching)を使用して、トップレベルの package.json に `cacheDirectories` 配列を追加します: + +```javascript +"cacheDirectories": [".next/cache"] +``` + +## Azure Pipelines {#azure-pipelines} + +Azure Pipelines の [Cache task](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/cache) を使用して、`next build` を実行するタスクの前に以下のタスクをパイプライン yaml ファイルに追加します: + +```yaml +- task: Cache@2 + displayName: 'Cache .next/cache' + inputs: + key: next | $(Agent.OS) | yarn.lock + path: '$(System.DefaultWorkingDirectory)/.next/cache' +``` + +## Jenkins (Pipeline) {#jenkins-pipeline} + +Jenkins の [Job Cacher](https://www.jenkins.io/doc/pipeline/steps/jobcacher/) プラグインを使用して、通常 `next build` または `npm install` を実行する `Jenkinsfile` に以下のビルドステップを追加します: + +```yaml +stage("Restore npm packages") { + steps { + // GIT_COMMIT ハッシュに基づいてキャッシュにロックファイルを書き込みます + writeFile file: "next-lock.cache", text: "$GIT_COMMIT" + + cache(caches: [ + arbitraryFileCache( + path: "node_modules", + includes: "**/*", + cacheValidityDecidingFile: "package-lock.json" + ) + ]) { + sh "npm install" + } + } +} +stage("Build") { + steps { + // GIT_COMMIT ハッシュに基づいてキャッシュにロックファイルを書き込みます + writeFile file: "next-lock.cache", text: "$GIT_COMMIT" + + cache(caches: [ + arbitraryFileCache( + path: ".next/cache", + includes: "**/*", + cacheValidityDecidingFile: "next-lock.cache" + ) + ]) { + // つまり `next build` + sh "npm run build" + } + } +} +``` diff --git a/docs/01-app/03-building-your-application/07-configuring/15-content-security-policy.mdx b/docs/01-app/02-guides/content-security-policy.mdx similarity index 67% rename from docs/01-app/03-building-your-application/07-configuring/15-content-security-policy.mdx rename to docs/01-app/02-guides/content-security-policy.mdx index 4e47eec0..3fd30d0b 100644 --- a/docs/01-app/03-building-your-application/07-configuring/15-content-security-policy.mdx +++ b/docs/01-app/02-guides/content-security-policy.mdx @@ -1,17 +1,18 @@ --- -title: 'Content Security Policy' -description: 'Next.jsアプリケーションに対してContent Security Policy (CSP)を設定する方法を学びます。' +title: 'Next.jsアプリケーションにContent Security Policy (CSP)を設定する方法' +nav_title: 'Content Security Policy' +description: 'Next.jsアプリケーションにContent Security Policy (CSP)を設定する方法を学びます。' related: links: - 'app/building-your-application/routing/middleware' - 'app/api-reference/functions/headers' --- -{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特化したコンテンツを追加するには、Contentコンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容はapp routerとpages routerの両方で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP)は、クロスサイトスクリプティング(XSS)、クリックジャッキング、その他のコードインジェクション攻撃など、さまざまなセキュリティ脅威からNext.jsアプリケーションを守るために重要です。 -CSPを使用することで、開発者はコンテンツのソース、スクリプト、スタイルシート、画像、フォント、オブジェクト、メディア(オーディオ、ビデオ)、iframeなどに対して許可されるオリジンを指定できます。 +CSPを使用することで、開発者はコンテンツソース、スクリプト、スタイルシート、画像、フォント、オブジェクト、メディア(音声、動画)、iframeなどに許可されるオリジンを指定できます。
@@ -20,21 +21,21 @@ CSPを使用することで、開発者はコンテンツのソース、スク
-## Nonce {#nonces} +## Nonces {#nonces} -[nonce](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/nonce)は、一度きりの使用のために作成された、ユニークでランダムな文字列です。これは、CSPと組み合わせて使用され、特定のインラインスクリプトやスタイルの実行を選択的に許可し、厳しいCSP指令をバイパスするために使われます。 +[nonce](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/nonce)は、一度だけ使用されるために作成されたユニークでランダムな文字列です。CSPと組み合わせて使用され、特定のインラインスクリプトやスタイルの実行を選択的に許可し、厳格なCSP指令を回避します。 ### なぜnonceを使用するのか? {#why-use-a-nonce} -CSPは悪意のあるスクリプトをブロックするように設計されていますが、インラインスクリプトが必要な正当なシナリオも存在します。そのような場合、nonceはこれらのスクリプトが正しいnonceを持っている場合に実行を許可する方法を提供します。 +CSPは悪意のあるスクリプトをブロックするように設計されていますが、インラインスクリプトが必要な正当なシナリオも存在します。そのような場合、nonceは正しいnonceを持つスクリプトの実行を許可する方法を提供します。 -### Middlewareを使用してnonceを追加する {#adding-a-nonce-with-middleware} +### Middlewareでnonceを追加する {#adding-a-nonce-with-middleware} -[Middleware](/docs/app/building-your-application/routing/middleware)を使用すると、ページがレンダリングされる前にヘッダーを追加し、nonceを生成することができます。 +[Middleware](/docs/app/building-your-application/routing/middleware)を使用すると、ページがレンダリングされる前にヘッダーを追加し、nonceを生成できます。 -ページが表示されるたびに、新しいnonceを生成する必要があります。これは、**nonceを追加するために動的レンダリングを使用しなければならない**ことを意味します。 +ページが表示されるたびに、新しいnonceを生成する必要があります。つまり、nonceを追加するには**動的レンダリングを使用する必要があります**。 -例えば: +例: @@ -56,7 +57,7 @@ export function middleware(request: NextRequest) { frame-ancestors 'none'; upgrade-insecure-requests; ` - // 改行文字とスペースを置換する + // 改行文字とスペースを置換 const contentSecurityPolicyHeaderValue = cspHeader .replace(/\s{2,}/g, ' ') .trim() @@ -103,7 +104,7 @@ export function middleware(request) { frame-ancestors 'none'; upgrade-insecure-requests; ` - // 改行文字とスペースを置換する + // 改行文字とスペースを置換 const contentSecurityPolicyHeaderValue = cspHeader .replace(/\s{2,}/g, ' ') .trim() @@ -132,9 +133,9 @@ export function middleware(request) { -デフォルトでは、Middlewareはすべてのリクエストで実行されます。[`matcher`](/docs/app/building-your-application/routing/middleware#matcher)を使用して、特定のパスでのみMiddlewareを実行するようにフィルタリングできます。 +デフォルトでは、Middlewareはすべてのリクエストで実行されます。特定のパスでMiddlewareを実行するようにフィルタリングするには、[`matcher`](/docs/app/building-your-application/routing/middleware#matcher)を使用できます。 -CSPヘッダーが不要なプリフェッチ(`next/link`から)や静的資産のマッチングを無視することをお勧めします。 +`next/link`からのプリフェッチやCSPヘッダーが不要な静的アセットのマッチングを無視することをお勧めします。 @@ -143,11 +144,11 @@ CSPヘッダーが不要なプリフェッチ(`next/link`から)や静的資 export const config = { matcher: [ /* - * 次で始まるリクエストパスを除くすべてのリクエストパスと一致します: + * 次のもので始まるリクエストパスを除くすべてのリクエストパスにマッチします: * - api (APIルート) * - _next/static (静的ファイル) * - _next/image (画像最適化ファイル) - * - favicon.ico (faviconファイル) + * - favicon.ico (ファビコンファイル) */ { source: '/((?!api|_next/static|_next/image|favicon.ico).*)', @@ -167,11 +168,11 @@ export const config = { export const config = { matcher: [ /* - * 次で始まるリクエストパスを除くすべてのリクエストパスと一致します: + * 次のもので始まるリクエストパスを除くすべてのリクエストパスにマッチします: * - api (APIルート) * - _next/static (静的ファイル) * - _next/image (画像最適化ファイル) - * - favicon.ico (faviconファイル) + * - favicon.ico (ファビコンファイル) */ { source: '/((?!api|_next/static|_next/image|favicon.ico).*)', @@ -189,7 +190,7 @@ export const config = { ### nonceの読み取り {#reading-the-nonce} -`headers`を使用して、[Server Component](/docs/app/building-your-application/rendering/server-components)からnonceを読み取ることができます: +[Server Component](/docs/app/building-your-application/rendering/server-components)を使用して[`headers`](/docs/app/api-reference/functions/headers)からnonceを読み取ることができます: @@ -234,9 +235,9 @@ export default async function Page() { -## Nonceを使用しない場合 {#without-nonces} +## Noncesを使用しない場合 {#without-nonces} -nonceを必要としないアプリケーションの場合、[`next.config.js`](/docs/app/api-reference/config/next-config-js)ファイルにCSPヘッダーを直接設定できます: +noncesが不要なアプリケーションの場合、CSPヘッダーを[`next.config.js`](/docs/app/api-reference/config/next-config-js)ファイルに直接設定できます: ```js title="next.config.js" const cspHeader = ` @@ -271,4 +272,4 @@ module.exports = { ## バージョン履歴 {#version-history} -nonceを適切に処理して適用するには、Next.jsの`v13.4.20+`の使用をお勧めします。 +noncesを適切に処理し適用するために、Next.jsの`v13.4.20+`の使用を推奨します。 diff --git a/docs/01-app/03-building-your-application/07-configuring/10-custom-server.mdx b/docs/01-app/02-guides/custom-server.mdx similarity index 63% rename from docs/01-app/03-building-your-application/07-configuring/10-custom-server.mdx rename to docs/01-app/02-guides/custom-server.mdx index 71e0f240..12e1fd1f 100644 --- a/docs/01-app/03-building-your-application/07-configuring/10-custom-server.mdx +++ b/docs/01-app/02-guides/custom-server.mdx @@ -1,11 +1,12 @@ --- -title: 'Custom Server' -description: 'カスタムサーバーを使用してNext.jsアプリをプログラムで開始する方法。' +title: 'Next.jsでカスタムサーバーを設定する方法' +nav_title: 'カスタムサーバー' +description: 'カスタムサーバーを使用してNext.jsアプリをプログラムで開始します。' --- -{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特有のコンテンツを追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} -Next.jsはデフォルトで`next start`とともに独自のサーバーを含んでいます。既存のバックエンドがある場合でも、Next.jsと一緒に使用できます(これはカスタムサーバーではありません)。カスタムNext.jsサーバーを使用すると、カスタムパターンのためにプログラムでサーバーを開始できます。ほとんどの場合、このアプローチは必要ありませんが、必要に応じて使用可能です。 +Next.jsはデフォルトで`next start`を使用して独自のサーバーを含んでいます。既存のバックエンドがある場合でも、Next.jsと一緒に使用できます(これはカスタムサーバーではありません)。カスタムNext.jsサーバーを使用すると、カスタムパターンのためにプログラムでサーバーを開始できます。ほとんどの場合、このアプローチは必要ありませんが、必要に応じて使用可能です。 > **Good to know**: > @@ -72,7 +73,7 @@ app.prepare().then(() => { -> `server.js`はNext.jsコンパイラやバンドルプロセスを通過しません。このファイルが必要とする構文とソースコードが、使用している現在のNode.jsバージョンと互換性があることを確認してください。[例を参照](https://github.com/vercel/next.js/tree/canary/examples/custom-server)。 +> `server.js`はNext.jsのコンパイラやバンドルプロセスを通過しません。このファイルが必要とする構文とソースコードが、使用している現在のNode.jsバージョンと互換性があることを確認してください。[例を参照](https://github.com/vercel/next.js/tree/canary/examples/custom-server)。 カスタムサーバーを実行するには、`package.json`の`scripts`を次のように更新する必要があります: @@ -86,7 +87,7 @@ app.prepare().then(() => { } ``` -または、`nodemon`をセットアップすることもできます([例](https://github.com/vercel/next.js/tree/canary/examples/custom-server))。カスタムサーバーは、Next.jsアプリケーションとサーバーを接続するために次のインポートを使用します: +または、`nodemon`を設定することもできます([例](https://github.com/vercel/next.js/tree/canary/examples/custom-server))。カスタムサーバーは、Next.jsアプリケーションとサーバーを接続するために次のインポートを使用します: ```js import next from 'next' @@ -96,16 +97,16 @@ const app = next({}) 上記の`next`インポートは、次のオプションを持つオブジェクトを受け取る関数です: -| オプション | 型 | 説明 | -| ------------ | ------------------ | --------------------------------------------------------------------------------------------- | -| `conf` | `Object` | `next.config.js`で使用するのと同じオブジェクト。デフォルトは`{}` | -| `dev` | `Boolean` | (_オプション_)Next.jsを開発モードで起動するかどうか。デフォルトは`false` | -| `dir` | `String` | (_オプション_)Next.jsプロジェクトの場所。デフォルトは`'.'` | -| `quiet` | `Boolean` | (_オプション_)サーバー情報を含むエラーメッセージを非表示にするかどうか。デフォルトは`false` | -| `hostname` | `String` | (_オプション_)サーバーが実行されているホスト名 | -| `port` | `Number` | (_オプション_)サーバーが実行されているポート | -| `httpServer` | `node:http#Server` | (_オプション_)Next.jsが実行されているHTTPサーバー | -| `turbo` | `Boolean` | (_オプション_)Turbopackを有効にするかどうか | +| オプション | 型 | 説明 | +| ------------ | ------------------ | -------------------------------------------------------------------------------------------- | +| `conf` | `Object` | `next.config.js`で使用するのと同じオブジェクト。デフォルトは`{}` | +| `dev` | `Boolean` | (_オプション_) Next.jsを開発モードで起動するかどうか。デフォルトは`false` | +| `dir` | `String` | (_オプション_) Next.jsプロジェクトの場所。デフォルトは`'.'` | +| `quiet` | `Boolean` | (_オプション_) サーバー情報を含むエラーメッセージを非表示にするかどうか。デフォルトは`false` | +| `hostname` | `String` | (_オプション_) サーバーが実行されているホスト名 | +| `port` | `Number` | (_オプション_) サーバーが実行されているポート | +| `httpServer` | `node:http#Server` | (_オプション_) Next.jsが実行されているHTTPサーバー | +| `turbo` | `Boolean` | (_オプション_) Turbopackを有効にする | 返された`app`は、必要に応じてNext.jsがリクエストを処理できるように使用できます。 @@ -113,7 +114,7 @@ const app = next({}) ## ファイルシステムルーティングの無効化 {#disabling-file-system-routing} -デフォルトでは、`Next`は`pages`フォルダー内の各ファイルをファイル名に一致するパス名の下で提供します。プロジェクトがカスタムサーバーを使用している場合、この動作により同じコンテンツが複数のパスから提供される可能性があり、SEOやUXに問題を引き起こすことがあります。 +デフォルトでは、`Next`は`pages`フォルダー内の各ファイルをファイル名に一致するパス名の下で提供します。プロジェクトがカスタムサーバーを使用している場合、この動作により同じコンテンツが複数のパスから提供されることになり、SEOやUXに問題を引き起こす可能性があります。 この動作を無効にし、`pages`内のファイルに基づくルーティングを防ぐには、`next.config.js`を開き、`useFileSystemPublicRoutes`設定を無効にします: diff --git a/docs/01-app/03-building-your-application/07-configuring/16-debugging.mdx b/docs/01-app/02-guides/debugging.mdx similarity index 84% rename from docs/01-app/03-building-your-application/07-configuring/16-debugging.mdx rename to docs/01-app/02-guides/debugging.mdx index aeec4431..f3c71bf3 100644 --- a/docs/01-app/03-building-your-application/07-configuring/16-debugging.mdx +++ b/docs/01-app/02-guides/debugging.mdx @@ -1,9 +1,10 @@ --- -title: 'デバッグ' -description: 'VS Code、Chrome DevTools、またはFirefox DevToolsを使用してNext.jsアプリケーションをデバッグする方法を学びましょう。' +title: 'Next.jsでデバッグツールを使用する方法' +nav_title: 'デバッグ' +description: 'VS Code、Chrome DevTools、またはFirefox DevToolsを使用してNext.jsアプリケーションをデバッグする方法を学びます。' --- -{/* このドキュメントの内容はapp routerとpages routerの間で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有されるコンテンツはコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} このドキュメントでは、[VS Codeデバッガー](https://code.visualstudio.com/docs/editor/debugging)、[Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools)、または[Firefox DevTools](https://firefox-source-docs.mozilla.org/devtools-user/)を使用して、Next.jsのフロントエンドおよびバックエンドコードをフルソースマップサポートでデバッグする方法を説明します。 @@ -11,7 +12,7 @@ Node.jsにアタッチできるデバッガーであれば、Next.jsアプリケ ## VS Codeでのデバッグ {#debugging-with-vs-code} -プロジェクトのルートに`.vscode/launch.json`という名前のファイルを作成し、次の内容を記述します: +プロジェクトのrootに`.vscode/launch.json`という名前のファイルを作成し、次の内容を記述します: ```json title="launch.json" { @@ -46,7 +47,7 @@ Node.jsにアタッチできるデバッガーであれば、Next.jsアプリケ "name": "Next.js: debug full stack", "type": "node", "request": "launch", - "program": "${workspaceFolder}/node_modules/.bin/next", + "program": "${workspaceFolder}/node_modules/next/dist/bin/next", "runtimeArgs": ["--inspect"], "skipFiles": ["/**"], "serverReadyAction": { @@ -67,7 +68,7 @@ Node.jsにアタッチできるデバッガーであれば、Next.jsアプリケ "Next.js: debug full stack"の設定では、`serverReadyAction.action`がサーバーが準備完了したときに開くブラウザを指定します。`debugWithEdge`はEdgeブラウザを起動することを意味します。Chromeを使用している場合は、この値を`debugWithChrome`に変更してください。 -アプリケーションの起動時に[ポート番号を変更している](https://nextjs.org/docs/canary/pages/api-reference/cli/next#next-dev-options)場合は、`http://localhost:3000`の`3000`を使用しているポートに置き換えてください。 +アプリケーションが起動するポート番号を[変更している場合](https://nextjs.org/docs/canary/pages/api-reference/cli/next#next-dev-options)、`http://localhost:3000`の`3000`を使用しているポートに置き換えてください。 Next.jsをroot以外のディレクトリから実行している場合(例えば、Turborepoを使用している場合)、サーバーサイドおよびフルスタックデバッグタスクに`cwd`を追加する必要があります。例えば、`"cwd": "${workspaceFolder}/apps/web"`のようにします。 @@ -98,11 +99,11 @@ Firefoxの場合: - Chromeでは:Windows/Linuxでは`Ctrl+P`、macOSでは`⌘+P`を押す - Firefoxでは:Windows/Linuxでは`Ctrl+P`、macOSでは`⌘+P`を押すか、左パネルのファイルツリーを使用 -検索時に、ソースファイルのパスは`webpack://_N_E/./`で始まります。 +検索時、ソースファイルのパスは`webpack://_N_E/./`で始まります。 ### サーバーサイドコード {#server-side-code} -ブラウザDevToolsを使用してサーバーサイドのNext.jsコードをデバッグするには、基盤となるNode.jsプロセスに[`--inspect`](https://nodejs.org/api/cli.html#cli_inspect_host_port)フラグを渡す必要があります: +ブラウザDevToolsでサーバーサイドのNext.jsコードをデバッグするには、基盤となるNode.jsプロセスに[`--inspect`](https://nodejs.org/api/cli.html#cli_inspect_host_port)フラグを渡す必要があります: ```bash title="Terminal" NODE_OPTIONS='--inspect' next dev @@ -155,7 +156,7 @@ Next.jsは、エラーオーバーレイのNext.jsバージョンインジケー ### Windowsでのデバッグ {#debugging-on-windows} -Windowsユーザーは、`NODE_OPTIONS='--inspect'`を使用する際に問題が発生する可能性があります。この構文はWindowsプラットフォームではサポートされていないためです。これを回避するには、[`cross-env`](https://www.npmjs.com/package/cross-env)パッケージを開発依存関係としてインストールし(`npm`と`yarn`では`-D`)、`dev`スクリプトを次のように置き換えます。 +Windowsユーザーは、`NODE_OPTIONS='--inspect'`を使用する際に問題が発生する可能性があります。この構文はWindowsプラットフォームではサポートされていないためです。これを回避するには、[`cross-env`](https://www.npmjs.com/package/cross-env)パッケージを開発依存関係としてインストールし(`npm`および`yarn`では`-D`)、`dev`スクリプトを次のように置き換えます。 ```json title="package.json" { @@ -167,11 +168,11 @@ Windowsユーザーは、`NODE_OPTIONS='--inspect'`を使用する際に問題 `cross-env`は、どのプラットフォーム(Mac、Linux、Windowsを含む)でも`NODE_OPTIONS`環境変数を設定し、デバイスやオペレーティングシステムを問わず一貫してデバッグできるようにします。 -> **Good to know**: Windows Defenderが無効になっていることを確認してください。この外部サービスは*すべてのファイル読み取り*をチェックし、`next dev`でのFast Refresh時間を大幅に増加させることが報告されています。これはNext.jsに関連しない既知の問題ですが、Next.jsの開発に影響を与えます。 +> **Good to know**: Windows Defenderが無効になっていることを確認してください。この外部サービスは*すべてのファイル読み取り*をチェックし、`next dev`でのFast Refresh時間を大幅に増加させると報告されています。これはNext.jsに関連しない既知の問題ですが、Next.jsの開発に影響を与えます。 ## 詳細情報 {#more-information} -JavaScriptデバッガーの使用方法について詳しく学ぶには、次のドキュメントをご覧ください: +JavaScriptデバッガーの使用方法について詳しく知りたい場合は、次のドキュメントをご覧ください: - [VS CodeでのNode.jsデバッグ:ブレークポイント](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_breakpoints) - [Chrome DevTools:JavaScriptのデバッグ](https://developers.google.com/web/tools/chrome-devtools/javascript) diff --git a/docs/01-app/02-guides/draft-mode.mdx b/docs/01-app/02-guides/draft-mode.mdx new file mode 100644 index 00000000..b5de5a79 --- /dev/null +++ b/docs/01-app/02-guides/draft-mode.mdx @@ -0,0 +1,251 @@ +--- +title: 'Next.jsでDraft Modeを使用してコンテンツをプレビューする方法' +nav_title: 'Draft Mode' +description: 'Next.jsには、静的ページと動的ページを切り替えるためのdraft modeがあります。App Routerを使用してその仕組みを学ぶことができます。' +related: + title: '次のステップ' + description: 'Draft Modeの使用方法についての詳細はAPIリファレンスをご覧ください。' + links: + - app/api-reference/functions/draft-mode +--- + +**Draft Mode**を使用すると、Next.jsアプリケーションでヘッドレスCMSからドラフトコンテンツをプレビューできます。これは、ビルド時に生成される静的ページにとって便利で、[動的レンダリング](/docs/app/building-your-application/rendering/server-components#dynamic-rendering)に切り替えて、サイト全体を再ビルドすることなくドラフトの変更を確認できます。 + +このページでは、Draft Modeを有効にして使用する方法を説明します。 + +## ステップ1: Route Handlerを作成する {#step-1-create-a-route-handler} + +[Route Handler](/docs/app/building-your-application/routing/route-handlers)を作成します。名前は任意で、例えば`app/api/draft/route.ts`とします。 + + + + +```ts title="app/api/draft/route.ts" switcher +export async function GET(request: Request) { + return new Response('') +} +``` + + + + +```js title="app/api/draft/route.js" switcher +export async function GET() { + return new Response('') +} +``` + + + + +次に、[`draftMode`](/docs/app/api-reference/functions/draft-mode)関数をインポートし、`enable()`メソッドを呼び出します。 + + + + +```ts title="app/api/draft/route.ts" switcher +import { draftMode } from 'next/headers' + +export async function GET(request: Request) { + const draft = await draftMode() + draft.enable() + return new Response('Draft mode is enabled') +} +``` + + + + +```js title="app/api/draft/route.js" switcher +import { draftMode } from 'next/headers' + +export async function GET(request) { + const draft = await draftMode() + draft.enable() + return new Response('Draft mode is enabled') +} +``` + + + + +これにより、**cookie**が設定され、draft modeが有効になります。このcookieを含む後続のリクエストはdraft modeをトリガーし、静的に生成されたページの動作を変更します。 + +`/api/draft`にアクセスし、ブラウザの開発者ツールを確認することで、手動でテストできます。`__prerender_bypass`という名前のcookieを持つ`Set-Cookie`レスポンスヘッダーに注目してください。 + +## ステップ2: ヘッドレスCMSからRoute Handlerにアクセスする {#step-2-access-the-route-handler-from-your-headless-cms} + +> 使用しているヘッドレスCMSが**カスタムドラフトURL**の設定をサポートしていることを前提としています。サポートしていない場合でも、この方法を使用してドラフトURLを保護できますが、ドラフトURLを手動で構築してアクセスする必要があります。具体的な手順は使用しているヘッドレスCMSによって異なります。 + +ヘッドレスCMSからRoute Handlerに安全にアクセスするには: + +1. 任意のトークンジェネレーターを使用して**シークレットトークン文字列**を作成します。このシークレットは、Next.jsアプリとヘッドレスCMSのみが知っているものです。 +2. ヘッドレスCMSがカスタムドラフトURLの設定をサポートしている場合、ドラフトURLを指定します(Route Handlerが`app/api/draft/route.ts`にあると仮定します)。例えば: + +```bash title="Terminal" +https:///api/draft?secret=&slug= +``` + +> - ``はデプロイメントドメインに置き換えてください。 +> - ``は生成したシークレットトークンに置き換えてください。 +> - ``は表示したいページのパスに置き換えてください。`/posts/one`を表示したい場合は、`&slug=/posts/one`を使用します。 +> +> ヘッドレスCMSによっては、ドラフトURLに変数を含めることができ、CMSのデータに基づいて``を動的に設定できるかもしれません:`&slug=/posts/{entry.fields.slug}` + +3. Route Handler内で、シークレットが一致し、`slug`パラメータが存在することを確認します(存在しない場合、リクエストは失敗するべきです)。`draftMode.enable()`を呼び出してcookieを設定し、`slug`で指定されたパスにブラウザをリダイレクトします: + + + + +```ts title="app/api/draft/route.ts" switcher +import { draftMode } from 'next/headers' +import { redirect } from 'next/navigation' + +export async function GET(request: Request) { + // クエリ文字列パラメータを解析 + const { searchParams } = new URL(request.url) + const secret = searchParams.get('secret') + const slug = searchParams.get('slug') + + // シークレットと次のパラメータを確認 + // このシークレットはこのRoute HandlerとCMSのみが知っているべきです + if (secret !== 'MY_SECRET_TOKEN' || !slug) { + return new Response('Invalid token', { status: 401 }) + } + + // 提供された`slug`が存在するかヘッドレスCMSをチェック + // getPostBySlugはヘッドレスCMSへの必要なフェッチロジックを実装します + const post = await getPostBySlug(slug) + + // slugが存在しない場合、draft modeの有効化を防ぐ + if (!post) { + return new Response('Invalid slug', { status: 401 }) + } + + // cookieを設定してDraft Modeを有効化 + const draft = await draftMode() + draft.enable() + + // フェッチした投稿からのパスにリダイレクト + // searchParams.slugにリダイレクトしないのは、オープンリダイレクトの脆弱性を避けるためです + redirect(post.slug) +} +``` + + + + +```js title="app/api/draft/route.js" switcher +import { draftMode } from 'next/headers' +import { redirect } from 'next/navigation' + +export async function GET(request) { + // クエリ文字列パラメータを解析 + const { searchParams } = new URL(request.url) + const secret = searchParams.get('secret') + const slug = searchParams.get('slug') + + // シークレットと次のパラメータを確認 + // このシークレットはこのRoute HandlerとCMSのみが知っているべきです + if (secret !== 'MY_SECRET_TOKEN' || !slug) { + return new Response('Invalid token', { status: 401 }) + } + + // 提供された`slug`が存在するかヘッドレスCMSをチェック + // getPostBySlugはヘッドレスCMSへの必要なフェッチロジックを実装します + const post = await getPostBySlug(slug) + + // slugが存在しない場合、draft modeの有効化を防ぐ + if (!post) { + return new Response('Invalid slug', { status: 401 }) + } + + // cookieを設定してDraft Modeを有効化 + const draft = await draftMode() + draft.enable() + + // フェッチした投稿からのパスにリダイレクト + // searchParams.slugにリダイレクトしないのは、オープンリダイレクトの脆弱性を避けるためです + redirect(post.slug) +} +``` + + + + +成功すれば、ブラウザはドラフトモードのcookieを持って表示したいパスにリダイレクトされます。 + +## ステップ3: ドラフトコンテンツをプレビューする {#step-3-preview-the-draft-content} + +次のステップは、ページを更新して`draftMode().isEnabled`の値を確認することです。 + +cookieが設定されたページをリクエストすると、データは**リクエスト時**にフェッチされます(ビルド時ではなく)。 + +さらに、`isEnabled`の値は`true`になります。 + + + + +```tsx title="app/page.tsx" switcher +// データをフェッチするページ +import { draftMode } from 'next/headers' + +async function getData() { + const { isEnabled } = await draftMode() + + const url = isEnabled + ? 'https://draft.example.com' + : 'https://production.example.com' + + const res = await fetch(url) + + return res.json() +} + +export default async function Page() { + const { title, desc } = await getData() + + return ( +
+

{title}

+

{desc}

+
+ ) +} +``` + +
+ + +```jsx title="app/page.js" switcher +// データをフェッチするページ +import { draftMode } from 'next/headers' + +async function getData() { + const { isEnabled } = await draftMode() + + const url = isEnabled + ? 'https://draft.example.com' + : 'https://production.example.com' + + const res = await fetch(url) + + return res.json() +} + +export default async function Page() { + const { title, desc } = await getData() + + return ( +
+

{title}

+

{desc}

+
+ ) +} +``` + +
+
+ +ヘッドレスCMSから(`secret`と`slug`を使用して)またはURLを手動で使用してドラフトRoute Handlerにアクセスすると、ドラフトコンテンツを確認できるはずです。また、ドラフトを公開せずに更新した場合でも、ドラフトを表示できるはずです。 diff --git a/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx b/docs/01-app/02-guides/environment-variables.mdx similarity index 69% rename from docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx rename to docs/01-app/02-guides/environment-variables.mdx index 5fa9cbee..8516eb5a 100644 --- a/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx +++ b/docs/01-app/02-guides/environment-variables.mdx @@ -1,11 +1,12 @@ --- -title: '環境変数' +title: 'Next.jsで環境変数を使用する方法' +nav_title: '環境変数' description: 'Next.jsアプリケーションで環境変数を追加し、アクセスする方法を学びます。' --- -{/* このドキュメントの内容はapp routerとpages routerの間で共有されています。Pages Routerに特有の内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} -Next.jsには環境変数のサポートが組み込まれており、以下のことが可能です: +Next.jsには環境変数の組み込みサポートがあり、以下のことが可能です: - [`.env`を使用して環境変数を読み込む](#loading-environment-variables) - [`NEXT_PUBLIC_`でプレフィックスを付けてブラウザ用に環境変数をバンドルする](#bundling-environment-variables-for-the-browser) @@ -14,7 +15,7 @@ Next.jsには環境変数のサポートが組み込まれており、以下の ## 環境変数の読み込み {#loading-environment-variables} -Next.jsは、`.env*`ファイルから`process.env`に環境変数を読み込むためのサポートを組み込んでいます。 +Next.jsは、`.env*`ファイルから`process.env`に環境変数を読み込むための組み込みサポートを提供しています。 ```txt title=".env" DB_HOST=localhost @@ -24,7 +25,7 @@ DB_PASS=mypassword -これにより、`process.env.DB_HOST`、`process.env.DB_USER`、`process.env.DB_PASS`がNode.js環境に自動的に読み込まれ、[Next.jsのデータ取得メソッド](https://nextjs.org/docs/canary/pages/building-your-application/data-fetching)や[APIルート](https://nextjs.org/docs/canary/pages/building-your-application/routing/api-routes)で使用できるようになります。 +これにより、`process.env.DB_HOST`、`process.env.DB_USER`、および`process.env.DB_PASS`がNode.js環境に自動的に読み込まれ、[Next.jsのデータ取得メソッド](https://nextjs.org/docs/canary/pages/building-your-application/data-fetching)や[APIルート](https://nextjs.org/docs/canary/pages/building-your-application/routing/api-routes)で使用できるようになります。 例えば、[`getStaticProps`](https://nextjs.org/docs/canary/pages/building-your-application/data-fetching/get-static-props)を使用する場合: @@ -55,12 +56,12 @@ export async function getStaticProps() { > ... > -----END DSA PRIVATE KEY-----" > -> # またはダブルクォート内に`\n`を使用して +> # または、ダブルクォート内に`\n`を使用して > PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END DSA PRIVATE KEY-----\n" > ``` -> **注意:** `/src`フォルダを使用している場合、Next.jsは.envファイルを**親フォルダからのみ**読み込み、`/src`フォルダからは**読み込みません**。 -> これにより、`process.env.DB_HOST`、`process.env.DB_USER`、`process.env.DB_PASS`がNode.js環境に自動的に読み込まれ、[Route Handlers](/docs/app/building-your-application/routing/route-handlers)で使用できるようになります。 +> **注意:** `/src`フォルダを使用している場合、Next.jsは親フォルダからのみ.envファイルを読み込み、`/src`フォルダからは読み込みません。 +> これにより、`process.env.DB_HOST`、`process.env.DB_USER`、および`process.env.DB_PASS`がNode.js環境に自動的に読み込まれ、[Route Handlers](/docs/app/building-your-application/routing/route-handlers)で使用できるようになります。 例えば: @@ -77,11 +78,11 @@ export async function GET() { -### `@next/env`を使用した環境変数の読み込み {#loading-environment-variables-with-next-env} +### `@next/env`で環境変数を読み込む {#loading-environment-variables-with-next-env} Next.jsランタイムの外部、例えばORMやテストランナーのroot設定ファイルで環境変数を読み込む必要がある場合、`@next/env`パッケージを使用できます。 -このパッケージは、Next.jsが内部で`.env*`ファイルから環境変数を読み込むために使用しています。 +このパッケージは、Next.jsが`.env*`ファイルから環境変数を読み込むために内部で使用しています。 使用するには、パッケージをインストールし、`loadEnvConfig`関数を使用して環境変数を読み込みます: @@ -143,9 +144,9 @@ export default defineConfig({
-### 他の変数の参照 {#referencing-other-variables} +### 他の変数を参照する {#referencing-other-variables} -Next.jsは、`.env*`ファイル内で他の変数を参照するために`$`を使用する変数を自動的に展開します。これにより、他のシークレットを参照できます。例えば: +Next.jsは、`.env*`ファイル内で他の変数を参照するために`$`を使用する変数を自動的に展開します。例えば、`$VARIABLE`のように記述できます。これにより、他のシークレットを参照することができます。例えば: ```txt title=".env" TWITTER_USER=nextjs @@ -154,13 +155,13 @@ TWITTER_URL=https://x.com/$TWITTER_USER 上記の例では、`process.env.TWITTER_URL`は`https://x.com/nextjs`に設定されます。 -> **Good to know**: 実際の値に`$`を含む変数を使用する必要がある場合は、`\$`でエスケープする必要があります。 +> **Good to know**: 実際の値に`$`を含む変数を使用する必要がある場合は、`\$`のようにエスケープする必要があります。 ## ブラウザ用に環境変数をバンドルする {#bundling-environment-variables-for-the-browser} `NEXT_PUBLIC_`で始まらない環境変数はNode.js環境でのみ利用可能であり、ブラウザからはアクセスできません(クライアントは異なる*環境*で実行されます)。 -環境変数の値をブラウザでアクセス可能にするために、Next.jsはビルド時にその値をクライアントに配信されるjsバンドルに「インライン」化し、`process.env.[variable]`へのすべての参照をハードコードされた値に置き換えることができます。これを行うには、変数に`NEXT_PUBLIC_`をプレフィックスとして付けるだけです。例えば: +環境変数の値をブラウザでアクセス可能にするために、Next.jsはビルド時にその値をクライアントに配信されるjsバンドルに「インライン」することができます。これを行うには、変数に`NEXT_PUBLIC_`をプレフィックスとして付けるだけです。例えば: ```txt title="Terminal" NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk @@ -184,14 +185,14 @@ function HomePage() { export default HomePage ``` -動的なルックアップはインライン化されないことに注意してください。例えば: +動的なルックアップはインライン化されないことに注意してください: ```js -// これはインライン化されません。なぜなら、変数を使用しているからです +// これはインライン化されません。変数を使用しているためです const varName = 'NEXT_PUBLIC_ANALYTICS_ID' setupAnalyticsService(process.env[varName]) -// これはインライン化されません。なぜなら、変数を使用しているからです +// これはインライン化されません。変数を使用しているためです const env = process.env setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID) ``` @@ -204,7 +205,7 @@ Next.jsはビルド時とランタイムの両方の環境変数をサポート -ランタイム環境変数を読み取るには、`getServerSideProps`または[App Routerの段階的な採用](/docs/app/guides/migrating/app-router-migration)を使用することをお勧めします。 +ランタイム環境変数を読み取るには、`getServerSideProps`を使用するか、[App Routerを段階的に採用する](/docs/app/guides/migrating/app-router-migration)ことをお勧めします。 @@ -249,12 +250,12 @@ export default async function Component() { -これにより、異なる値を持つ複数の環境を通じてプロモートできる単一のDockerイメージを使用できます。 +これにより、異なる値を持つ複数の環境を通じてプロモートできる単一のDockerイメージを使用することができます。 **Good to know:** -- [`register`関数](/docs/app/building-your-application/optimizing/instrumentation)を使用してサーバーの起動時にコードを実行できます。 -- [`runtimeConfig`](https://nextjs.org/docs/canary/pages/api-reference/config/next-config-js/runtime-configuration)オプションの使用は推奨しません。これはスタンドアロン出力モードでは機能しないためです。この機能が必要な場合は、[段階的にApp Routerを採用する](/docs/app/guides/migrating/app-router-migration)ことをお勧めします。 +- [`register`関数](/docs/app/guides/instrumentation)を使用してサーバーの起動時にコードを実行できます。 +- [`runtimeConfig`](https://nextjs.org/docs/canary/pages/api-reference/config/next-config-js/runtime-configuration)オプションの使用は推奨しません。これはスタンドアロン出力モードでは機能しないためです。この機能が必要な場合は、[App Routerを段階的に採用する](/docs/app/guides/migrating/app-router-migration)ことをお勧めします。 ## Vercelでの環境変数 {#environment-variables-on-vercel} @@ -268,22 +269,22 @@ Next.jsアプリケーションを[Vercel](https://vercel.com)にデプロイす vercel env pull ``` -> **Good to know**: Next.jsアプリケーションを[Vercel](https://vercel.com)にデプロイする際、`.env*`ファイル内の環境変数は、名前が`NEXT_PUBLIC_`でプレフィックスされていない限り、Edge Runtimeで利用できません。すべての環境変数が利用可能な[プロジェクト設定](https://vercel.com/docs/projects/environment-variables?utm_medium=docs&utm_source=next-site&utm_campaign=next-website)で環境変数を管理することを強くお勧めします。 +> **Good to know**: Next.jsアプリケーションを[Vercel](https://vercel.com)にデプロイする際、`.env*`ファイル内の環境変数は、名前が`NEXT_PUBLIC_`で始まらない限り、Edge Runtimeで利用できません。すべての環境変数が利用可能な[プロジェクト設定](https://vercel.com/docs/projects/environment-variables?utm_medium=docs&utm_source=next-site&utm_campaign=next-website)で環境変数を管理することを強くお勧めします。 ## テスト環境変数 {#test-environment-variables} -`development`および`production`環境とは別に、3番目のオプションとして`test`環境があります。開発または本番環境のデフォルトを設定できるのと同様に、`testing`環境用に`.env.test`ファイルを使用して同じことができます(ただし、これは前述の2つほど一般的ではありません)。Next.jsは`testing`環境で`.env.development`または`.env.production`から環境変数を読み込みません。 +`development`および`production`環境とは別に、3番目のオプションとして`test`があります。開発または本番環境のデフォルトを設定できるのと同様に、`testing`環境用に`.env.test`ファイルを使用して同じことができます(ただし、これは前述の2つほど一般的ではありません)。Next.jsは`testing`環境で`.env.development`または`.env.production`から環境変数を読み込みません。 -これは、`jest`や`cypress`のようなツールを使用してテストを実行する際に、テスト目的で特定の環境変数を設定する必要がある場合に便利です。`NODE_ENV`が`test`に設定されている場合、テストのデフォルト値が読み込まれますが、通常は手動でこれを行う必要はありません。テストツールがそれを処理します。 +これは、`jest`や`cypress`のようなツールを使用してテストを実行する際に、テスト目的で特定の環境変数を設定する必要がある場合に便利です。テストのデフォルト値は`NODE_ENV`が`test`に設定されている場合に読み込まれますが、通常は手動でこれを行う必要はありません。テストツールがそれを処理します。 -`test`環境と`development`および`production`環境の間には、小さな違いがあります:`.env.local`は読み込まれません。これは、テストがすべての人に同じ結果をもたらすことを期待しているためです。このようにして、`.env.local`(デフォルトセットを上書きすることを意図している)を無視することで、異なる実行間で同じ環境デフォルトを使用します。 +`test`環境と`development`および`production`の間には小さな違いがあります:`.env.local`は読み込まれません。これは、テストがすべての人に同じ結果をもたらすことを期待しているためです。このようにして、`.env.local`(デフォルトセットを上書きすることを意図している)を無視することで、異なる実行間で同じ環境デフォルトを使用します。 > **Good to know**: デフォルトの環境変数と同様に、`.env.test`ファイルはリポジトリに含めるべきですが、`.env.test.local`は含めるべきではありません。`.env*.local`は`.gitignore`を通じて無視されることを意図しています。 ユニットテストを実行する際、`@next/env`パッケージの`loadEnvConfig`関数を活用して、Next.jsが行うのと同じ方法で環境変数を読み込むことを確認できます。 ```js -// 以下は、Jestのグローバルセットアップファイルや、テストセットアップ用の類似のファイルで使用できます +// 以下は、Jestのグローバルセットアップファイルや、テストセットアップ用の類似ファイルで使用できます import { loadEnvConfig } from '@next/env' export default async () => { @@ -294,25 +295,25 @@ export default async () => { ## 環境変数の読み込み順序 {#environment-variable-load-order} -環境変数は、以下の場所で順番に検索され、変数が見つかった時点で停止します。 +環境変数は、以下の場所で順番に検索され、変数が見つかると停止します。 1. `process.env` 1. `.env.$(NODE_ENV).local` -1. `.env.local`(`NODE_ENV`が`test`の場合はチェックされません。) +1. `.env.local` (`NODE_ENV`が`test`の場合はチェックされません。) 1. `.env.$(NODE_ENV)` 1. `.env` 例えば、`NODE_ENV`が`development`で、`.env.development.local`と`.env`の両方に変数を定義した場合、`.env.development.local`の値が使用されます。 -> **Good to know**: `NODE_ENV`の許可される値は`production`、`development`、`test`です。 +> **Good to know**: `NODE_ENV`の許可される値は`production`、`development`、および`test`です。 ## Good to know {#good-to-know} -- [`/src`ディレクトリ](/docs/app/building-your-application/configuring/src-directory)を使用している場合、`.env.*`ファイルはプロジェクトのrootに残すべきです。 -- 環境変数`NODE_ENV`が未割り当ての場合、Next.jsは`next dev`コマンドを実行する際に自動的に`development`を割り当て、他のすべてのコマンドには`production`を割り当てます。 +- [`/src`ディレクトリ](/docs/app/api-reference/file-conventions/src-folder)を使用している場合、`.env.*`ファイルはプロジェクトのrootに残すべきです。 +- 環境変数`NODE_ENV`が未割り当ての場合、Next.jsは`next dev`コマンドを実行するときに自動的に`development`を割り当て、他のすべてのコマンドには`production`を割り当てます。 ## バージョン履歴 {#version-history} -| バージョン | 変更内容 | -| ---------- | -------------------------------------------------- | -| `v9.4.0` | `.env`と`NEXT_PUBLIC_`のサポートが導入されました。 | +| Version | Changes | +| -------- | --------------------------------------------- | +| `v9.4.0` | Support `.env` and `NEXT_PUBLIC_` introduced. | diff --git a/docs/01-app/02-guides/index.mdx b/docs/01-app/02-guides/index.mdx index 96382bf9..0a21a602 100644 --- a/docs/01-app/02-guides/index.mdx +++ b/docs/01-app/02-guides/index.mdx @@ -27,7 +27,7 @@ description: 'Next.jsを使用して一般的なUIパターンやユースケー ### サーバーアクション {#server-actions} - [追加の値を渡す](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#passing-additional-arguments) -- [データを再検証する](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#revalidating-data) +- [データの再検証](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#revalidating-data) - [リダイレクト](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting) - [cookieを設定する](/docs/app/api-reference/functions/cookies#setting-a-cookie) - [cookieを削除する](/docs/app/api-reference/functions/cookies#deleting-cookies) @@ -43,21 +43,21 @@ description: 'Next.jsを使用して一般的なUIパターンやユースケー ### 認証 {#auth} -- [サインアップフォームを作成する](/docs/app/building-your-application/authentication#sign-up-and-login-functionality) -- [ステートレスでcookieベースのセッション管理](/docs/app/building-your-application/authentication#stateless-sessions) -- [ステートフルでデータベースをバックにしたセッション管理](/docs/app/building-your-application/authentication#database-sessions) -- [認可の管理](/docs/app/building-your-application/authentication#authorization) +- [サインアップフォームを作成する](/docs/app/guides/authentication#sign-up-and-login-functionality) +- [ステートレスでcookieベースのセッション管理](/docs/app/guides/authentication#stateless-sessions) +- [ステートフルでデータベースをバックにしたセッション管理](/docs/app/guides/authentication#database-sessions) +- [認可の管理](/docs/app/guides/authentication#authorization) ### テスト {#testing} -- [Vitest](/docs/app/building-your-application/testing/vitest) -- [Jest](/docs/app/building-your-application/testing/jest) -- [Playwright](/docs/app/building-your-application/testing/playwright) -- [Cypress](/docs/app/building-your-application/testing/cypress) +- [Vitest](/docs/app/guides/testing/vitest) +- [Jest](/docs/app/guides/testing/jest) +- [Playwright](/docs/app/guides/testing/playwright) +- [Cypress](/docs/app/guides/testing/cypress) ### デプロイ {#deployment} -- [Dockerfileを作成する](/docs/app/building-your-application/deploying#docker-image) -- [静的エクスポート(SPA)を作成する](/docs/app/building-your-application/deploying/static-exports) -- [セルフホスティング時のキャッシュ設定](/docs/app/building-your-application/deploying#configuring-caching) -- [セルフホスティング時の画像最適化の設定](/docs/app/building-your-application/deploying#image-optimization) +- [Dockerfileを作成する](/docs/app/guides/self-hosting#docker-image) +- [静的エクスポート(SPA)を作成する](/docs/app/guides/static-exports) +- [セルフホスティング時のキャッシュ設定](/docs/app/guides/self-hosting#configuring-caching) +- [セルフホスティング時の画像最適化の設定](/docs/app/guides/self-hosting#image-optimization) diff --git a/docs/01-app/02-guides/instrumentation.mdx b/docs/01-app/02-guides/instrumentation.mdx new file mode 100644 index 00000000..6039fc92 --- /dev/null +++ b/docs/01-app/02-guides/instrumentation.mdx @@ -0,0 +1,123 @@ +--- +title: 'インストゥルメンテーションの設定方法' +nav_title: 'Instrumentation' +description: 'Next.jsアプリでサーバー起動時にコードを実行するためのインストゥルメンテーションの使い方を学びます' +related: + title: 'インストゥルメンテーションについてもっと学ぶ' + links: + - app/api-reference/file-conventions/instrumentation +--- + +{/* このドキュメントの内容はapp routerとpages routerの両方で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} + +インストゥルメンテーションは、アプリケーションにモニタリングやロギングツールを統合するためにコードを使用するプロセスです。これにより、アプリケーションのパフォーマンスや動作を追跡し、本番環境での問題をデバッグすることができます。 + +## 規約 {#convention} + +インストゥルメンテーションを設定するには、プロジェクトの**ルートディレクトリ**(または[`src`](/docs/app/api-reference/file-conventions/src-folder)フォルダを使用している場合はその中)に`instrumentation.ts|js`ファイルを作成します。 + +次に、このファイルで`register`関数をエクスポートします。この関数は、新しいNext.jsサーバーインスタンスが開始されるときに**一度だけ**呼び出されます。 + +例えば、Next.jsを[OpenTelemetry](https://opentelemetry.io/)と[@vercel/otel](https://vercel.com/docs/observability/otel-overview)と共に使用するには、以下のようにします: + + + + +```ts title="instrumentation.ts" switcher +import { registerOTel } from '@vercel/otel' + +export function register() { + registerOTel('next-app') +} +``` + + + + +```js title="instrumentation.js" switcher +import { registerOTel } from '@vercel/otel' + +export function register() { + registerOTel('next-app') +} +``` + + + + +完全な実装については、[Next.js with OpenTelemetryの例](https://github.com/vercel/next.js/tree/canary/examples/with-opentelemetry)を参照してください。 + +> **Good to know**: +> +> - `instrumentation`ファイルはプロジェクトのルートに置くべきで、`app`や`pages`ディレクトリの中に置いてはいけません。`src`フォルダを使用している場合は、`pages`や`app`と並んで`src`の中にファイルを置いてください。 +> - [`pageExtensions`設定オプション](/docs/app/api-reference/config/next-config-js/pageExtensions)を使用してサフィックスを追加する場合、`instrumentation`ファイル名もそれに合わせて更新する必要があります。 + +## 例 {#examples} + +### 副作用を持つファイルのインポート {#importing-files-with-side-effects} + +時には、コード内で副作用を引き起こすためにファイルをインポートすることが有用です。例えば、一連のグローバル変数を定義するファイルをインポートするが、コード内でそのインポートされたファイルを明示的に使用しない場合があります。それでも、パッケージが宣言したグローバル変数にアクセスできます。 + +`register`関数内でJavaScriptの`import`構文を使用してファイルをインポートすることをお勧めします。以下の例は、`register`関数内での`import`の基本的な使用法を示しています: + + + + +```ts title="instrumentation.ts" switcher +export async function register() { + await import('package-with-side-effect') +} +``` + + + + +```js title="instrumentation.js" switcher +export async function register() { + await import('package-with-side-effect') +} +``` + + + + +> **Good to know:** +> +> ファイルの先頭ではなく、`register`関数内からファイルをインポートすることをお勧めします。これにより、コード内のすべての副作用を一箇所にまとめ、ファイルの先頭でグローバルにインポートすることによる意図しない結果を避けることができます。 + +### ランタイム固有のコードのインポート {#importing-runtime-specific-code} + +Next.jsはすべての環境で`register`を呼び出すため、特定のランタイム(例:[EdgeやNode.js](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes))をサポートしないコードを条件付きでインポートすることが重要です。現在の環境を取得するには、`NEXT_RUNTIME`環境変数を使用できます: + + + + +```ts title="instrumentation.ts" switcher +export async function register() { + if (process.env.NEXT_RUNTIME === 'nodejs') { + await import('./instrumentation-node') + } + + if (process.env.NEXT_RUNTIME === 'edge') { + await import('./instrumentation-edge') + } +} +``` + + + + +```js title="instrumentation.js" switcher +export async function register() { + if (process.env.NEXT_RUNTIME === 'nodejs') { + await import('./instrumentation-node') + } + + if (process.env.NEXT_RUNTIME === 'edge') { + await import('./instrumentation-edge') + } +} +``` + + + diff --git a/docs/01-app/03-building-your-application/06-optimizing/07-lazy-loading.mdx b/docs/01-app/02-guides/lazy-loading.mdx similarity index 64% rename from docs/01-app/03-building-your-application/06-optimizing/07-lazy-loading.mdx rename to docs/01-app/02-guides/lazy-loading.mdx index ffd04c1c..8d47c3eb 100644 --- a/docs/01-app/03-building-your-application/06-optimizing/07-lazy-loading.mdx +++ b/docs/01-app/02-guides/lazy-loading.mdx @@ -1,20 +1,21 @@ --- -title: 'Lazy Loading' -description: 'インポートされたライブラリやReactコンポーネントを遅延ロードして、アプリケーションの読み込みパフォーマンスを向上させます。' +title: 'Client Componentsとライブラリの遅延読み込み方法' +nav_title: '遅延読み込み' +description: 'インポートされたライブラリやReactコンポーネントを遅延読み込みして、アプリケーションの読み込みパフォーマンスを向上させます。' --- -{/* このドキュメントの内容はapp routerとpages routerの間で共有されています。Pages Routerに特有のコンテンツを追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容はapp routerとpages routerの間で共有されています。Pages Routerに特化した内容を追加するには、`Content`コンポーネントを使用できます。共有される内容はコンポーネントでラップしないでください。 */} -[Lazy loading](https://developer.mozilla.org/docs/Web/Performance/Lazy_loading)は、Next.jsにおいて、ルートをレンダリングするために必要なJavaScriptの量を減らすことで、アプリケーションの初期読み込みパフォーマンスを向上させます。 +Next.jsにおける[遅延読み込み](https://developer.mozilla.org/docs/Web/Performance/Lazy_loading)は、ルートをレンダリングするために必要なJavaScriptの量を減らすことで、アプリケーションの初期読み込みパフォーマンスを向上させます。 -これにより、**client component**やインポートされたライブラリの読み込みを遅らせ、必要なときにのみクライアントバンドルに含めることができます。たとえば、ユーザーがモーダルを開くためにクリックするまで、その読み込みを遅らせることができます。 +これにより、**Client Components**やインポートされたライブラリの読み込みを遅らせ、必要なときにのみクライアントバンドルに含めることができます。たとえば、ユーザーがモーダルを開くためにクリックするまで、その読み込みを遅らせることができます。 -Next.jsで遅延ロードを実装する方法は2つあります: +Next.jsで遅延読み込みを実装する方法は2つあります: -1. `next/dynamic`を使用した[Dynamic Imports](#nextdynamic) +1. `next/dynamic`を使用した[動的インポート](#nextdynamic) 2. [Suspense](https://react.dev/reference/react/Suspense)と共に[`React.lazy()`](https://react.dev/reference/react/lazy)を使用 -デフォルトでは、server componentは自動的に[コード分割](https://developer.mozilla.org/docs/Glossary/Code_splitting)され、[ストリーミング](/docs/app/building-your-application/routing/loading-ui-and-streaming)を使用して、UIの部分をサーバーからクライアントに段階的に送信できます。遅延ロードはclient componentに適用されます。 +デフォルトでは、Server Componentsは自動的に[コード分割](https://developer.mozilla.org/docs/Glossary/Code_splitting)され、[ストリーミング](/docs/app/building-your-application/routing/loading-ui-and-streaming)を使用して、UIの部分をサーバーからクライアントに段階的に送信できます。遅延読み込みはClient Componentsに適用されます。 ## `next/dynamic` {#next-dynamic} @@ -41,29 +42,29 @@ export default function ClientComponentExample() { return (
- {/* 即座に読み込まれますが、別のクライアントバンドルで */} + {/* 即座に読み込むが、別のクライアントバンドルで */} - {/* 条件が満たされた場合にのみオンデマンドで読み込まれます */} + {/* 条件が満たされた場合にのみオンデマンドで読み込む */} {showMore && } - {/* クライアントサイドでのみ読み込まれます */} + {/* クライアントサイドでのみ読み込む */}
) } ``` -> **Note:** server componentがclient componentを動的にインポートする場合、自動的な[コード分割](https://developer.mozilla.org/docs/Glossary/Code_splitting)は現在サポートされていません。 +> **Note:** Server ComponentがClient Componentを動的にインポートする場合、自動的な[コード分割](https://developer.mozilla.org/docs/Glossary/Code_splitting)は現在サポートされていません。 ### SSRのスキップ {#skipping-ssr} -`React.lazy()`とSuspenseを使用する場合、client componentはデフォルトで[プリレンダリング](https://github.com/reactwg/server-components/discussions/4)(SSR)されます。 +`React.lazy()`とSuspenseを使用する場合、Client Componentsはデフォルトで[プリレンダリング](https://github.com/reactwg/server-components/discussions/4)(SSR)されます。 -> **Note:** `ssr: false`オプションはclient componentでのみ機能し、クライアントのコード分割が適切に動作するようにclient componentに移動してください。 +> **Note:** `ssr: false`オプションはClient Componentsでのみ機能し、クライアントのコード分割が適切に動作するようにClient Componentsに移動してください。 -client componentのプリレンダリングを無効にしたい場合は、`ssr`オプションを`false`に設定できます: +Client Componentのプリレンダリングを無効にしたい場合は、`ssr`オプションを`false`に設定できます: ```jsx const ComponentC = dynamic(() => import('../components/C'), { ssr: false }) @@ -71,8 +72,7 @@ const ComponentC = dynamic(() => import('../components/C'), { ssr: false }) ### Server Componentsのインポート {#importing-server-components} -server componentを動的にインポートする場合、そのserver componentの子であるclient componentのみが遅延ロードされます。server component自体は遅延ロードされません。 -また、server componentで使用する場合、CSSなどの静的アセットのプリロードにも役立ちます。 +Server Componentを動的にインポートする場合、Server Component自体ではなく、その子であるClient Componentsのみが遅延読み込みされます。また、Server Componentsで使用する際にCSSなどの静的アセットをプリロードするのにも役立ちます。 ```jsx title="app/page.js" import dynamic from 'next/dynamic' @@ -89,12 +89,12 @@ export default function ServerComponentExample() { } ``` -> **Note:** server componentでは`ssr: false`オプションはサポートされていません。server componentで使用しようとするとエラーが表示されます。 -> `ssr: false`はserver componentで`next/dynamic`と共に使用することはできません。client componentに移動してください。 +> **Note:** Server Componentsでは`ssr: false`オプションはサポートされていません。Server Componentsで使用しようとするとエラーが発生します。 +> `ssr: false`はServer Componentsで`next/dynamic`と共に使用することはできません。Client Componentに移動してください。 ### 外部ライブラリの読み込み {#loading-external-libraries} -外部ライブラリは、[`import()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import)関数を使用してオンデマンドで読み込むことができます。この例では、ファジー検索のために外部ライブラリ`fuse.js`を使用しています。モジュールは、ユーザーが検索入力に入力した後にのみクライアントで読み込まれます。 +外部ライブラリは[`import()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import)関数を使用してオンデマンドで読み込むことができます。この例では、ファジー検索のために外部ライブラリ`fuse.js`を使用しています。モジュールはユーザーが検索入力に入力した後にのみクライアントで読み込まれます。 ```jsx title="app/page.js" 'use client' @@ -174,7 +174,7 @@ const ClientComponent = dynamic(() => -`next/dynamic`を使用することで、ヘッダーコンポーネントはページの初期JavaScriptバンドルに含まれません。ページは最初にSuspenseの`fallback`をレンダリングし、`Suspense`境界が解決されると`Header`コンポーネントをレンダリングします。 +`next/dynamic`を使用することで、ヘッダーコンポーネントはページの初期JavaScriptバンドルに含まれません。ページは最初にSuspenseの`fallback`をレンダリングし、`Suspense`境界が解決されると`Header`コンポーネントを続けてレンダリングします。 ```jsx import dynamic from 'next/dynamic' @@ -209,7 +209,7 @@ const DynamicComponent = dynamic(() => ## SSRなしの場合 {#with-no-ssr} -クライアントサイドでコンポーネントを動的に読み込むには、`ssr`オプションを使用してサーバーレンダリングを無効にできます。これは、外部依存関係やコンポーネントが`window`のようなブラウザAPIに依存している場合に便利です。 +クライアントサイドでコンポーネントを動的に読み込むには、`ssr`オプションを使用してサーバーレンダリングを無効にできます。これは、`window`のようなブラウザAPIに依存する外部依存関係やコンポーネントに役立ちます。 ```jsx 'use client' @@ -223,7 +223,7 @@ const DynamicHeader = dynamic(() => import('../components/header'), { ## 外部ライブラリの場合 {#with-external-libraries} -この例では、ファジー検索のために外部ライブラリ`fuse.js`を使用しています。モジュールは、ユーザーが検索入力に入力した後にのみブラウザで読み込まれます。 +この例では、ファジー検索のために外部ライブラリ`fuse.js`を使用しています。モジュールはユーザーが検索入力に入力した後にのみブラウザで読み込まれます。 ```jsx import { useState } from 'react' diff --git a/docs/01-app/03-building-your-application/06-optimizing/14-local-development.mdx b/docs/01-app/02-guides/local-development.mdx similarity index 79% rename from docs/01-app/03-building-your-application/06-optimizing/14-local-development.mdx rename to docs/01-app/02-guides/local-development.mdx index 54a203c5..fddcf0b2 100644 --- a/docs/01-app/03-building-your-application/06-optimizing/14-local-development.mdx +++ b/docs/01-app/02-guides/local-development.mdx @@ -1,9 +1,10 @@ --- -title: 'ローカル開発' +title: 'ローカル開発環境を最適化する方法' +nav_title: '開発環境' description: 'Next.jsでローカル開発環境を最適化する方法を学びましょう。' --- -Next.jsは、優れた開発者体験を提供するように設計されています。アプリケーションが成長するにつれて、ローカル開発中のコンパイル時間が遅くなることに気付くかもしれません。このガイドでは、一般的なコンパイル時のパフォーマンス問題を特定し、修正する方法を説明します。 +Next.jsは、優れた開発者体験を提供するように設計されています。アプリケーションが成長するにつれて、ローカル開発中のコンパイル時間が遅くなることがあります。このガイドでは、一般的なコンパイル時のパフォーマンス問題を特定し、修正する方法を説明します。 ## ローカル開発と本番環境の違い {#local-dev-vs-production} @@ -15,13 +16,13 @@ Next.jsは、優れた開発者体験を提供するように設計されてい ### 1. コンピュータのウイルス対策ソフトを確認する {#1-check-your-computer-s-antivirus} -ウイルス対策ソフトウェアはファイルアクセスを遅くする可能性があります。 +ウイルス対策ソフトウェアはファイルアクセスを遅くすることがあります。 プロジェクトフォルダをウイルス対策の除外リストに追加してみてください。これはWindowsマシンで一般的ですが、ウイルス対策ツールがインストールされているシステムには推奨されます。 ### 2. Next.jsを更新し、Turbopackを有効にする {#2-update-next-js-and-enable-turbopack} -Next.jsの最新バージョンを使用していることを確認してください。新しいバージョンには、パフォーマンスの向上が含まれていることがよくあります。 +Next.jsの最新バージョンを使用していることを確認してください。新しいバージョンには、しばしばパフォーマンスの改善が含まれています。 Turbopackは、Next.jsに統合された新しいバンドラーで、ローカルパフォーマンスを向上させることができます。 @@ -34,7 +35,7 @@ npm run dev --turbopack ### 3. インポートを確認する {#3-check-your-imports} -コードのインポート方法は、コンパイルとバンドルの時間に大きく影響します。[パッケージバンドルの最適化](/docs/app/building-your-application/optimizing/package-bundling)について詳しく学び、[Dependency Cruiser](https://github.com/sverweij/dependency-cruiser)や[Madge](https://github.com/pahen/madge)などのツールを探索してください。 +コードのインポート方法は、コンパイルとバンドルの時間に大きく影響します。[パッケージバンドルの最適化](/docs/app/guides/package-bundling)について詳しく学び、[Dependency Cruiser](https://github.com/sverweij/dependency-cruiser)や[Madge](https://github.com/pahen/madge)などのツールを探索してください。 ### アイコンライブラリ {#icon-libraries} @@ -62,7 +63,7 @@ import Icon2 from 'react-icons/md/Icon2' ### バレルファイル {#barrel-files} -"バレルファイル"は、他のファイルから多くのアイテムをエクスポートするファイルです。これらは、モジュールスコープで副作用があるかどうかをインポートを使用してコンパイラが解析する必要があるため、ビルドを遅くする可能性があります。 +"バレルファイル"は、他のファイルから多くのアイテムをエクスポートするファイルです。これらは、モジュールスコープ内で副作用があるかどうかをインポートを使用してコンパイラが解析する必要があるため、ビルドを遅くする可能性があります。 可能であれば、特定のファイルから直接インポートするようにしてください。[バレルファイルについて詳しくはこちら](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)とNext.jsの組み込み最適化について学びましょう。 @@ -84,7 +85,7 @@ Turbopackはインポートを自動的に解析し、最適化します。こ Tailwind CSSを使用している場合は、正しく設定されていることを確認してください。 -一般的な間違いは、`content`配列を`node_modules`やスキャンすべきでない大きなディレクトリを含むように設定することです。 +一般的な間違いは、`content`配列を`node_modules`やスキャンすべきでない他の大きなディレクトリを含むように設定することです。 Tailwind CSSバージョン3.4.8以降では、ビルドを遅くする可能性のある設定について警告します。 @@ -116,27 +117,27 @@ Tailwind CSSバージョン3.4.8以降では、ビルドを遅くする可能性 カスタムwebpack設定を追加した場合、それがコンパイルを遅くしている可能性があります。 -ローカル開発に本当に必要かどうかを検討してください。特定のツールを本番ビルドのみに含めるか、Turbopackに移行して[loaders](/docs/app/api-reference/config/next-config-js/turbopack#supported-loaders)を使用することを検討してください。 +ローカル開発に本当に必要かどうかを考慮してください。特定のツールを本番ビルドのみに含めるか、Turbopackに移行して[loaders](/docs/app/api-reference/config/next-config-js/turbopack#supported-loaders)を使用することを検討してください。 -### 6. メモリ使用量を最適化する {#6-optimize-memory-usage} +### 6. メモリ使用量の最適化 {#6-optimize-memory-usage} -アプリが非常に大きい場合、より多くのメモリが必要になるかもしれません。 +アプリが非常に大きい場合、より多くのメモリが必要になることがあります。 -[メモリ使用量の最適化について詳しくはこちら](/docs/app/building-your-application/optimizing/memory-usage)。 +[メモリ使用量の最適化について詳しくはこちら](/docs/app/guides/memory-usage)。 ### 7. Server Componentsとデータフェッチ {#7-server-components-and-data-fetching} -Server Componentsへの変更は、ローカルでページ全体を再レンダリングし、新しい変更を表示するためにコンポーネントの新しいデータをフェッチすることを含みます。 +Server Componentsへの変更は、ページ全体を再レンダリングし、新しいデータをコンポーネントに表示するためにローカルで再レンダリングを引き起こします。 -実験的な`serverComponentsHmrCache`オプションを使用すると、ローカル開発でのホットモジュールリプレースメント(HMR)リフレッシュ中にServer Components内の`fetch`レスポンスをキャッシュできます。これにより、応答が高速化され、課金されるAPIコールのコストが削減されます。 +実験的な`serverComponentsHmrCache`オプションを使用すると、ローカル開発でのホットモジュールリプレースメント(HMR)リフレッシュ間でServer Components内の`fetch`レスポンスをキャッシュできます。これにより、レスポンスが高速化され、課金されるAPIコールのコストが削減されます。 [実験的オプションについて詳しくはこちら](/docs/app/api-reference/config/next-config-js/serverComponentsHmrCache)。 ## 問題を見つけるためのツール {#tools-for-finding-problems} -### 詳細なフェッチログ {#detailed-fetch-logging} +### 詳細なfetchログ {#detailed-fetch-logging} -開発中に何が起こっているのかをより詳細に知るために、このコマンドを使用してください: +開発中に何が起こっているかの詳細情報を確認するには、このコマンドを使用してください: ```bash next dev --verbose @@ -145,16 +146,16 @@ next dev --verbose ## Turbopackトレース {#turbopack-tracing} Turbopackトレースは、ローカル開発中のアプリケーションのパフォーマンスを理解するのに役立つツールです。 -各モジュールのコンパイルにかかる時間とそれらの関連性についての詳細な情報を提供します。 +各モジュールのコンパイルにかかる時間とそれらの関連性についての詳細情報を提供します。 -1. Next.jsの最新バージョンがインストールされていることを確認します。 +1. 最新バージョンのNext.jsがインストールされていることを確認します。 1. Turbopackトレースファイルを生成します: ```bash NEXT_TURBOPACK_TRACING=1 npm run dev ``` -1. アプリケーションをナビゲートしたり、ファイルを編集して問題を再現します。 +1. アプリケーション内をナビゲートしたり、ファイルを編集して問題を再現します。 1. Next.js開発サーバーを停止します。 1. `.next`フォルダに`trace-turbopack`というファイルが生成されます。 1. `next internal trace [path-to-file]`を使用してファイルを解釈できます: @@ -170,7 +171,7 @@ Turbopackトレースは、ローカル開発中のアプリケーションの ``` 1. トレースサーバーが実行されると、https://trace.nextjs.org/でトレースを表示できます。 -1. デフォルトでは、トレースビューアはタイミングを集計します。各個別の時間を表示するには、ビューアの右上で「Aggregated in order」から「Spans in order」に切り替えることができます。 +1. デフォルトでは、トレースビューアはタイミングを集計します。各個別の時間を確認するには、ビューアの右上で「Aggregated in order」から「Spans in order」に切り替えることができます。 ## まだ問題がありますか? {#still-having-problems} diff --git a/docs/01-app/03-building-your-application/07-configuring/05-mdx.mdx b/docs/01-app/02-guides/mdx.mdx similarity index 84% rename from docs/01-app/03-building-your-application/07-configuring/05-mdx.mdx rename to docs/01-app/02-guides/mdx.mdx index 3f1669fe..8fc64f07 100644 --- a/docs/01-app/03-building-your-application/07-configuring/05-mdx.mdx +++ b/docs/01-app/02-guides/mdx.mdx @@ -1,12 +1,12 @@ --- -title: 'MarkdownとMDX' +title: 'Next.jsでのMarkdownとMDXの使用方法' nav_title: 'MDX' -description: 'MDXを設定し、Next.jsアプリで使用する方法を学びます。' +description: 'MDXを設定し、Next.jsアプリで使用する方法を学びましょう。' --- -{/* このドキュメントの内容はapp routerとpages routerの間で共有されています。Pages Routerに特化したコンテンツを追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} +{/* このドキュメントの内容は、app routerとpages routerの間で共有されています。Pages Routerに特有のコンテンツを追加するには、`Content`コンポーネントを使用できます。共有コンテンツはコンポーネントでラップしないでください。 */} -[Markdown](https://daringfireball.net/projects/markdown/syntax)は、テキストをフォーマットするための軽量マークアップ言語です。プレーンテキストの構文を使用して書き、それを構造的に有効なHTMLに変換することができます。ウェブサイトやブログのコンテンツを書く際によく使用されます。 +[Markdown](https://daringfireball.net/projects/markdown/syntax)は、テキストをフォーマットするために使用される軽量マークアップ言語です。プレーンテキストの構文を使用して書き、それを構造的に有効なHTMLに変換することができます。ウェブサイトやブログのコンテンツを書く際によく使用されます。 次のように書くと... @@ -20,9 +20,9 @@ I **love** using [Next.js](https://nextjs.org/)

I love using Next.js

``` -[MDX](https://mdxjs.com/)は、Markdownのスーパーセットであり、Markdownファイル内で直接[JSX](https://react.dev/learn/writing-markup-with-jsx)を書くことができます。これは、動的なインタラクティビティを追加し、Reactコンポーネントをコンテンツ内に埋め込む強力な方法です。 +[MDX](https://mdxjs.com/)は、Markdownのスーパーセットであり、Markdownファイル内で直接[JSX](https://react.dev/learn/writing-markup-with-jsx)を書くことができます。動的なインタラクティビティを追加し、Reactコンポーネントをコンテンツ内に埋め込む強力な方法です。 -Next.jsは、アプリケーション内のローカルMDXコンテンツと、サーバー上で動的に取得されるリモートMDXファイルの両方をサポートできます。Next.jsプラグインは、MarkdownとReactコンポーネントをHTMLに変換する処理を行い、Server Components(App Routerでのデフォルト)での使用もサポートしています。 +Next.jsは、アプリケーション内のローカルMDXコンテンツと、サーバー上で動的にフェッチされるリモートMDXファイルの両方をサポートできます。Next.jsプラグインは、MarkdownとReactコンポーネントをHTMLに変換する処理を行い、Server Components(App Routerでのデフォルト)での使用もサポートしています。 > **Good to know**: 完全な動作例については、[Portfolio Starter Kit](https://vercel.com/templates/next.js/portfolio-starter-kit)テンプレートを参照してください。 @@ -58,11 +58,11 @@ const withMDX = createMDX({ export default withMDX(nextConfig) ``` -これにより、`.md`および`.mdx`ファイルがアプリケーション内でページ、ルート、またはインポートとして機能するようになります。 +これにより、`.md`および`.mdx`ファイルをアプリケーション内のページ、ルート、またはインポートとして使用できるようになります。 ## `mdx-components.tsx`ファイルの追加 {#add-an-mdx-components-tsx-file} -グローバルなMDXコンポーネントを定義するために、プロジェクトのrootに`mdx-components.tsx`(または`.js`)ファイルを作成します。例えば、`pages`や`app`と同じレベル、または該当する場合は`src`内に作成します。 +プロジェクトのrootに`mdx-components.tsx`(または`.js`)ファイルを作成して、グローバルなMDXコンポーネントを定義します。たとえば、`pages`や`app`と同じレベル、または該当する場合は`src`内に配置します。 @@ -95,7 +95,7 @@ export function useMDXComponents(components) { > > - `mdx-components.tsx`は、App Routerで`@next/mdx`を使用するために**必須**であり、これがないと動作しません。 > - [`mdx-components.tsx`ファイルの規約](/docs/app/api-reference/file-conventions/mdx-components)について詳しく学びましょう。 -> - [カスタムスタイルとコンポーネントの使用](#using-custom-styles-and-components)について学びましょう。 +> - [カスタムスタイルとコンポーネントの使用](#using-custom-styles-and-components)方法を学びましょう。 ## MDXのレンダリング {#rendering-mdx} @@ -136,7 +136,7 @@ App Routerアプリでは、[メタデータ](/docs/app/building-your-applicatio
-これらのファイル内でMDXを使用し、MDXページ内で直接Reactコンポーネントをインポートすることもできます: +これらのファイル内でMDXを使用し、MDXページ内でReactコンポーネントを直接インポートすることもできます: ```mdx import { MyComponent } from 'my-component' @@ -193,7 +193,7 @@ Checkout my React component: -これらのファイル内でMDXを使用し、MDXページ内で直接Reactコンポーネントをインポートすることもできます: +これらのファイル内でMDXを使用し、MDXページ内でReactコンポーネントを直接インポートすることもできます: @@ -219,7 +219,7 @@ Checkout my React component: -ページ内でMDXファイルをインポートしてコンテンツを表示します: +ページ内でMDXファイルをインポートして、コンテンツを表示します: @@ -287,7 +287,7 @@ export default function Page() { ファイルシステムルーティングを使用せずに、動的なMDXコンポーネントをインポートできます。 -例えば、別のディレクトリからMDXコンポーネントをロードする動的ルートセグメントを持つことができます: +たとえば、別のディレクトリからMDXコンポーネントをロードする動的ルートセグメントを持つことができます: 動的MDXコンポーネントのルートセグメント -[`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params)を使用して、提供されたルートをプリレンダリングできます。`dynamicParams`を`false`に設定すると、`generateStaticParams`で定義されていないルートにアクセスすると404になります。 +[`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params)を使用して、提供されたルートを事前レンダリングできます。`dynamicParams`を`false`に設定すると、`generateStaticParams`で定義されていないルートにアクセスすると404になります。 @@ -342,13 +342,13 @@ export const dynamicParams = false -> **Good to know**: インポート時に`.mdx`ファイル拡張子を指定してください。[モジュールパスエイリアス](/docs/app/getting-started/installation#set-up-absolute-imports-and-module-path-aliases)(例: `@/content`)を使用する必要はありませんが、インポートパスを簡素化します。 +> **Good to know**: インポート時に`.mdx`ファイル拡張子を指定することを確認してください。[モジュールパスエイリアス](/docs/app/getting-started/installation#set-up-absolute-imports-and-module-path-aliases)(例: `@/content`)を使用する必要はありませんが、インポートパスを簡素化します。 ## カスタムスタイルとコンポーネントの使用 {#using-custom-styles-and-components} -MarkdownはレンダリングされるとネイティブのHTML要素にマッピングされます。例えば、次のMarkdownを書くと: +Markdownはレンダリングされると、ネイティブのHTML要素にマッピングされます。たとえば、次のMarkdownを書くと: ```md ## This is a heading {#this-is-a-heading} @@ -374,7 +374,7 @@ This is a list in markdown: ``` -Markdownをスタイルするために、生成されたHTML要素にマッピングされるカスタムコンポーネントを提供できます。スタイルとコンポーネントは、グローバル、ローカル、および共有レイアウトで実装できます。 +Markdownをスタイルするには、生成されたHTML要素にマッピングするカスタムコンポーネントを提供できます。スタイルとコンポーネントは、グローバル、ローカル、および共有レイアウトで実装できます。 ### グローバルスタイルとコンポーネント {#global-styles-and-components} @@ -440,7 +440,7 @@ export function useMDXComponents(components) { ### ローカルスタイルとコンポーネント {#local-styles-and-components} -インポートしたMDXコンポーネントにスタイルとコンポーネントを渡すことで、特定のページにローカルスタイルとコンポーネントを適用できます。これらは[グローバルスタイルとコンポーネント](#global-styles-and-components)とマージされ、上書きされます。 +インポートしたMDXコンポーネントに渡すことで、特定のページにローカルスタイルとコンポーネントを適用できます。これらは[グローバルスタイルとコンポーネント](#global-styles-and-components)とマージされ、上書きされます。 @@ -611,7 +611,7 @@ export default function MDXPage({ children }) { このプラグインは、Markdownのようなソースからのコンテンツブロックにタイポグラフィスタイルを追加するための`prose`クラスを追加します。 -[Tailwind typographyのインストール](https://github.com/tailwindlabs/tailwindcss-typography?tab=readme-ov-file#installation)と[共有レイアウト](#shared-layouts)を使用して、必要な`prose`を追加します。 +[Tailwind typographyをインストール](https://github.com/tailwindlabs/tailwindcss-typography?tab=readme-ov-file#installation)し、[共有レイアウト](#shared-layouts)で使用して、必要な`prose`を追加します。 @@ -700,13 +700,13 @@ export default function MDXPage({ children }) { ## Frontmatter {#frontmatter} -Frontmatterは、ページに関するデータを保存するために使用できるYAMLのようなキー/値のペアリングです。`@next/mdx`はデフォルトではfrontmatterをサポートしていませんが、MDXコンテンツにfrontmatterを追加するための多くのソリューションがあります。例えば: +Frontmatterは、ページに関するデータを保存するために使用されるYAMLのようなキー/値のペアリングです。`@next/mdx`はデフォルトではfrontmatterをサポートしていませんが、MDXコンテンツにfrontmatterを追加するための多くのソリューションがあります。例えば: - [remark-frontmatter](https://github.com/remarkjs/remark-frontmatter) - [remark-mdx-frontmatter](https://github.com/remcohaszing/remark-mdx-frontmatter) - [gray-matter](https://github.com/jonschlinkert/gray-matter) -`@next/mdx`は、他のJavaScriptコンポーネントと同様にエクスポートを使用することを**許可**しています: +`@next/mdx`は、他のJavaScriptコンポーネントと同様にエクスポートを使用することを許可しています: @@ -790,7 +790,7 @@ export default function Page() { -これの一般的な使用例は、MDXのコレクションを反復処理してデータを抽出したい場合です。例えば、すべてのブログ投稿からブログインデックスページを作成する場合です。[Nodeの`fs`モジュール](https://nodejs.org/api/fs.html)や[globby](https://www.npmjs.com/package/globby)などのパッケージを使用して、投稿のディレクトリを読み取り、メタデータを抽出できます。 +これの一般的な使用例は、MDXのコレクションを反復処理してデータを抽出したい場合です。たとえば、すべてのブログ投稿からブログインデックスページを作成することです。 [Nodeの`fs`モジュール](https://nodejs.org/api/fs.html)や[globby](https://www.npmjs.com/package/globby)などのパッケージを使用して、投稿のディレクトリを読み取り、メタデータを抽出できます。 > **Good to know**: > @@ -799,9 +799,9 @@ export default function Page() { ## remarkとrehypeプラグイン {#remark-and-rehype-plugins} -MDXコンテンツを変換するために、remarkとrehypeプラグインをオプションで提供できます。 +MDXコンテンツを変換するために、オプションでremarkとrehypeプラグインを提供できます。 -例えば、[`remark-gfm`](https://github.com/remarkjs/remark-gfm)を使用してGitHub Flavored Markdownをサポートできます。 +たとえば、[`remark-gfm`](https://github.com/remarkjs/remark-gfm)を使用してGitHub Flavored Markdownをサポートできます。 remarkとrehypeのエコシステムはESMのみであるため、設定ファイルとして`next.config.mjs`または`next.config.ts`を使用する必要があります。 @@ -856,11 +856,11 @@ export default withMDX(nextConfig) ## リモートMDX {#remote-mdx} -MDXファイルやコンテンツが*他の場所*にある場合、サーバー上で動的に取得できます。これは、CMS、データベース、または他の場所に保存されたコンテンツに便利です。この用途に人気のあるコミュニティパッケージは[`next-mdx-remote`](https://github.com/hashicorp/next-mdx-remote#react-server-components-rsc--nextjs-app-directory-support)です。 +MDXファイルやコンテンツが*他の場所*にある場合、サーバー上で動的にフェッチできます。これは、CMS、データベース、または他の場所に保存されたコンテンツに便利です。この用途に人気のあるコミュニティパッケージは[`next-mdx-remote`](https://github.com/hashicorp/next-mdx-remote#react-server-components-rsc--nextjs-app-directory-support)です。 -> **Good to know**: 注意して進めてください。MDXはJavaScriptにコンパイルされ、サーバー上で実行されます。信頼できるソースからのみMDXコンテンツを取得する必要があります。そうしないと、リモートコード実行(RCE)につながる可能性があります。 +> **Good to know**: 注意して進めてください。MDXはJavaScriptにコンパイルされ、サーバー上で実行されます。信頼できるソースからのみMDXコンテンツをフェッチする必要があります。そうしないと、リモートコード実行(RCE)につながる可能性があります。 -次の例では`next-mdx-remote`を使用しています: +次の例では、`next-mdx-remote`を使用します: @@ -952,9 +952,9 @@ export async function getStaticProps() { ## 深掘り: MarkdownをHTMLに変換する方法 {#deep-dive-how-do-you-transform-markdown-into-html} -ReactはMarkdownをネイティブに理解しません。Markdownのプレーンテキストは、まずHTMLに変換される必要があります。これは`remark`と`rehype`で実現できます。 +ReactはネイティブにMarkdownを理解しません。Markdownのプレーンテキストは、まずHTMLに変換する必要があります。これは`remark`と`rehype`を使用して達成できます。 -`remark`はMarkdownに関するツールのエコシステムです。`rehype`はHTMLに関する同様のエコシステムです。例えば、次のコードスニペットはMarkdownをHTMLに変換します: +`remark`はMarkdownに関するツールのエコシステムです。`rehype`はHTMLに関する同様のものです。たとえば、次のコードスニペットはMarkdownをHTMLに変換します: ```js import { unified } from 'unified' @@ -979,7 +979,7 @@ async function main() { `remark`と`rehype`のエコシステムには、[シンタックスハイライト](https://github.com/atomiks/rehype-pretty-code)、[見出しのリンク](https://github.com/rehypejs/rehype-autolink-headings)、[目次の生成](https://github.com/remarkjs/remark-toc)などのプラグインがあります。 -上記のように`@next/mdx`を使用する場合、`remark`や`rehype`を直接使用する必要は**ありません**。これは自動的に処理されます。ここでは、`@next/mdx`パッケージが内部で行っていることをより深く理解するために説明しています。 +上記のように`@next/mdx`を使用する場合、`remark`や`rehype`を直接使用する必要はありません。これらは自動的に処理されます。ここでは、`@next/mdx`パッケージが内部で行っていることをより深く理解するために説明しています。 ## RustベースのMDXコンパイラの使用(実験的) {#using-the-rust-based-mdx-compiler-experimental} diff --git a/docs/01-app/02-guides/memory-usage.mdx b/docs/01-app/02-guides/memory-usage.mdx new file mode 100644 index 00000000..0ed7203b --- /dev/null +++ b/docs/01-app/02-guides/memory-usage.mdx @@ -0,0 +1,137 @@ +--- +title: 'メモリ使用量を最適化する方法' +nav_title: 'メモリ使用量' +description: '開発および本番環境でアプリケーションのメモリ使用量を最適化します。' +--- + +アプリケーションが成長し、機能が豊富になるにつれて、ローカルでの開発や本番ビルドの作成時により多くのリソースを要求することがあります。 + +Next.jsでのメモリ最適化のための戦略と技術を探ってみましょう。 + +## 依存関係の数を減らす {#reduce-number-of-dependencies} + +依存関係が多いアプリケーションは、より多くのメモリを使用します。 + +[Bundle Analyzer](/docs/app/guides/package-bundling)を使用すると、アプリケーション内の大きな依存関係を調査し、パフォーマンスとメモリ使用量を改善するために削除できるかどうかを確認できます。 + +## `experimental.webpackMemoryOptimizations`を試す {#try-experimental-webpackmemoryoptimizations} + +`v15.0.0`から、`next.config.js`ファイルに`experimental.webpackMemoryOptimizations: true`を追加することで、Webpackの動作を変更し、最大メモリ使用量を削減できますが、コンパイル時間がわずかに増加する可能性があります。 + +> **Good to know**: この機能は現在実験的であり、より多くのプロジェクトでテストするために低リスクと考えられています。 + +## `--experimental-debug-memory-usage`で`next build`を実行する {#run-next-build-with-experimental-debug-memory-usage} + +`14.2.0`から、`next build --experimental-debug-memory-usage`を実行することで、Next.jsがビルド中にメモリ使用量に関する情報を継続的に出力するモードでビルドを実行できます。ヒープ使用量やガベージコレクションの統計情報などが表示されます。メモリ使用量が設定された制限に近づくと、自動的にヒープスナップショットが取得されます。 + +> **Good to know**: この機能は、カスタムwebpack設定がない限り自動的に有効になるWebpackビルドワーカーオプションと互換性がありません。 + +## ヒーププロファイルを記録する {#record-a-heap-profile} + +メモリの問題を探すために、Node.jsからヒーププロファイルを記録し、Chrome DevToolsで読み込んでメモリリークの潜在的な原因を特定できます。 + +ターミナルで、Next.jsビルドを開始する際にNode.jsに`--heap-prof`フラグを渡します: + +```sh +node --heap-prof node_modules/next/dist/bin/next build +``` + +ビルドの終了時に、Node.jsによって`.heapprofile`ファイルが作成されます。 + +Chrome DevToolsでは、メモリタブを開き、「Load Profile」ボタンをクリックしてファイルを視覚化できます。 + +## ヒープのスナップショットを分析する {#analyze-a-snapshot-of-the-heap} + +インスペクターツールを使用して、アプリケーションのメモリ使用量を分析できます。 + +`next build`または`next dev`コマンドを実行する際に、コマンドの先頭に`NODE_OPTIONS=--inspect`を追加します。これにより、デフォルトポートでインスペクターエージェントが公開されます。 +ユーザーコードが開始する前に停止したい場合は、代わりに`--inspect-brk`を渡すことができます。プロセスが実行中の間、Chrome DevToolsなどのツールを使用してデバッグポートに接続し、ヒープのスナップショットを記録して分析し、どのメモリが保持されているかを確認できます。 + +`14.2.0`から、`--experimental-debug-memory-usage`フラグを使用して`next build`を実行することもでき、ヒープスナップショットを簡単に取得できます。 + +このモードで実行中に、任意の時点でプロセスに`SIGUSR2`シグナルを送信すると、プロセスはヒープスナップショットを取得します。 + +ヒープスナップショットはNext.jsアプリケーションのプロジェクトrootに保存され、Chrome DevToolsなどのヒープアナライザーで読み込んで、どのメモリが保持されているかを確認できます。このモードはまだWebpackビルドワーカーと互換性がありません。 + +詳細については、[ヒープスナップショットの記録と分析方法](https://developer.chrome.com/docs/devtools/memory-problems/heap-snapshots)を参照してください。 + +## Webpackビルドワーカー {#webpack-build-worker} + +Webpackビルドワーカーを使用すると、別のNode.jsワーカー内でWebpackコンパイルを実行でき、ビルド中のアプリケーションのメモリ使用量を減少させることができます。 + +このオプションは、`v14.1.0`からカスタムWebpack設定がない場合にデフォルトで有効になります。 + +古いバージョンのNext.jsを使用している場合やカスタムWebpack設定がある場合は、`next.config.js`内に`experimental.webpackBuildWorker: true`を設定してこのオプションを有効にできます。 + +> **Good to know**: この機能はすべてのカスタムWebpackプラグインと互換性がない場合があります。 + +## Webpackキャッシュを無効にする {#disable-webpack-cache} + +[Webpackキャッシュ](https://webpack.js.org/configuration/cache/)は、ビルドの速度を向上させるために生成されたWebpackモジュールをメモリおよび/またはディスクに保存します。これによりパフォーマンスが向上しますが、キャッシュされたデータを保存するためにアプリケーションのメモリ使用量も増加します。 + +アプリケーションに[カスタムWebpack設定](/docs/app/api-reference/config/next-config-js/webpack)を追加することで、この動作を無効にできます: + +```js title="next.config.mjs" +/** @type {import('next').NextConfig} */ +const nextConfig = { + webpack: ( + config, + { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack } + ) => { + if (config.cache && !dev) { + config.cache = Object.freeze({ + type: 'memory', + }) + } + // 重要: 修正された設定を返す + return config + }, +} + +export default nextConfig +``` + +## 静的解析を無効にする {#disable-static-analysis} + +型チェックやリンティングは、特に大規模なプロジェクトでは多くのメモリを必要とする場合があります。 +しかし、ほとんどのプロジェクトにはこれらのタスクをすでに処理する専用のCIランナーがあります。 +ビルド中に「型の有効性のチェックとリンティング」ステップでメモリ不足の問題が発生する場合、ビルド中にこれらのタスクを無効にできます: + +```js title="next.config.mjs" +/** @type {import('next').NextConfig} */ +const nextConfig = { + eslint: { + // 警告: プロジェクトにESLintエラーがある場合でも + // 本番ビルドが正常に完了することを許可します。 + ignoreDuringBuilds: true, + }, + typescript: { + // !! 警告 !! + // プロジェクトに型エラーがある場合でも + // 本番ビルドが正常に完了することを危険に許可します。 + // !! 警告 !! + ignoreBuildErrors: true, + }, +} + +export default nextConfig +``` + +- [TypeScriptエラーの無視](/docs/app/api-reference/config/typescript#disabling-typescript-errors-in-production) +- [Next.js設定でのESLint](https://nextjs.org/docs/canary/pages/api-reference/config/next-config-js/eslint) + +これにより、型エラーやリンティングの問題が原因で誤ったデプロイが発生する可能性があることを覚えておいてください。 +静的解析が完了した後にのみビルドを本番環境に昇格させることを強くお勧めします。 +Vercelにデプロイする場合は、[ステージングデプロイメントのガイド](https://vercel.com/docs/deployments/managing-deployments#staging-and-promoting-a-production-deployment)を参照して、カスタムタスクが成功した後にビルドを本番環境に昇格させる方法を学ぶことができます。 + +## ソースマップを無効にする {#disable-source-maps} + +ソースマップの生成は、ビルドプロセス中に追加のメモリを消費します。 + +ソースマップの生成を無効にするには、Next.js設定に`productionBrowserSourceMaps: false`と`experimental.serverSourceMaps: false`を追加します。 + +> **Good to know**: 一部のプラグインはソースマップをオンにする可能性があり、無効にするためにカスタム設定が必要な場合があります。 + +## Edgeのメモリ問題 {#edge-memory-issues} + +Next.js `v14.1.3`では、Edge runtimeを使用する際のメモリ問題が修正されました。このバージョン(またはそれ以降)に更新して、問題が解決されるかどうかを確認してください。 diff --git a/docs/01-app/02-guides/migrating/from-create-react-app.mdx b/docs/01-app/02-guides/migrating/from-create-react-app.mdx index 5c3415e6..76ed2d79 100644 --- a/docs/01-app/02-guides/migrating/from-create-react-app.mdx +++ b/docs/01-app/02-guides/migrating/from-create-react-app.mdx @@ -10,20 +10,20 @@ description: '既存の React アプリケーションを Create React App か Create React App から Next.js に移行したい理由はいくつかあります: -### 初期ページ読み込み時間の遅さ {#slow-initial-page-loading-time} +### 初期ページの読み込み時間が遅い {#slow-initial-page-loading-time} -Create React App は純粋にクライアントサイドの React を使用しています。クライアントサイドのみのアプリケーション、別名 [シングルページアプリケーション (SPA)](/docs/app/guides/single-page-applications) は、初期ページ読み込み時間が遅くなることがよくあります。これは以下の理由によります: +Create React App は純粋にクライアントサイドの React を使用しています。クライアントサイドのみのアプリケーション、別名 [シングルページアプリケーション (SPA)](/docs/app/guides/single-page-applications) は、初期ページの読み込み時間が遅くなることがよくあります。これは以下の理由によります: -1. ブラウザは、React コードとアプリケーション全体のバンドルがダウンロードされて実行されるまで待つ必要があります。 -2. 新しい機能や依存関係を追加するたびにアプリケーションコードが増加します。 +1. ブラウザは、React コードとアプリケーション全体のバンドルがダウンロードされて実行されるのを待つ必要があり、その後でコードがデータをロードするためのリクエストを送信できるようになります。 +2. 新しい機能や依存関係を追加するたびに、アプリケーションコードが増加します。 ### 自動コード分割がない {#no-automatic-code-splitting} -前述の読み込み時間の遅さの問題は、コード分割である程度緩和できます。しかし、手動でコード分割を試みると、ネットワークウォーターフォールを引き起こす可能性があります。Next.js は、自動コード分割と tree-shaking をルーターとビルドパイプラインに組み込んでいます。 +前述の読み込み時間の遅さの問題は、コード分割によってある程度緩和できます。しかし、手動でコード分割を試みると、ネットワークのウォーターフォールを意図せずに引き起こす可能性があります。Next.js は、自動コード分割と tree-shaking をルーターとビルドパイプラインに組み込んでいます。 ### ネットワークウォーターフォール {#network-waterfalls} -パフォーマンスが悪化する一般的な原因は、データを取得するためにクライアントとサーバー間で順次リクエストを行うことです。[SPA](/docs/app/guides/single-page-applications) でのデータ取得のパターンの1つは、プレースホルダーをレンダリングし、コンポーネントがマウントされた後にデータを取得することです。残念ながら、子コンポーネントは親が自身のデータを読み込んだ後でしかデータを取得できないため、リクエストの「ウォーターフォール」が発生します。 +パフォーマンスが悪化する一般的な原因は、アプリケーションがデータを取得するためにクライアントとサーバー間で順次リクエストを行うことです。[SPA](/docs/app/guides/single-page-applications) でのデータ取得のパターンの1つは、プレースホルダーをレンダリングし、コンポーネントがマウントされた後にデータを取得することです。残念ながら、子コンポーネントは親が自身のデータを読み込んだ後でしかデータを取得できないため、リクエストの「ウォーターフォール」が発生します。 Next.js ではクライアントサイドのデータ取得もサポートされていますが、データ取得をサーバーに移動することもできます。これにより、クライアントとサーバー間のウォーターフォールが完全に排除されることがよくあります。 @@ -35,7 +35,7 @@ Next.js ではクライアントサイドのデータ取得もサポートされ ### データ取得戦略の選択 {#choose-the-data-fetching-strategy} -必要に応じて、Next.js ではページまたはコンポーネントレベルでデータ取得戦略を選択できます。たとえば、CMS からデータを取得し、ビルド時(SSG)にブログ投稿をレンダリングして高速な読み込み速度を実現したり、必要に応じてリクエスト時(SSR)にデータを取得したりできます。 +ニーズに応じて、Next.js ではページまたはコンポーネントレベルでデータ取得戦略を選択できます。たとえば、CMS からデータを取得し、ビルド時(SSG)にブログ投稿をレンダリングして高速な読み込み速度を実現したり、必要に応じてリクエスト時(SSR)にデータを取得したりできます。 ### ミドルウェア {#middleware} @@ -43,13 +43,13 @@ Next.js ではクライアントサイドのデータ取得もサポートされ ### 組み込みの最適化 {#built-in-optimizations} -[画像](/docs/app/building-your-application/optimizing/images)、[フォント](/docs/app/building-your-application/optimizing/fonts)、および[サードパーティスクリプト](/docs/app/building-your-application/optimizing/scripts) は、アプリケーションのパフォーマンスに大きな影響を与えることがよくあります。Next.js には、これらを自動的に最適化するための専用コンポーネントと API が含まれています。 +[画像](/docs/app/building-your-application/optimizing/images)、[フォント](/docs/app/building-your-application/optimizing/fonts)、および[サードパーティスクリプト](/docs/app/guides/scripts) は、アプリケーションのパフォーマンスに大きな影響を与えることがよくあります。Next.js には、これらを自動的に最適化するための専用コンポーネントと API が含まれています。 ## 移行手順 {#migration-steps} -私たちの目標は、できるだけ早く動作する Next.js アプリケーションを作成し、その後で Next.js の機能を段階的に採用できるようにすることです。まず、アプリケーションを純粋なクライアントサイドアプリケーション([SPA](/docs/app/guides/single-page-applications))として扱い、既存のルーターをすぐに置き換えないようにします。これにより、複雑さとマージの競合が軽減されます。 +目標は、できるだけ早く動作する Next.js アプリケーションを作成し、その後で Next.js の機能を段階的に採用できるようにすることです。まず、アプリケーションを純粋なクライアントサイドアプリケーション([SPA](/docs/app/guides/single-page-applications))として扱い、既存のルーターをすぐに置き換えないようにします。これにより、複雑さとマージの競合が軽減されます。 -> **注意**: `package.json` のカスタム `homepage` フィールド、カスタムサービスワーカー、特定の Babel/webpack 調整など、CRA の高度な設定を使用している場合は、Next.js でこれらの機能を再現または適応するためのヒントについて、このガイドの最後にある **追加の考慮事項** セクションを参照してください。 +> **注意**: `package.json` のカスタム `homepage` フィールド、カスタムサービスワーカー、特定の Babel/webpack 調整など、CRA の高度な設定を使用している場合は、ガイドの最後にある **追加の考慮事項** セクションを参照して、これらの機能を Next.js で再現または適応するためのヒントを確認してください。 ### ステップ 1: Next.js の依存関係をインストールする {#step-1-install-the-next-js-dependency} @@ -61,28 +61,28 @@ npm install next@latest ### ステップ 2: Next.js の設定ファイルを作成する {#step-2-create-the-next-js-configuration-file} -プロジェクトの root に `next.config.ts` を作成します(`package.json` と同じレベル)。このファイルには、[Next.js の設定オプション](/docs/app/api-reference/config/next-config-js)が含まれます。 +プロジェクトの root(`package.json` と同じレベル)に `next.config.ts` を作成します。このファイルには [Next.js の設定オプション](/docs/app/api-reference/config/next-config-js) が含まれます。 ```js title="next.config.ts" import type { NextConfig } from 'next' const nextConfig: NextConfig = { - output: 'export', // シングルページアプリケーション (SPA) を出力します - distDir: 'build', // ビルド出力ディレクトリを `build` に変更します + output: 'export', // シングルページアプリケーション (SPA) を出力 + distDir: 'build', // ビルド出力ディレクトリを `build` に変更 } export default nextConfig ``` -> **注意**: `output: 'export'` を使用すると、静的エクスポートを行っていることを意味します。サーバーサイドの機能(SSR や API など)にはアクセスできません。Next.js のサーバー機能を活用するには、この行を削除できます。 +> **注意**: `output: 'export'` を使用すると、静的エクスポートを行っていることになります。サーバーサイドの機能(SSR や API など)にはアクセスできません。この行を削除すると、Next.js のサーバー機能を活用できます。 -### ステップ 3: Root レイアウトを作成する {#step-3-create-the-root-layout} +### ステップ 3: root レイアウトを作成する {#step-3-create-the-root-layout} Next.js [App Router](/docs/app) アプリケーションには、すべてのページをラップする [root レイアウト](/docs/app/building-your-application/routing/layouts-and-templates#root-layout-required) ファイルが必要です。これは、[React Server Component](/docs/app/building-your-application/rendering/server-components) です。 CRA アプリケーションでの root レイアウトファイルに最も近いものは、``、``、および `` タグを含む `public/index.html` です。 -1. `src` ディレクトリ内に新しい `app` ディレクトリを作成します(または、`app` を root に配置する場合はプロジェクトの root に作成します)。 +1. `src` フォルダ内に新しい `app` ディレクトリを作成します(または、`app` を root に配置する場合はプロジェクトの root に作成します)。 2. `app` ディレクトリ内に `layout.tsx`(または `layout.js`)ファイルを作成します: @@ -110,7 +110,7 @@ export default function RootLayout({ children }) { -古い `index.html` の内容をこの `` コンポーネントにコピーします。`body div#root`(および `body noscript`)を `
{children}
` に置き換えます。 +次に、古い `index.html` の内容をこの `` コンポーネントにコピーします。`body div#root`(および `body noscript`)を `
{children}
` に置き換えます。 @@ -163,7 +163,7 @@ export default function RootLayout({ children }) { -> **Good to know**: Next.js はデフォルトで CRA の `public/manifest.json`、追加のアイコン、および[テスト設定](/docs/app/building-your-application/testing)を無視します。これらが必要な場合、Next.js は [Metadata API](/docs/app/building-your-application/optimizing/metadata) と[テスト](/docs/app/building-your-application/testing)のセットアップをサポートしています。 +> **Good to know**: Next.js はデフォルトで CRA の `public/manifest.json`、追加のアイコン、[テスト設定](/docs/app/guides/testing) を無視します。これらが必要な場合、Next.js には [Metadata API](/docs/app/building-your-application/optimizing/metadata) と [Testing](/docs/app/guides/testing) のセットアップがサポートされています。 ### ステップ 4: メタデータ {#step-4-metadata} @@ -216,7 +216,7 @@ export default function RootLayout({ children }) { -`favicon.ico`、`icon.png`、`robots.txt` などの[メタデータファイル](/docs/app/building-your-application/optimizing/metadata#file-based-metadata)は、`app` ディレクトリのトップレベルに配置されている限り、アプリケーションの `` タグに自動的に追加されます。すべての[サポートされているファイル](/docs/app/building-your-application/optimizing/metadata#file-based-metadata)を `app` ディレクトリに移動した後、それらの `` タグを安全に削除できます: +`favicon.ico`、`icon.png`、`robots.txt` などの[メタデータファイル](/docs/app/building-your-application/optimizing/metadata#file-based-metadata)は、`app` ディレクトリのトップレベルに配置されている限り、アプリケーションの `` タグに自動的に追加されます。すべての[サポートされているファイル](/docs/app/building-your-application/optimizing/metadata#file-based-metadata)を `app` ディレクトリに移動した後、`` タグを安全に削除できます: @@ -318,7 +318,7 @@ export default function RootLayout({ children }) { ### ステップ 5: スタイル {#step-5-styles} -CRA と同様に、Next.js は [CSS Modules](/docs/app/building-your-application/styling/css#css-modules) を標準でサポートしています。また、[グローバル CSS インポート](/docs/app/building-your-application/styling/css#global-styles)もサポートしています。 +CRA と同様に、Next.js は [CSS Modules](/docs/app/building-your-application/styling/css#css-modules) を標準でサポートしています。また、[グローバル CSS インポート](/docs/app/building-your-application/styling/css#global-styles) もサポートしています。 グローバル CSS ファイルがある場合は、`app/layout.tsx` にインポートします: @@ -357,7 +357,7 @@ Tailwind CSS を使用している場合は、[インストールドキュメン Create React App は `src/index.tsx`(または `index.js`)をエントリーポイントとして使用します。Next.js(App Router)では、`app` ディレクトリ内の各フォルダがルートに対応し、各フォルダには `page.tsx` が必要です。 -現在のところアプリを SPA として保持し、**すべて**のルートをインターセプトしたいので、[optional catch-all route](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) を使用します。 +アプリを SPA として保持し、**すべての**ルートをインターセプトしたいので、[optional catch-all route](/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments) を使用します。 1. **`app` 内に `[[...slug]]` ディレクトリを作成します。** @@ -399,11 +399,11 @@ export default function Page() { -これは Next.js に空のスラッグ(`/`)のための単一のルートを生成するよう指示し、**すべて**のルートを同じページにマッピングします。このページは[Server Component](/docs/app/building-your-application/rendering/server-components)であり、静的 HTML にプリレンダリングされます。 +これは、Next.js に空のスラッグ(`/`)のための単一のルートを生成するよう指示し、**すべての**ルートを同じページにマッピングします。このページは [Server Component](/docs/app/building-your-application/rendering/server-components) であり、静的 HTML にプリレンダリングされます。 ### ステップ 7: クライアント専用のエントリーポイントを追加する {#step-7-add-a-client-only-entrypoint} -次に、CRA の root App コンポーネントを[Client Component](/docs/app/building-your-application/rendering/client-components)内に埋め込み、すべてのロジックをクライアントサイドに残します。Next.js を初めて使用する場合、クライアントコンポーネント(デフォルトでは)もサーバーでプリレンダリングされることを知っておく価値があります。クライアントサイドの JavaScript を実行する追加の機能を持っていると考えることができます。 +次に、CRA の root App コンポーネントを [Client Component](/docs/app/building-your-application/rendering/client-components) 内に埋め込み、すべてのロジックをクライアントサイドに保持します。Next.js を初めて使用する場合、クライアントコンポーネント(デフォルトでは)もサーバーでプリレンダリングされることを知っておく価値があります。クライアントサイドの JavaScript を実行する追加の機能を持っていると考えることができます。 `app/[[...slug]]/` に `client.tsx`(または `client.js`)を作成します: @@ -440,8 +440,8 @@ export function ClientOnly() { -- `'use client'` ディレクティブは、このファイルを**クライアントコンポーネント**にします。 -- `dynamic` インポートと `ssr: false` は `` コンポーネントのサーバーサイドレンダリングを無効にし、真にクライアント専用(SPA)にします。 +- `'use client'` ディレクティブは、このファイルを **Client Component** にします。 +- `dynamic` インポートと `ssr: false` は、`` コンポーネントのサーバーサイドレンダリングを無効にし、純粋にクライアント専用(SPA)にします。 次に、`page.tsx`(または `page.js`)を更新して新しいコンポーネントを使用します: @@ -490,39 +490,39 @@ export default function App() { } ``` -Next.js では、静的画像インポートはオブジェクトを返します。このオブジェクトは Next.js の [`` コンポーネント](/docs/app/api-reference/components/image)で直接使用することができ、または既存の `` タグでオブジェクトの `src` プロパティを使用することができます。 +Next.js では、静的画像インポートはオブジェクトを返します。このオブジェクトは Next.js の [`` コンポーネント](/docs/app/api-reference/components/image) で直接使用することができ、または既存の `` タグでオブジェクトの `src` プロパティを使用することができます。 -`` コンポーネントには[自動画像最適化](/docs/app/building-your-application/optimizing/images)の追加の利点があります。`` コンポーネントは、画像の寸法に基づいて結果の `` の `width` と `height` 属性を自動的に設定します。これにより、画像が読み込まれるときのレイアウトシフトを防ぎます。ただし、アプリに寸法の一方のみがスタイルされ、他方が `auto` にスタイルされていない画像が含まれている場合、問題が発生する可能性があります。`auto` にスタイルされていない場合、寸法は `` の寸法属性の値にデフォルト設定され、画像が歪んで表示される可能性があります。 +`` コンポーネントには、[自動画像最適化](/docs/app/building-your-application/optimizing/images) の追加の利点があります。`` コンポーネントは、画像の寸法に基づいて結果の `` の `width` と `height` 属性を自動的に設定します。これにより、画像が読み込まれるときのレイアウトシフトを防ぎます。ただし、アプリに寸法の一方のみがスタイルされ、他方が `auto` にスタイルされていない画像が含まれている場合、問題が発生する可能性があります。`auto` にスタイルされていない場合、寸法は `` の寸法属性の値にデフォルト設定され、画像が歪んで表示される可能性があります。 -`` タグを保持することで、アプリケーションの変更量を減らし、上記の問題を防ぐことができます。その後、[ローダーを設定](/docs/app/building-your-application/optimizing/images#loaders)するか、画像を自動的に最適化するデフォルトの Next.js サーバーに移行することで、画像を最適化するために `` コンポーネントに移行することができます。 +`` タグを保持することで、アプリケーションの変更を減らし、上記の問題を防ぐことができます。その後、[ローダーを設定](/docs/app/building-your-application/optimizing/images#loaders) して画像を最適化するために `` コンポーネントに移行するか、または自動画像最適化を備えたデフォルトの Next.js サーバーに移行することができます。 **`/public` からインポートされた画像の絶対インポートパスを相対インポートに変換します:** ```tsx -// 変更前 +// Before import logo from '/logo.png' -// 変更後 +// After import logo from '../public/logo.png' ``` **画像オブジェクト全体ではなく、画像の `src` プロパティを `` タグに渡します:** ```tsx -// 変更前 +// Before -// 変更後 +// After ``` -または、ファイル名に基づいて画像アセットの公開 URL を参照することもできます。たとえば、`public/logo.png` はアプリケーションの `/logo.png` で画像を提供し、これが `src` 値になります。 +または、ファイル名に基づいて画像アセットの公開 URL を参照することもできます。たとえば、`public/logo.png` はアプリケーションで `/logo.png` で画像を提供し、これが `src` 値になります。 -> **警告**: TypeScript を使用している場合、`src` プロパティにアクセスするときに型エラーが発生する可能性があります。これを修正するには、`tsconfig.json` ファイルの [`include` 配列](https://www.typescriptlang.org/tsconfig#include)に `next-env.d.ts` を追加する必要があります。Next.js は、ステップ 9 でアプリケーションを実行するときにこのファイルを自動的に生成します。 +> **警告:** TypeScript を使用している場合、`src` プロパティにアクセスするときに型エラーが発生する可能性があります。これを修正するには、`tsconfig.json` ファイルの [`include` 配列](https://www.typescriptlang.org/tsconfig#include) に `next-env.d.ts` を追加する必要があります。Next.js は、ステップ 9 でアプリケーションを実行するときにこのファイルを自動的に生成します。 ### ステップ 9: 環境変数を移行する {#step-9-migrate-environment-variables} -Next.js は CRA と同様に[環境変数](/docs/app/building-your-application/configuring/environment-variables)をサポートしていますが、ブラウザで公開したい変数には `NEXT_PUBLIC_` プレフィックスが**必要**です。 +Next.js は CRA と同様に[環境変数](/docs/app/guides/environment-variables)をサポートしていますが、ブラウザで公開したい変数には `NEXT_PUBLIC_` プレフィックスが**必要**です。 主な違いは、クライアントサイドで環境変数を公開するために使用されるプレフィックスです。`REACT_APP_` プレフィックスを持つすべての環境変数を `NEXT_PUBLIC_` に変更します。 @@ -568,7 +568,7 @@ Create React App に特有のアーティファクトを削除できます: ### CRA でカスタム `homepage` を使用する {#using-a-custom-homepage-in-cra} -CRA の `package.json` で `homepage` フィールドを使用してアプリを特定のサブパスで提供していた場合、Next.js の `next.config.ts` で [`basePath` 設定](/docs/app/api-reference/config/next-config-js/basePath)を使用してそれを再現できます: +CRA の `package.json` で `homepage` フィールドを使用してアプリを特定のサブパスで提供していた場合、Next.js の `next.config.ts` で [`basePath` 設定](/docs/app/api-reference/config/next-config-js/basePath) を使用してそれを再現できます: ```ts title="next.config.ts" import { NextConfig } from 'next' @@ -583,11 +583,11 @@ export default nextConfig ### カスタム `Service Worker` の処理 {#handling-a-custom-service-worker} -CRA のサービスワーカー(例:`create-react-app` の `serviceWorker.js`)を使用していた場合、Next.js で[プログレッシブウェブアプリケーション (PWA)](/docs/app/building-your-application/configuring/progressive-web-apps)を作成する方法を学ぶことができます。 +CRA のサービスワーカー(例:`create-react-app` の `serviceWorker.js`)を使用していた場合、Next.js で [プログレッシブウェブアプリケーション (PWA)](/docs/app/guides/progressive-web-apps) を作成する方法を学ぶことができます。 ### API リクエストのプロキシ {#proxying-api-requests} -CRA アプリで `package.json` の `proxy` フィールドを使用してバックエンドサーバーへのリクエストを転送していた場合、`next.config.ts` で [Next.js のリライト](/docs/app/api-reference/config/next-config-js/rewrites)を使用してこれを再現できます: +CRA アプリで `package.json` の `proxy` フィールドを使用してバックエンドサーバーへのリクエストを転送していた場合、`next.config.ts` で [Next.js のリライト](/docs/app/api-reference/config/next-config-js/rewrites) を使用してこれを再現できます: ```ts title="next.config.ts" import { NextConfig } from 'next' @@ -613,7 +613,7 @@ import { NextConfig } from 'next' const nextConfig: NextConfig = { webpack: (config, { isServer }) => { - // ここで webpack 設定を変更します + // ここで webpack 設定を変更 return config }, } @@ -621,7 +621,7 @@ const nextConfig: NextConfig = { export default nextConfig ``` -> **注意**: これには `dev` スクリプトから `--turbopack` を削除して Turbopack を無効にする必要があります。 +> **注意**: これには、`dev` スクリプトから `--turbopack` を削除して Turbopack を無効にする必要があります。 ### TypeScript のセットアップ {#typescript-setup} @@ -635,25 +635,25 @@ Next.js は `tsconfig.json` がある場合、自動的に TypeScript をセッ ## バンドラーの互換性 {#bundler-compatibility} -Create React App と Next.js はどちらもデフォルトで webpack をバンドリングに使用します。Next.js はまた、ローカル開発をより高速にするための [Turbopack](/docs/app/api-reference/config/next-config-js/turbopack) を提供しています: +Create React App と Next.js はどちらもデフォルトで webpack をバンドリングに使用します。Next.js は、ローカル開発をより高速にするための [Turbopack](/docs/app/api-reference/config/next-config-js/turbopack) も提供しています: ```bash next dev --turbopack ``` -CRA から高度な webpack 設定を移行する必要がある場合は、[カスタム webpack 設定](/docs/app/api-reference/config/next-config-js/webpack)を提供することもできます。 +CRA から高度な webpack 設定を移行する必要がある場合、[カスタム webpack 設定](/docs/app/api-reference/config/next-config-js/webpack) を提供することもできます。 ## 次のステップ {#next-steps} -すべてが正常に動作した場合、現在はシングルページアプリケーションとして動作する Next.js アプリケーションがあります。まだサーバーサイドレンダリングやファイルベースのルーティングなどの Next.js の機能を活用していませんが、これらを段階的に行うことができます: +すべてが正常に動作した場合、現在はシングルページアプリケーションとして動作する Next.js アプリケーションがあります。まだサーバーサイドレンダリングやファイルベースのルーティングなどの Next.js の機能を活用していませんが、段階的に行うことができます: -- [Next.js App Router](/docs/app/building-your-application/routing) に**React Router から移行**して: +- **React Router から移行**して、以下のために [Next.js App Router](/docs/app/building-your-application/routing) を使用します: - 自動コード分割 - [ストリーミングサーバーレンダリング](/docs/app/building-your-application/routing/loading-ui-and-streaming) - [React Server Components](/docs/app/building-your-application/rendering/server-components) -- [`` コンポーネント](/docs/app/building-your-application/optimizing/images)で**画像を最適化** -- [`next/font`](/docs/app/building-your-application/optimizing/fonts)で**フォントを最適化** -- [` ``` -または `dangerouslySetInnerHTML` プロパティを使用して: +または、`dangerouslySetInnerHTML`プロパティを使用することもできます: ```jsx