Next.js入門ガイド:特徴・できること・始め方を徹底解説
Web開発の世界は常に進化しており、より良いユーザー体験、高いパフォーマンス、そして効率的な開発プロセスを実現するための新しいツールやフレームワークが次々と登場しています。その中でも、特に注目を集め、多くの開発者に採用されているのが「Next.js」です。
Reactをベースとしながらも、ルーティング、データ取得、コード分割、サーバーサイドレンダリングといった多くの機能を標準で提供し、開発者が複雑な設定なしに高性能なアプリケーションを構築できるように設計されています。本記事では、このNext.jsの魅力に迫り、その特徴、できること、そしてこれからNext.jsを学び始める方がスムーズに開発に入れるよう、具体的な始め方までを詳細に解説していきます。
Next.jsは、静的なブログサイトから大規模な動的Webアプリケーション、さらにはAPIバックエンドまで、幅広い用途に対応できる柔軟性を持っています。しかし、その多機能さゆえに、どこから学び始めれば良いか迷う方もいるかもしれません。この記事が、あなたのNext.js学習の第一歩を踏み出すための、最も網羅的で分かりやすいガイドとなることを目指します。
さあ、Next.jsの世界へ飛び込み、次世代のWeb開発を体験してみましょう。
1. Next.jsとは何か? なぜNext.jsなのか?
1.1 Next.jsの概要
Next.jsは、Reactフレームワークの1つです。ReactはUI構築のためのJavaScriptライブラリですが、そのままではルーティングやデータ取得の方法、アプリケーション全体の構成といった部分を開発者自身が設計・実装する必要があります。Next.jsは、これらの一般的なWebアプリケーション開発に必要な機能や構成をフレームワークとして提供することで、開発者がアプリケーションの「構築」そのものに集中できるようにします。
Next.jsの最大の特徴は、その柔軟なレンダリング方法にあります。クライアントサイドレンダリング(CSR)だけでなく、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)、さらにはその両方の利点を組み合わせたIncremental Static Regeneration(ISR)といった複数のレンダリング戦略をアプリケーションのページごとに選択・組み合わせることができます。これにより、パフォーマンス、SEO、ユーザー体験の向上を同時に実現することが可能です。
また、ファイルシステムベースのルーティングを採用しており、ディレクトリ構造がそのままURLのパスに対応するため、直感的で分かりやすいルーティング設定が可能です。加えて、/api
ディレクトリ以下にファイルを配置することで、簡単にサーバーレスAPIエンドポイントを作成できる機能も持っています。
開発体験においても、Fast Refreshによる高速なホットリローディング、コード分割の自動化、TypeScriptやESLint、Tailwind CSSなどのモダンな開発ツールとの連携など、生産性を高める多くの仕組みが組み込まれています。
Next.jsは、Vercelという企業によって開発・メンテナンスされており、特にVercelプラットフォーム上でのデプロイに最適化されていますが、Netlify、AWS、Azureなど、他の様々な環境にもデプロイ可能です。
1.2 なぜNext.jsを使うのか? Web開発の課題とNext.js
モダンなWeb開発、特にReactのようなクライアントサイドでJavaScriptを実行してUIを構築するライブラリを使った開発には、いくつかの課題がありました。
- 初期表示速度とパフォーマンス: クライアントサイドレンダリング(CSR)では、ブラウザがHTML、CSS、JavaScriptファイルをダウンロードし、JavaScriptを実行して初めてコンテンツが表示されます。このJavaScriptの実行に時間がかかる場合、ユーザーは真っ白な画面を見せられたり、インタラクティブになるまでの時間が長くなったりしてしまいます。特にネットワーク環境が悪い場合や、デバイスのスペックが低い場合には顕著な問題となります。
- SEO (検索エンジン最適化): 多くの検索エンジンのクローラーは、静的なHTMLコンテンツを効率的に解析します。CSRで構築されたサイトは、初期のHTMLにはコンテンツがほとんど含まれておらず、JavaScriptの実行結果にコンテンツが生成されるため、クローラーが正しくコンテンツを認識できない可能性がありました(最近のクローラーはJavaScriptの実行も行いますが、完全に信頼できるわけではありません)。これは、検索エンジンのランキングに影響を与えかねない重要な課題です。
- 開発の複雑さ: React単体では、ルーティング、状態管理、ビルド設定、サーバーサイドレンダリングの導入など、アプリケーション全体を構築するための多くの決定と実装が必要です。これらをゼロから行うのは手間がかかりますし、ベストプラクティスに沿って行うためにはある程度の専門知識が必要です。
- API連携: フロントエンドとバックエンドを分離して開発する場合、APIエンドポイントを別途用意する必要があります。小規模なアプリケーションやプロトタイプの場合でも、簡単なデータ取得やフォーム送信のためのサーバーサイドの処理が必要になることがあります。
Next.jsは、これらの課題に対する包括的な解決策を提供します。
- パフォーマンス・SEOの向上: SSRやSSG、ISRといったプリレンダリング機能により、サーバー側でHTMLを生成してブラウザに送信できます。これにより、初期表示速度が向上し、検索エンジンのクローラーもコンテンツを容易に解析できるようになります。ブラウザに送られるHTMLにはすでにコンテンツが含まれているため、JavaScriptが実行される前でもユーザーは内容を見ることができます。
- 開発効率の向上: ファイルシステムベースのルーティング、API Routes、ビルド設定の自動化、Fast Refreshなどの機能が標準で提供されるため、開発者はアプリケーションのコア機能開発に集中できます。面倒な設定やボイラープレートコードを大幅に削減できます。
- 柔軟なデータ取得とレンダリング: ページの特性に応じて、最適なデータ取得方法(ビルド時、リクエスト時など)とレンダリング戦略を選択できます。これにより、パフォーマンス要件、コンテンツの更新頻度、SEO要件など、様々な側面から最適なアーキテクチャを実現できます。
- フルスタック開発の可能性: API Routes機能により、Next.jsプロジェクト内にバックエンドのロジック(データベースアクセス、認証、外部API連携など)を記述できます。これにより、小規模なプロジェクトやプロトタイプであれば、別途バックエンドサーバーを用意することなく、Next.jsだけで完結した開発が可能になります。
これらの理由から、Next.jsは現代のWebアプリケーション開発において、非常に強力で実践的な選択肢となっています。パフォーマンス、SEO、開発体験の全てを高いレベルで実現したい開発者にとって、Next.jsは学ぶ価値のあるフレームワークです。
1.3 本記事の目的
本記事は、Next.jsに興味を持っている、またはこれからNext.jsを学び始めたいと考えている方を対象としています。Next.jsが持つ多くの特徴やメリットを理解し、実際に手を動かして開発を始めるための具体的なステップを学ぶことを目的とします。
- Next.jsの主要な機能やコンセプト(SSR, SSG, ISR, API Routesなど)を分かりやすく解説します。
- Next.jsでどのような種類のアプリケーションが開発できるのか、具体的なイメージを持っていただきます。
- 開発環境のセットアップから、簡単なページの作成、ルーティング、データ取得、API Routeの作成、スタイリング、画像の表示など、開発を始めるために必要な基本的な知識と手順を解説します。
- 特に、Next.js 13以降で導入された新しいルーティングシステムであるApp Routerを中心に解説しつつ、従来のPages Routerとの違いや関係性にも触れます。
- Next.jsをさらに深く学ぶためのリソースも紹介します。
約5000語というボリュームを活かし、各項目を網羅的かつ詳細に説明することで、読者がこの記事を読み終えた後に、自信を持ってNext.jsプロジェクトを開始できるようになることを目指します。
2. Next.jsの主要な特徴とメリット
Next.jsが多くの開発者に選ばれる理由となる、その主要な特徴と、それがもたらすメリットについて詳しく見ていきましょう。
2.1 サーバーサイドレンダリング (SSR) と静的サイト生成 (SSG) / プリレンダリング
Next.jsの最も強力な特徴の一つは、柔軟なプリレンダリング機能です。これにより、クライアントサイドでのJavaScript実行前に、サーバー側でページのHTMLを生成できます。プリレンダリングには主にSSRとSSGの2つの方法があります。
2.1.1 サーバーサイドレンダリング (SSR)
- 仕組み: ユーザーからのリクエストがあるたびに、サーバー側でページのReactコンポーネントをHTMLにレンダリングし、そのHTMLをブラウザに返します。クライアント側では、受け取ったHTMLを表示し、バックグラウンドでJavaScriptをダウンロード・実行して、ページをインタラクティブな状態にします(これを「ハイドレーション (Hydration)」と呼びます)。
- メリット:
- リアルタイム性の高いコンテンツ: リクエストごとに最新のデータを取得してレンダリングできるため、頻繁に更新される情報やユーザーごとに内容が変わるページ(例: ダッシュボード、ログイン後のページ)に適しています。
- パフォーマンス: 初回表示に必要なHTMLがサーバーから直接送られるため、クライアント側でのJavaScript実行待ち時間が短縮され、ページの表示が速くなります。
- SEO: 検索エンジンのクローラーはサーバーから送られるHTMLをそのまま解析できるため、SEOに非常に有利です。
- デメリット:
- サーバー負荷: リクエストごとにレンダリング処理が発生するため、アクセス数が増えるとサーバーの負荷が高まります。
- TTFB (Time To First Byte) の増加: サーバー側でのレンダリング処理に時間がかかる場合、ブラウザが最初のバイトを受け取るまでの時間が長くなる可能性があります。
2.1.2 静的サイト生成 (SSG)
- 仕組み: アプリケーションのビルド時に、事前に全てのページを静的なHTMLファイルとして生成します。ユーザーからのリクエストがあった際には、生成済みのHTMLファイルをCDN(Contents Delivery Network)などから配信します。クライアント側では、受け取ったHTMLを表示し、SSRと同様にハイドレーションを行います。
- メリット:
- 極めて高いパフォーマンス: サーバー側での動的な処理が不要なため、ユーザーは最も高速な方法(通常はCDNからの配信)でコンテンツを受け取ることができます。TTFBが非常に短くなります。
- 高いスケーラビリティ: 生成済みの静的ファイルを配信するだけなので、アクセス数が急増してもサーバー負荷はほとんど増えず、安定したパフォーマンスを維持できます。
- SEO: SSRと同様に、検索エンジンのクローラーは静的なHTMLを容易に解析できます。
- コスト効率: 静的ファイルをホストするコストは、動的にサーバーを運用するコストと比較して一般的に低くなります。
- デメリット:
- コンテンツのリアルタイム性: コンテンツを更新した場合、サイトを再ビルドしてデプロイし直すまで、ユーザーは古いコンテンツを見ることになります。頻繁に更新される情報やユーザー固有の情報を含むページには不向きです。
2.1.3 ハイドレーション (Hydration)
SSRやSSGでサーバーからHTMLを受け取ったブラウザは、まずそのHTMLを表示します。その後、ページに必要なJavaScriptファイルがダウンロード・実行されます。このJavaScriptが、サーバー側でレンダリングされたDOMツリーにイベントリスナーをアタッチしたり、Reactのコンポーネントツリーと紐付けたりするプロセスを「ハイドレーション」と呼びます。ハイドレーションが完了すると、ページは完全にインタラクティブな状態になります。ハイドレーションが完了するまでは、ユーザーがボタンをクリックしても反応しないなどの現象が発生する可能性があります。Next.jsは、このハイドレーション処理を効率的に行うように設計されています。
2.1.4 SSRとSSGの使い分け
Next.jsでは、ページごとにSSRとSSGを柔軟に使い分けることができます。
- SSGが適しているケース:
- ブログ記事、ドキュメント、企業の紹介ページなど、コンテンツが頻繁に更新されないページ。
- ユーザーごとに内容が変わらない、公開情報のみを表示するページ。
- 最高のパフォーマンスとスケーラビリティが求められるページ。
- SSRが適しているケース:
- ログイン後のユーザー専用ダッシュボードやプロフィールページ。
- ショッピングサイトのカートページや注文履歴ページなど、ユーザー固有の情報をリアルタイムに表示する必要があるページ。
- 検索結果ページやニュース記事一覧など、常に最新の情報が必要で、かつデータソースが頻繁に更新されるページ。
Pages Routerを使用していた頃は、getStaticProps
(SSG)やgetServerSideProps
(SSR)といった特別なデータ取得関数を使ってこのレンダリング戦略を指定していました。App Routerでは、デフォルトがSSGに近い動作(Static Render)であり、fetch
APIのキャッシュ設定やコンポーネントの種類(Server Component/Client Component)によって、柔軟にレンダリング戦略を制御する考え方に進化しています。
2.2 ファイルシステムベースのルーティング
Next.jsは、プロジェクトのディレクトリ構造に基づいて自動的にルーティングを生成します。これは直感的で設定が簡単です。
- Pages Router (従来のルーティング): ルートディレクトリの
pages/
ディレクトリ以下にReactコンポーネントファイル(.js
,.jsx
,.ts
,.tsx
)を配置すると、ファイル名やディレクトリ構造がそのままURLパスに対応します。pages/index.js
->/
pages/about.js
->/about
pages/blog/index.js
->/blog
pages/blog/first-post.js
->/blog/first-post
- App Router (新しいルーティング): ルートディレクトリの
app/
ディレクトリ以下にディレクトリを作成し、その中にpage.js
(または.jsx
,.ts
,.tsx
) ファイルを配置します。ディレクトリ構造がURLパスに対応し、page.js
がそのパスで表示されるコンテンツとなります。app/page.js
->/
app/about/page.js
->/about
app/blog/page.js
->/blog
(/blog
の一覧ページなど)app/blog/[slug]/page.js
->/blog/first-post
,/blog/second-post
など ([slug] 部分が動的なパラメータになる)
本記事では、最新の推奨であるApp Routerを中心に解説します。
2.2.1 ダイナミックルーティング
特定のパターンに一致するパスに対して、動的にコンテンツを生成する機能です。例えば、ブログ記事の詳細ページなど、記事IDやスラッグによってURLが変わるような場合に利用します。
- Pages Router:
pages/posts/[id].js
のようにファイル名を角括弧[]
で囲みます。[id]
部分がURLパスの動的なセグメントになります。 - App Router:
app/blog/[slug]/page.js
のようにディレクトリ名を角括弧[]
で囲みます。[slug]
ディレクトリ内のpage.js
コンポーネント内で、params
というプロパティを通じて動的なセグメントの値(この例ではスラッグ)にアクセスできます。
これにより、個別のファイルを作成することなく、大量の動的なページに対応できます。
2.2.2 Catch-allルーティング
特定のパス以下の全てのセグメントを捕捉するルーティングです。例えば、ドキュメントサイトで、任意の階層のパスに対応する場合などに利用します。
- Pages Router:
pages/docs/[...slug].js
のようにファイル名を角括弧と3つのドット[...]
で囲みます。slug
はパスセグメントの配列として取得できます。 - App Router:
app/docs/[[...slug]]/page.js
のようにディレクトリ名を角括弧と3つのドット[...]
で囲みます。外側の角括弧[]
はOptional Catch-all(セグメントがなくてもマッチする)を意味し、内側の[...]
はCatch-all(セグメントが存在する場合、その全てを捕捉)を意味します。セグメントはparams.slug
として配列で取得できます。
2.3 API Routes
Next.jsには、フロントエンドと同じプロジェクト内でバックエンドのAPIエンドポイントを作成できる機能があります。
- 仕組み: Pages Routerでは
pages/api/
ディレクトリ以下に、App Routerではapp/api/
ディレクトリ以下にファイルを作成します。これらのファイルはクライアントサイドのバンドルに含まれず、サーバーサイドでのみ実行されるサーバーレス関数として扱われます。 -
App RouterでのAPI Route:
app/api/
ディレクトリ以下にディレクトリを作成し、その中にroute.js
(または.ts
) ファイルを配置します。このファイル内で、GET
,POST
,PUT
,DELETE
などのHTTPメソッドに対応する関数をエクスポートします。
“`javascript
// app/api/hello/route.js
import { NextResponse } from ‘next/server’;export async function GET(request) {
return NextResponse.json({ message: ‘Hello, API Routes!’ });
}export async function POST(request) {
const data = await request.json();
return NextResponse.json({ received: data, message: ‘Data received!’ });
}
``
/api/hello` パスへのGETリクエストに対してJSONレスポンスを返し、POSTリクエストに対してリクエストボディを処理するエンドポイントを作成しています。
この例では、
* メリット:
* 手軽なバックエンド: 簡単なデータ取得、フォーム送信処理、認証、データベース連携など、小規模なバックエンド機能を素早く実装できます。
* フルスタック開発: フロントエンドとバックエンドを同じプロジェクト内で管理できるため、開発効率が向上します。
* サーバーレス: Vercelなどのプラットフォームにデプロイすると、これらのAPI Routesは自動的にサーバーレス関数として扱われ、必要な時に必要なだけリソースが利用されるため、スケーラブルかつコスト効率が高くなります。
* BFF (Backend For Frontend): クライアントが必要とするデータを整形したり、複数の外部APIを組み合わせて呼び出したりするBFFとしての役割を持たせることもできます。
ただし、API RoutesはあくまでNext.jsプロジェクト内での補助的なバックエンド機能であり、複雑で大規模なバックエンドロジックが必要な場合は、別途専用のバックエンドサーバーを構築することも検討すべきです。
2.4 Incremental Static Regeneration (ISR)
SSGは非常に高速ですが、コンテンツ更新時に再ビルド・再デプロイが必要という欠点がありました。ISRは、SSGの高速性を保ちつつ、コンテンツの更新にも対応するための機能です。
- 仕組み: SSGと同様にビルド時にページを生成しますが、加えてページのデータが古くなった場合に、バックグラウンドで新しいデータを取得してページを再生成する設定を行います。
fetch
APIのオプションや、Pages RouterではgetStaticProps
のrevalidate
オプションを使用して、この再生成間隔(秒単位)を指定します。 - 動作例:
revalidate: 60
と設定した場合、- 最初のユーザーがページにアクセスすると、ビルド時に生成された静的ページが表示されます。
- 60秒以内に別のユーザーがアクセスしても、同じ静的ページが表示されます。
- 60秒経過後にユーザーがアクセスすると、一度ビルド時の静的ページを表示しつつ、Next.jsはバックグラウンドでページの再生成を開始します。
- 再生成が完了すると、それ以降のユーザーには新しく生成されたページが表示されるようになります。再生成中にアクセスしたユーザーには古いページが表示され続けます。
- メリット:
- SSGのパフォーマンスとスケーラビリティを維持できます。
- コンテンツが更新されても、手動での再ビルド・再デプロイなしにページを最新の状態に保つことができます。
- ブログ記事など、コンテンツの更新頻度は高くないが、常に最新の状態を表示したいページに最適です。
- 注意点: 再生成がバックグラウンドで行われるため、設定した再生成間隔内、あるいは再生成処理中には、ユーザーが古いコンテンツを見ることになる可能性がある点を理解しておく必要があります。リアルタイム性が厳密に求められる情報には向きません。
App Routerでは、fetch
APIのキャッシュ設定(cache: 'no-store'
でSSR相当、next: { revalidate: 60 }
でISR相当)によってISRに近い動作を実現します。
2.5 Fast Refresh
開発中のコード変更を即座にブラウザに反映させる機能です。コードを変更してファイルを保存すると、ブラウザのページが自動的に更新され、変更内容が表示されます。
- メリット:
- 開発効率の向上: コード変更の度に手動でページをリロードする必要がないため、開発サイクルが大幅に短縮されます。
- ステートの保持: Reactコンポーネントのローカルステート(
useState
などで管理されているデータ)を可能な限り保持したまま更新されるため、アプリケーションの特定の状態を維持したままUIの変更を確認できます。これは、フォーム入力中のUI調整や、モーダルを開いた状態でのスタイル変更などに非常に便利です。
- ホットリローディングとの違い: 従来のホットリローディングでは、コンポーネントの状態がリセットされてしまうことがよくありました。Fast RefreshはReactのコンポーネントモデルに最適化されており、よりインテリジェントにステートを保持します。
2.6 Code Splitting (コード分割)
Next.jsは、ページごとに必要なJavaScriptコードのみを読み込むように、自動的にコードを分割します。
- 仕組み: 通常、Reactアプリケーションでは全てのJavaScriptコードを1つの大きなファイル(バンドル)にまとめてブラウザに読み込ませます。しかし、Next.jsはページ単位でバンドルを分割するため、ユーザーが特定のページにアクセスした際に、そのページに必要な最小限のコードだけがダウンロードされます。
- メリット:
- 初期ロード時間の短縮: ダウンロードするJavaScriptの量が減るため、ページの初期表示が速くなります。
- パフォーマンスの向上: 不要なコードのパースや実行が不要になるため、ブラウザの負荷が軽減されます。
特別な設定なしにこの最適化が自動で行われるのは、Next.jsの大きな強みです。
2.7 スタイリングの多様なサポート
Next.jsは、様々なスタイリング手法に対応しています。
- Global CSS:
app/global.css
のようなファイルに記述し、アプリケーション全体に適用できます。 - CSS Modules:
.module.css
という拡張子のファイルにスタイルを記述することで、各コンポーネントにローカルスコープなCSSクラスを適用できます。クラス名の衝突を防ぎ、メンテナンス性を高めます。 - Styled Components, EmotionなどのCSS-in-JSライブラリ: これらのライブラリも問題なく利用できます。
- Tailwind CSS: 人気のユーティリティファーストCSSフレームワークであるTailwind CSSも、簡単な設定で導入・利用できます。
create-next-app
でプロジェクトを作成する際にTailwind CSSを含めるオプションも提供されています。
開発者は自分の好みやプロジェクトの要件に合わせて、最適なスタイリング手法を選択できます。
2.8 Image Optimization (next/image
)
Webサイトのパフォーマンスにおいて、画像の最適化は非常に重要です。Next.jsは、next/image
コンポーネントを提供しており、これを利用することで画像の最適化を自動で行えます。
- 仕組み:
next/image
コンポーネントは、画像の遅延ロード(Lazy Loading)、レスポンシブ表示のためのサイズの自動調整、WebPやAVIFといった次世代画像フォーマットへの自動変換、画像の最適化された配信(Vercelデプロイ時など)といった機能を組み込んでいます。 - メリット:
- パフォーマンス向上: 画像の読み込み速度が向上し、Cumulative Layout Shift (CLS) のようなWeb Vitals指標の改善に貢献します。
- 開発の手間削減: 手動での画像最適化や複数の画像サイズを用意する手間が省けます。
- Core Web Vitalsへの貢献: 重要なユーザー体験指標であるCore Web Vitalsの改善に繋がります。
ローカルの画像ファイルだけでなく、リモートの画像URLも最適化できます(ただし、next.config.js
に設定が必要です)。
2.9 TypeScript サポート
Next.jsは、TypeScriptによる開発を強力にサポートしています。create-next-app
でプロジェクトを作成する際にTypeScriptを選択でき、型安全性のある開発を進めることができます。
2.10 その他の特徴
- ES Module / CommonJS サポート: 両方のモジュール形式をサポートしており、既存のライブラリとの互換性が高いです。
- 環境変数のサポート:
.env.local
などのファイルを使って環境変数を簡単に管理できます。
これらの特徴により、Next.jsは開発者に強力なツールを提供し、パフォーマンスが高く、メンテナンスしやすいWebアプリケーションの構築を支援します。
3. Next.jsで「できること」具体例
Next.jsの柔軟なレンダリング戦略と豊富な機能を活用することで、様々な種類のWebサイトやアプリケーションを効率的に開発できます。ここでは、Next.jsで実現可能な具体的なプロジェクト例をいくつか紹介します。
3.1 静的サイト (ブログ、コーポレートサイト、ドキュメントサイト)
コンテンツが頻繁に更新されない、あるいは更新頻度が低いサイトに最適です。SSG(静的サイト生成)を最大限に活用することで、極めて高速な表示と高いスケーラビリティ、そして優れたSEOを実現できます。
- ブログ: Markdownなどのマークアップ言語で記事を記述し、ビルド時に各記事ページを静的に生成します。
[slug].js
や[slug]/page.js
といったダイナミックルーティングとSSG (getStaticPaths
,getStaticProps
または App Router のgenerateStaticParams
とfetch
API のキャッシュ設定) を組み合わせることで、数千、数万の記事があるブログでも高速に表示できます。ISR (revalidate
) を利用すれば、新しい記事を公開した際に手動で再ビルドすることなく、一定期間後に自動で最新の状態に更新することも可能です。 - コーポレートサイト: 会社の情報、サービス紹介、お問い合わせページなど、比較的変更が少ないページを静的に生成します。高いパフォーマンスは信頼性の向上に繋がり、SEOの強さは新規顧客獲得に貢献します。
- ドキュメントサイト: 技術ドキュメントなど、構造化された大量のコンテンツを静的に生成します。検索機能などを組み合わせる場合でも、基本となるページ表示はSSGにより高速に行えます。Catch-allルーティング (
[[...slug]]/page.js
) が役立ちます。
3.2 動的なWebアプリケーション (管理画面、SNS風アプリ、SaaSアプリケーション)
ユーザー認証が必要なページ、ユーザー固有の情報が表示されるページ、頻繁にデータが更新されるページなど、リアルタイム性が求められるアプリケーションにも対応できます。主にSSR(サーバーサイドレンダリング)や、クライアントサイドでのデータ取得(CSR)を組み合わせることで実現します。
- 管理画面/ダッシュボード: ログインユーザーに合わせた情報を表示したり、データの追加・編集・削除といった操作を行ったりする機能が必要です。SSRで初期表示を高速化しつつ、ログイン状態のチェックやユーザーごとのデータ取得を行います。データの更新やインタラクティブな操作はクライアントサイドのJavaScriptで行います。API Routesを使って、管理画面から呼び出すバックエンドAPIを実装することも可能です。
- SNS風アプリケーション: ユーザーフィード、プロフィールページ、コメント機能など、ユーザー間のインタラクションやリアルタイムなデータ表示が重要な要素となります。SSRでフィードの初期表示を行い、その後の新しい投稿の読み込みやコメント機能はクライアントサイドで行うなど、機能に応じてSSRとCSRを組み合わせます。ユーザー認証やデータの投稿・取得にはAPI Routesを活用できます。
- SaaSアプリケーション: サービス利用状況の表示、設定変更、各種データの管理など、機能が多岐にわたり、ユーザーごとに表示内容が大きく変わるアプリケーションです。コア機能の表示にはSSRを利用し、グラフの描画や複雑なフォーム入力などはクライアントサイドで行うなど、最適なレンダリング戦略を選択します。API Routesは、アプリケーションが必要とする様々なバックエンド処理を実装するのに役立ちます。
3.3 Eコマースサイト
商品の表示、検索、カート、注文処理など、静的なコンテンツと動的なコンテンツが混在するEコマースサイトもNext.jsで構築できます。
- 商品一覧/詳細ページ: 商品情報は頻繁に更新される可能性があるため、SSRで最新情報を表示するか、ISRで一定期間キャッシュしつつバックグラウンドで更新する戦略が考えられます。膨大な商品数を扱う場合は、SSGとISRの組み合わせが特に有効です。
- カート/チェックアウトページ: ユーザー固有の情報(カートに入っている商品、配送先情報など)を扱うため、これらのページはSSRまたはCSRで実装するのが一般的です。ユーザー認証や注文処理はAPI Routesを介して行います。
- ブログ/特集ページ: SSGを利用して高速表示します。
next/image
コンポーネントによる画像最適化は、大量の商品画像を扱うEコマースサイトで特に大きな効果を発揮します。
3.4 APIサーバー (API Routes)
Next.jsプロジェクトの主要な部分がAPI Routesであるような、API中心のアプリケーションとしても利用できます。
- BFF (Backend For Frontend): フロントエンドの要件に合わせて、複数のバックエンドサービスからのデータを集約・整形して提供するAPI層として機能させます。
- マイクロサービス: 小規模な独立したAPIサービスとして開発し、他のサービスから利用されるような設計も可能です。
- シンプルなバックエンド: データベースとの連携、外部サービスのAPI呼び出し、認証・認可など、比較的シンプルなバックエンド機能を実装するのに利用します。
Next.jsのAPI Routesはサーバーレスとして動作するため、スケーラビリティが高く、運用コストを抑えられるメリットがあります。
3.5 Jamstack構成の実現
Jamstack(JavaScript, APIs, Markup)は、事前に生成された静的ファイル(Markup)をCDNから配信し、必要に応じてクライアントサイドのJavaScriptからAPI(APIs)を呼び出して動的な機能を実現するアーキテクチャパターンです。
Next.jsはSSG機能により高性能な静的ファイルを生成でき、API Routes機能によりサーバーレスなAPIを提供できるため、Jamstack構成を非常に容易に実現できます。VercelなどのJamstackホスティングプラットフォームにデプロイすることで、そのメリットを最大限に活かすことができます。
このように、Next.jsは単なる静的サイトジェネレーターでも、単なるSSRフレームワークでもなく、アプリケーションの特性に応じて最適なレンダリング戦略と開発手法を選択できる柔軟性を持っています。これにより、小規模な個人プロジェクトから大規模なエンタープライズアプリケーションまで、幅広いニーズに対応できる汎用性の高いフレームワークとなっています。
4. Next.jsの始め方 (実践)
ここからは、実際に手を動かしてNext.jsプロジェクトを開始するための具体的なステップを解説します。最新の推奨であるApp Routerを中心に説明を進めます。
4.1 環境構築
Next.jsプロジェクトを開始するには、以下の環境が必要です。
- Node.js: Next.jsはNode.js上で動作します。バージョン18.17以降を推奨します。Node.jsの公式サイトからダウンロード・インストールできます。インストール時にnpm(Node Package Manager)も同時にインストールされます。
- npm, yarn, または pnpm: Node.jsのパッケージマネージャーです。npmはNode.jsに付属していますが、yarnやpnpmを使用することもできます。いずれか一つがあれば十分です。
npm -v
やyarn -v
、pnpm -v
コマンドでバージョンが表示されればインストール済みです。
これらの準備ができていることを確認してください。
4.2 プロジェクトの作成 (create-next-app
)
Next.jsプロジェクトを作成する最も簡単な方法は、公式が提供している create-next-app
というCLIツールを使用することです。ターミナル(コマンドプロンプトやPowerShellなど)を開き、以下のコマンドを実行します。
bash
npx create-next-app@latest my-next-app
npx
: Node.jsの実行コマンドです。create-next-app
をローカルにインストールせずに実行できます。create-next-app@latest
:create-next-app
ツールの最新版を指定しています。my-next-app
: 作成するプロジェクトのディレクトリ名です。任意の名前を指定できます。
コマンドを実行すると、プロジェクトの設定に関するいくつかの質問が対話形式で表示されます。
What is your project named? my-next-app
Would you like to use TypeScript? (Yes/No) Yes # TypeScriptを使用するか
Would you like to use ESLint? (Yes/No) Yes # ESLintを使用するか
Would you like to use Tailwind CSS? (Yes/No) No # Tailwind CSSを使用するか (今回はNoで進めます)
Would you like to use `src/` directory? (Yes/No) No # `src` ディレクトリを使用するか
Would you like to use App Router? (Yes/No) Yes # App Routerを使用するか (強く推奨)
Would you like to customize the default import alias (@/*)? (Yes/No) No # インポートエイリアスを設定するか
- TypeScript: 静的型付けによる開発は、特に規模が大きくなるにつれてコードの品質や保守性を高めます。学習コストはかかりますが、導入を強く推奨します。
- ESLint: コードの静的解析ツールです。コードの品質を保ち、潜在的なバグを防ぐのに役立ちます。導入を推奨します。
- Tailwind CSS: ユーティリティファーストのCSSフレームワークです。もし利用する場合はYesを選択してください。後から手動で導入することも可能です。
src/
directory: プロジェクトのソースコードをsrc
ディレクトリ以下に配置するかどうかです。組織によってはこの構造を好む場合もありますが、必須ではありません。- App Router: Next.js 13から導入された新しいルーティングシステムです。Server Components、Nested Layouts、高度なデータ取得機能など、多くの新機能がApp Routerによって提供されます。今後のNext.js開発の主流となるため、新規プロジェクトではApp Routerの利用を強く推奨します。
- Import alias:
@/
のようなエイリアスを設定することで、import Component from '@/components/Component'
のようにルートディレクトリからの相対パスでインポートできるようになります。あると便利です。
質問に回答していくと、必要なファイルや依存関係のインストールが自動的に行われます。完了したら、作成されたディレクトリに移動します。
bash
cd my-next-app
これで、Next.jsプロジェクトの準備が整いました。
4.3 基本的なファイル構成 (App Router)
create-next-app
でApp Routerを選択して作成したプロジェクトの基本的なファイル構成を見てみましょう(主要なファイルのみ抜粋)。
my-next-app/
├── app/ # App Router のルートディレクトリ
│ ├── layout.js # ルートレイアウト (<html>, <body> など)
│ ├── page.js # トップページ (/)
│ └── globals.css # グローバルCSSファイル
├── public/ # 静的ファイル (画像など) を配置するディレクトリ
├── next.config.js # Next.js の設定ファイル
├── package.json # プロジェクト情報と依存関係
├── tailwind.config.js # Tailwind CSS 設定ファイル (Tailwindを選択した場合)
└── tsconfig.json # TypeScript 設定ファイル (TypeScriptを選択した場合)
app/
ディレクトリ
App Routerの全てのルートとロジックはこのディレクトリ以下に配置されます。
app/layout.js
(または.tsx
):- アプリケーション全体のレイアウトを定義します。ルートレイアウトは
<html>
タグと<body>
タグを含める必須のファイルです。 children
というプロパティを受け取り、これがネストされたレイアウトやページコンポーネントになります。- サーバーコンポーネントとしてデフォルトでレンダリングされます。
javascript
// app/layout.js
export default function RootLayout({ children }) {
return (
<html lang="ja">
<body>{children}</body>
</html>
);
}
- アプリケーション全体のレイアウトを定義します。ルートレイアウトは
app/page.js
(または.tsx
):- 各ルートセグメントのUIを定義します。ファイル名が
page.js
のディレクトリが、そのパスに対応するページのエントリーポイントとなります。 app/page.js
はルートパス (/
) に対応します。- サーバーコンポーネントとしてデフォルトでレンダリングされます。
javascript
// app/page.js
export default function Page() {
return (
<h1>Hello, Next.js with App Router!</h1>
);
}
- 各ルートセグメントのUIを定義します。ファイル名が
app/globals.css
:- アプリケーション全体に適用されるグローバルなCSSスタイルを記述します。ルートレイアウトファイル (
app/layout.js
) でインポートする必要があります。
- アプリケーション全体に適用されるグローバルなCSSスタイルを記述します。ルートレイアウトファイル (
- その他の特別なファイル: App Routerでは、各ルートセグメント内に以下の特別なファイルを配置することで、様々なUIや機能を追加できます。
loading.js
: そのセグメントのコンテンツがロード中の間に表示されるUIを定義します。error.js
: そのセグメントとその子要素で発生したエラーを捕捉し、フォールバックUIを表示します。not-found.js
: そのセグメント以下にマッチするルートが見つからなかった場合に表示されるUIを定義します。template.js
: レイアウトと同様に子要素をラップしますが、ナビゲーションの際にステートがリセットされる点がレイアウトと異なります。アニメーションなどに使用されます。default.js
: Optional Catch-all ルート ([[...slug]]/page.js
) にマッチしない場合に表示されるUIを定義します。
これらのファイルを組み合わせることで、複雑なUI構成やエラーハンドリング、ローディング表示などを効率的に実現できます。
public/
ディレクトリ
画像、フォント、faviconなどの静的ファイルを配置します。これらのファイルは、アプリケーションのルートパス /
から直接アクセス可能です。
public/favicon.ico
->/favicon.ico
public/image.png
->/image.png
next.config.js
Next.jsのビルド設定や実行時の設定をカスタマイズするためのファイルです。JavaScriptファイルとして記述し、設定オブジェクトをエクスポートします。画像の最適化設定、環境変数の公開設定、ヘッダーの設定などを行います。
“`javascript
// next.config.js
/* @type {import(‘next’).NextConfig} /
const nextConfig = {
// ここに設定を記述
};
module.exports = nextConfig;
“`
4.4 簡単なページの作成 (App Router使用)
create-next-app
で作成したプロジェクトには、すでにトップページ (app/page.js
) と基本的なレイアウト (app/layout.js
) が含まれています。
新しいページを作成してみましょう。例えば、「About」ページを作成したい場合、app
ディレクトリ内に about
という新しいディレクトリを作成し、その中に page.js
ファイルを作成します。
my-next-app/
├── app/
│ ├── about/ # 新しいディレクトリ
│ │ └── page.js # About ページコンポーネント
│ ├── layout.js
│ ├── page.js
│ └── globals.css
└── ...
app/about/page.js
ファイルを開き、以下のように記述します。
“`javascript
// app/about/page.js
import React from ‘react’;
export default function AboutPage() {
return (
About Us
This is the about page.
);
}
“`
これで、/about
というURLパスに対応するページが作成されました。特別なルーティング設定ファイルを作成する必要はありません。
4.5 ルーティング (ナビゲーション)
ページ間を移動するためには、リンクを使用します。Next.jsはクライアントサイドナビゲーションを最適化するために、<Link>
コンポーネントを提供しています。
<Link>
コンポーネント (next/link
)
標準のHTMLの <a>
タグを使用してもページ遷移は可能ですが、その場合はブラウザの完全なページリロードが発生します。<Link>
コンポーネントを使用すると、クライアントサイドでの遷移(JavaScriptによるSPAのような遷移)が行われるため、ページ間の移動が高速になります。
app/page.js
を編集して、Aboutページへのリンクを追加してみましょう。
“`javascript
// app/page.js
import Link from ‘next/link’; // next/link から Link コンポーネントをインポート
export default function Page() {
return (
Hello, Next.js with App Router!
Welcome to the homepage.
{/ href プロパティに遷移先のパスを指定 /}
Aboutページへ
);
}
“`
同様に、app/about/page.js
にトップページへのリンクを追加します。
“`javascript
// app/about/page.js
import Link from ‘next/link’; // next/link から Link コンポーネントをインポート
import React from ‘react’;
export default function AboutPage() {
return (
About Us
This is the about page.
{/ トップページへのリンク /}
トップページへ戻る
);
}
“`
<Link>
コンポーネントは、内部で <a>
タグをレンダリングします。テキストや他の要素を <Link>
でラップすることで、その要素がリンクになります。
4.6 データの取得 (Data Fetching)
Webアプリケーションでは、外部データ(APIやデータベースなど)を取得して表示することが不可欠です。Next.jsのApp Routerでは、Server Componentsを活用した新しいデータ取得方法が推奨されています。
App Routerでのデータ取得
App Routerでは、デフォルトでServer Componentsが使用されます。Server Components内では、非同期処理(async/await
)を使って直接データを取得できます。ブラウザにJavaScriptを送信する前にサーバー側でデータ取得とレンダリングが完了するため、高速な初期表示とSEOに有利です。
例として、外部APIからデータを取得して表示するページを作成してみましょう。app/posts/[id]/page.js
のような動的ルーティングのページで、投稿の詳細データを取得して表示することを考えます。
まず、投稿一覧ページ app/posts/page.js
を作成します。
“`javascript
// app/posts/page.js
import Link from ‘next/link’;
// Server Component としてデータ取得は async function で記述
async function getPosts() {
const res = await fetch(‘https://jsonplaceholder.typicode.com/posts’); // 外部APIから投稿一覧を取得
if (!res.ok) {
throw new Error(‘Failed to fetch posts’);
}
// データをJSONとしてパース
return res.json();
}
export default async function PostsPage() {
const posts = await getPosts(); // データ取得を待つ (await)
return (
Posts
-
{posts.map(post => (
-
/posts/${post.id}}>
{post.title}
))}
);
}
“`
次に、投稿詳細ページ app/posts/[id]/page.js
を作成します。動的なIDを取得するには、コンポーネントのプロパティとして params
を受け取ります。
“`javascript
// app/posts/[id]/page.js
import React from ‘react’;
async function getPost(id) {
// fetch API の第2引数でキャッシュ戦略を指定
// デフォルトは cache: ‘force-cache’ (SSG相当)
// cache: ‘no-store’ で SSR 相当
// next: { revalidate: 60 } で ISR 相当
const res = await fetch(https://jsonplaceholder.typicode.com/posts/${id}
);
if (!res.ok) {
// notFound() 関数を呼び出すと not-found.js ページが表示される
// import { notFound } from ‘next/navigation’;
// notFound();
throw new Error(‘Failed to fetch post’);
}
return res.json();
}
// generateStaticParams を使用すると、ビルド時に動的なパスのページを事前に生成できる (SSG)
// この関数がない場合、リクエスト時にデータを取得してSSRされる (デフォルトのフェッチキャッシュ設定による)
/*
export async function generateStaticParams() {
const res = await fetch(‘https://jsonplaceholder.typicode.com/posts’);
const posts = await res.json();
// パスパラメータとして使用するオブジェクトの配列を返す
return posts.map((post) => ({
id: post.id.toString(), // パラメータは文字列である必要がある
}));
}
*/
// params プロパティで動的なルートセグメントの値を取得
export default async function PostDetail({ params }) {
const post = await getPost(params.id); // URLから取得したIDを使ってデータ取得
return (
{post.title}
{post.body}
{/ 他の詳細情報 /}
);
}
“`
この例では、app/posts/page.js
では fetch
のデフォルトキャッシュ (force-cache
相当) を利用することで、ビルド時に投稿一覧データを取得し、SSGのように高速なページを生成します。
app/posts/[id]/page.js
では、コメントアウトしていますが generateStaticParams
関数を定義することで、ビルド時に全ての投稿詳細ページを静的に生成(SSG)できます。generateStaticParams
をコメントアウトしたままの場合、デフォルトの fetch
キャッシュ戦略に従ってデータが取得されますが、リクエストごとのデータ取得(SSR相当)やISR (revalidate
) も fetch
のオプションで制御可能です。
App Routerでのデータ取得のポイント:
- Server Components (
async
関数として定義できるコンポーネント) 内でfetch
APIを直接使用できます。 fetch
のオプション (cache
,next: { revalidate, tags }
) によって、キャッシュ戦略(SSG, SSR, ISR相当)を細かく制御できます。- クライアントコンポーネント (
'use client'
ディレクティブを付けたコンポーネント) 内では、ブラウザのfetch
や SWR, React Query といったライブラリを使用してクライアントサイドでデータ取得を行います。
Pages Routerでのデータ取得 (getStaticProps
, getServerSideProps
)
App Routerが推奨されるようになりましたが、既存のプロジェクトや一部のチュートリアルではPages Routerがまだ使われています。Pages Routerでは、ページコンポーネントファイル内で以下の特殊な非同期関数をエクスポートすることで、ビルド時やリクエスト時にデータを取得できます。
getStaticProps
: SSG(静的サイト生成)のためにビルド時にデータを取得します。取得したデータはページコンポーネントのpropsとして渡されます。revalidate
オプションでISRも設定できます。getStaticPaths
: ダイナミックルーティング ([id].js
など) でSSGを行う際に、ビルド時に生成するパス(どのIDのページを生成するかなど)を定義します。getServerSideProps
: SSR(サーバーサイドレンダリング)のために、リクエストがあるたびにサーバー側でデータを取得します。取得したデータはページコンポーネントのpropsとして渡されます。
App Routerのデータ取得は、これらのPages Routerのデータ取得メソッドの概念をより柔軟に、コンポーネントレベルで、そして標準の fetch
APIの拡張として実現したものと考えることができます。新規プロジェクトではApp Routerのデータ取得方法を学ぶことを推奨します。
4.7 API Route の作成例
簡単なAPI Routeを作成してみましょう。/api/hello
というパスでJSONレスポンスを返すAPIエンドポイントを作成します。
app/api
ディレクトリ内に hello
というディレクトリを作成し、その中に route.js
ファイルを作成します。
my-next-app/
├── app/
│ ├── api/
│ │ └── hello/
│ │ └── route.js # API Route ファイル
│ ├── layout.js
│ ├── page.js
│ └── ...
└── ...
app/api/hello/route.js
ファイルを開き、以下のように記述します。
“`javascript
// app/api/hello/route.js
import { NextResponse } from ‘next/server’;
// GET リクエストに対応する関数をエクスポート
export async function GET(request) {
// NextResponse.json を使って JSON レスポンスを返す
return NextResponse.json({ message: ‘Hello from Next.js API Route!’ });
}
// 必要に応じて他の HTTP メソッドにも対応する関数を定義できる
// export async function POST(request) { … }
// export async function PUT(request) { … }
// export async function DELETE(request) { … }
“`
開発サーバーを起動した後(後述)、ブラウザやAPIクライアントから http://localhost:3000/api/hello
にアクセスすると、{"message": "Hello from Next.js API Route!"}
というJSONレスポンスが返ってくるはずです。
このAPI Routeは、同じNext.jsプロジェクトのフロントエンドから fetch('/api/hello')
のように呼び出すことも、他の外部クライアントから呼び出すことも可能です。
4.8 スタイリング
前述の通り、Next.jsは様々なスタイリング方法をサポートしています。ここでは、Global CSS、CSS Modules、Tailwind CSSの基本的な使い方を見てみましょう。
Global CSS
app/globals.css
ファイルに記述します。このファイルは、app/layout.js
の中でインポートすることで、アプリケーション全体に適用されます。
“`css
/ app/globals.css /
body {
font-family: sans-serif;
line-height: 1.5;
margin: 0;
padding: 0;
}
h1 {
color: #333;
}
“`
“`javascript
// app/layout.js
import ‘./globals.css’; // global.css をインポート
export default function RootLayout({ children }) {
return (
);
}
“`
CSS Modules
特定のコンポーネントにのみ適用されるローカルなスタイルを記述する場合に便利です。.module.css
という拡張子でCSSファイルを作成します。
例として、ボタンコンポーネント用のスタイルを作成します。app/components/Button.module.css
のように作成します(components
ディレクトリは任意で作成)。
“`css
/ app/components/Button.module.css /
.button {
background-color: #0070f3;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.button:hover {
background-color: #005cbf;
}
“`
このスタイルをコンポーネント内で使用するには、CSSファイルをインポートし、クラス名をオブジェクトのプロパティとして参照します。
“`javascript
// app/components/Button.js (または .tsx)
import React from ‘react’;
import styles from ‘./Button.module.css’; // CSS Module をインポート
export default function Button({ children, onClick }) {
return (
);
}
“`
className={styles.button}
のようにすることで、Next.jsはビルド時にユニークなクラス名(例: Button_button__xyz123
)を生成し、スタイル衝突を防ぎます。
Tailwind CSS
create-next-app
でTailwind CSSを含める選択をした場合、既に設定は完了しています。あとはクラス名をHTML要素に直接記述するだけで利用できます。
javascript
// app/page.js (Tailwind CSS を有効にしている場合)
export default function Page() {
return (
<div className="container mx-auto p-4"> {/* Tailwind のクラス名 */}
<h1 className="text-4xl font-bold text-blue-600">
Hello, Tailwind CSS with Next.js!
</h1>
<p className="mt-4 text-gray-700">
This page is styled using Tailwind CSS utility classes.
</p>
<button className="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded mt-4">
Click me
</button>
</div>
);
}
Tailwind CSSを使用しない場合でも、CSS ModulesやCSS-in-JSライブラリなど、他のモダンなスタイリング手法を自由に選択できます。
4.9 画像の表示 (next/image
)
画像の表示には、パフォーマンス最適化のために next/image
コンポーネントを使用することを推奨します。
next/image
は next/image
からインポートして使用します。ローカルの画像ファイルとリモートの画像URLの両方に対応しています。
ローカル画像の表示
プロジェクト内の public
ディレクトリに配置した画像を最適化して表示する場合。
“`javascript
// app/page.js
import Image from ‘next/image’; // Image コンポーネントをインポート
import profilePic from ‘../public/profile.jpg’; // 画像ファイルをインポート (public ディレクトリからの相対パスまたはエイリアス)
export default function Page() {
return (
My Profile
Welcome to my profile page.
);
}
“`
ローカル画像の場合、画像のインポート時に画像のメタデータ(幅、高さなど)が自動的に取得されるため、width
と height
プロパティは必須であり、オリジナルの画像のサイズを正確に指定する必要があります。
リモート画像の表示
外部URLの画像を最適化して表示する場合。この場合、セキュリティ上の理由から、最適化を許可するドメインを next.config.js
に設定する必要があります。
next.config.js
を編集して、許可する画像ドメインを追加します。
“`javascript
// next.config.js
/ @type {import(‘next’).NextConfig} */
const nextConfig = {
images: {
domains: [‘via.placeholder.com’], // 例: 許可するドメインを配列で指定
// または remotePatterns を使用する (より柔軟な設定が可能)
// remotePatterns: [
// {
// protocol: ‘https’,
// hostname: ‘via.placeholder.com’,
// port: ”,
// pathname: ‘/‘,
// },
// ],
},
};
module.exports = nextConfig;
“`
ページコンポーネントでリモート画像を表示します。
“`javascript
// app/page.js
import Image from ‘next/image’;
export default function Page() {
return (
Remote Image Example
);
}
“`
next/image
は、指定された幅と高さに基づいて適切なサイズの画像を生成し、ブラウザのビューポートサイズに応じて最適な画像を遅延ロードするため、パフォーマンスが大幅に向上します。
4.10 開発サーバーの起動
プロジェクトの作成と基本的なファイルの編集が完了したら、開発サーバーを起動してブラウザで確認してみましょう。プロジェクトのルートディレクトリで以下のコマンドを実行します。
“`bash
npm run dev
または yarn dev
または pnpm dev
“`
開発サーバーが起動し、通常は http://localhost:3000
でアプリケーションにアクセスできるようになります。
開発サーバーはFast Refreshに対応しており、コードを変更して保存すると、ブラウザの表示が自動的に更新されます。エラーが発生した場合は、ターミナルまたはブラウザのエラーオーバーレイに表示されます。
4.11 本番ビルドと実行
アプリケーションを本番環境にデプロイする準備ができたら、まずビルドを行います。
“`bash
npm run build
または yarn build
または pnpm build
“`
このコマンドは、アプリケーションを本番向けに最適化し、SSGによる静的ファイルの生成、コードのトランスパイルと圧縮、不要なコードの削除などを行います。ビルドが完了すると、.next
ディレクトリに本番用のファイルが生成されます。
ビルドされたアプリケーションをローカルでテスト実行するには、以下のコマンドを使用します。
“`bash
npm start
または yarn start
または pnpm start
“`
これにより、ビルドされた .next
ディレクトリ内のファイルがサーバーとして実行されます。これは開発サーバー (npm run dev
) とは異なり、Fast Refreshなどの開発者向けの機能は無効化され、本番環境に近い状態での動作確認が可能です。
本番環境へのデプロイについては、後述の「デプロイについて」のセクションで触れます。
5. App Router vs Pages Router (詳細比較と推奨)
Next.js 13で導入されたApp Routerは、これまでのPages Routerからアーキテクチャが大きく変更されました。ここでは、両者の違いを詳細に比較し、なぜApp Routerが推奨されるのかを解説します。
5.1 Pages Router
- ルーティング:
pages/
ディレクトリ以下のファイル構造に基づきます。ファイル名がそのままパスになります。 - レンダリング: ページ単位でレンダリング戦略(SSR:
getServerSideProps
, SSG:getStaticProps
, CSR: データ取得関数なし)を選択します。 - データ取得: ページコンポーネント内で
getStaticProps
,getServerSideProps
,getInitialProps
といった特別な関数をエクスポートしてデータを取得します。 - コンポーネント: デフォルトではクライアントコンポーネントのように動作しますが、プリレンダリングのためにサーバー側でも実行されます。状態管理や副作用は
useEffect
,useState
など、クライアントサイドの機能に依存します。 - レイアウト: レイアウトを共有する場合、
_app.js
や_document.js
といったファイルをカスタマイズしたり、各ページで同じレイアウトコンポーネントを呼び出す必要がありました。ネストされたレイアウトの実現は複雑でした。 - API Routes:
pages/api/
ディレクトリ以下にファイルを作成します。
5.2 App Router
- ルーティング:
app/
ディレクトリ以下のディレクトリ構造に基づきます。page.js
ファイルがそのディレクトリのパスに対応するUIとなります。 - レンダリング: デフォルトはServer Componentsによる静的なレンダリング(SSG相当)。
fetch
APIのキャッシュ設定やコンポーネントの種類(Server Component/Client Component)によって、SSRやISRに近い動作も実現します。 - データ取得: Server Components内で非同期処理 (
async/await
) と標準のfetch
APIを使ってデータを取得します。fetch
のオプションでキャッシュ戦略を制御します。クライアントコンポーネントでは、これまで通りクライアントサイドでデータ取得を行います。 - コンポーネント: デフォルトがServer Componentsです。Server Componentsはサーバーサイドでのみ実行され、インタラクティブな機能(クリックイベントハンドラ、状態管理など)は持てません。インタラクティブなUIが必要な部分は
'use client'
ディレクティブを使ってClient Componentsとして定義します。Server ComponentsとClient Componentsを組み合わせてアプリケーションを構築します。 - レイアウト:
layout.js
ファイルをディレクトリ構造の中に配置することで、ネストされたレイアウトを簡単に実現できます。親ディレクトリのレイアウトが子ディレクトリのレイアウトやページをラップする構造になります。 - API Routes:
app/api/
ディレクトリ以下にroute.js
ファイルを作成します。HTTPメソッドに対応する関数をエクスポートします。
5.3 App Routerが推奨される理由
Next.jsチームは、新規プロジェクトにおいてはApp Routerの使用を強く推奨しています。その主な理由は以下の通りです。
- Server Componentsによるパフォーマンス向上と開発体験の改善:
- パフォーマンス: データを取得する処理がサーバー側で行われるため、クライアントに送信されるJavaScriptの量が減り、初期表示速度が向上します。ハイドレーションが必要な部分も最小限になります。
- 簡潔なデータ取得: Server Components内では、特別な関数を使うことなく
async/await
でデータを直接取得できます。API Routesを呼び出す必要なく、データベースやファイルシステムから直接データを読み込むことも可能です(ただしセキュリティには注意が必要)。 - バンドルサイズの削減: Server Components自体はクライアントに送信されないため、クライアント側のJavaScriptバンドルサイズが小さくなります。
- セキュリティ: サーバー側でのみ実行されるため、APIキーなどの機密情報をServer Components内に直接記述しても安全です(ただし環境変数などを使うのがベストプラクティスです)。
- 柔軟で効率的なデータ取得とキャッシュ:
- 標準の
fetch
APIを拡張する形で、ビルド時(SSG相当)、リクエスト時(SSR相当)、およびISRのキャッシュ戦略を統一的に設定できます。 - 自動的なリクエストの重複排除など、パフォーマンス最適化が組み込まれています。
- 標準の
- より優れたルーティングとレイアウト:
- ファイルシステムベースのルーティングがApp Routerではより直感的になり、
page.js
がUIのエントリーポイントであることが明確です。 layout.js
を使ったネストされたレイアウトは、UIの共通部分の管理を非常に容易にします。ローディング (loading.js
)、エラー (error.js
)、Not Found (not-found.js
) といった特別なUIも、ルーティング構造の中で簡単に定義できます。
- ファイルシステムベースのルーティングがApp Routerではより直感的になり、
- Pages Routerとの共存と移行パス:
- App RouterとPages Routerは同じプロジェクト内で共存させることができます。これにより、既存のPages Routerプロジェクトの一部から徐々にApp Routerへ移行することが可能です。
App Routerは、Next.jsの今後の開発の方向性を示すものであり、Server Componentsという新しい概念はReactそのものの進化とも連動しています。学習コストはかかりますが、これらの新機能とメリットを享受するためにも、新規開発ではApp Routerを選択するのが賢明です。
6. デプロイについて
Next.jsで構築したアプリケーションをインターネット上に公開するには、デプロイが必要です。Next.jsアプリケーションは、そのレンダリング戦略(SSG, SSR, API Routes)に応じて、いくつかの方法でデプロイできます。
6.1 Vercel
Next.jsの開発元であるVercelは、Next.jsアプリケーションをデプロイするための最適なプラットフォームです。Gitリポジトリ(GitHub, GitLab, Bitbucket)と連携させることで、コードのプッシュをトリガーに自動的にビルド・デプロイが行われます。
- SSG: ビルド時に生成された静的ファイルは自動的にグローバルなCDNに配置され、高速に配信されます。
- SSR / API Routes: これらのサーバーサイドのコードは、自動的にサーバーレス関数としてデプロイされます。リクエストに応じて実行され、必要な時にだけ課金されるため、高いスケーラビリティとコスト効率を実現します。
- ISR: VercelはISRをネイティブにサポートしており、設定するだけで利用できます。
- Image Optimization:
next/image
の最適化機能もVercelプラットフォーム上で最大限に活かされます。
VercelはNext.jsの機能を最もシンプルかつ効率的にデプロイできるため、特別な理由がなければ最初のデプロイ先としてVercelを検討するのが良いでしょう。
6.2 Netlify
Netlifyも人気のあるJamstackホスティングプラットフォームであり、Next.jsアプリケーションのデプロイをサポートしています。
- SSG: ビルドされた静的ファイルをCDNから配信します。
- SSR / API Routes: Netlify Functionsというサーバーレス機能としてデプロイできます。ただし、VercelほどNext.jsのSSR/API Routesに密接に統合されているわけではないため、一部設定が必要な場合があります。
- ISR: プラグインなどを使用して実現可能な場合がありますが、Vercelほどのネイティブサポートではありません。
既存のインフラがNetlifyである場合や、Netlifyの他の機能(Forms, Identityなど)を利用したい場合に選択肢となります。
6.3 その他のプラットフォーム
Dockerコンテナ化してECS (AWS Elastic Container Service) やKubernetesにデプロイしたり、EC2 (AWS Elastic Compute Cloud) やVPSのような仮想マシン上にNode.jsサーバーとして実行したりすることも可能です。
npm run build
で生成される .next
ディレクトリには、本番実行に必要なコードが含まれています。npm start
コマンドでこのコードを実行するNode.jsサーバーを起動できます。
- AWS Amplify: フルスタックアプリケーションの構築・デプロイをサポートするサービスです。Next.jsのSSG/SSR両方に対応しています。
- Azure Static Web Apps: 静的サイトとサーバーレスAPIを組み合わせたデプロイに適しています。Next.jsのSSG部分と、Azure FunctionsとしてデプロイされるAPI Routes部分に対応します。
- Heroku, Renderなど: Node.jsアプリケーションとしてSSR/API Routesを含むNext.jsアプリケーションをデプロイできます。
これらの方法では、VercelのようにNext.jsの全ての機能(特にISRやImage Optimization)がネイティブにサポートされているわけではない場合があります。環境構築や設定の手間もVercelに比べて増える傾向があります。
初めてNext.jsアプリケーションをデプロイする場合や、Next.jsの機能を最大限に活用したい場合は、Vercelが最も手軽で強力な選択肢と言えるでしょう。
7. Next.jsを学ぶためのリソース
Next.jsの学習を進めるにあたり、役立つ公式および非公式のリソースを紹介します。
7.1 公式ドキュメント
Next.jsの公式ドキュメント (https://nextjs.org/docs) は、最も正確で網羅的な情報源です。最新のApp Routerに関する詳細な説明、APIリファレンス、様々な機能のガイドなどが含まれています。
- Docs: 各機能(ルーティング、データ取得、スタイリングなど)に関する詳細なガイド。困ったときはまずここを見ましょう。
- API Reference: Next.jsが提供するAPIやコンポーネント(
next/link
,next/image
など)の使い方に関する詳細な情報。 - Migrating: Pages RouterからApp Routerへの移行に関するガイドも提供されています。
公式ドキュメントは英語が基本ですが、ブラウザの翻訳機能などを活用しながら読むことをお勧めします。
7.2 公式Learnチュートリアル
Next.js公式サイトには、インタラクティブなチュートリアル (https://nextjs.org/learn) が用意されています。ゼロからNext.jsアプリケーションを構築しながら、App Routerの基本的な概念やデータ取得、スタイリングなどを学ぶことができます。手を動かしながら学びたい方にとって、非常に優れたリソースです。
7.3 コミュニティ
開発中に疑問点や問題に直面した場合、コミュニティの助けを借りることができます。
- GitHub: Next.jsの公式リポジトリ (https://github.com/vercel/next.js/) で、Issueの検索や新しいIssueの作成、Pull Requestの確認などができます。
- Stack Overflow:
next.js
タグが付いた質問を検索したり、自分で質問したりできます。多くの開発者が利用しており、様々な質問に対する回答が見つかります。 - Discord: Next.jsの公式Discordサーバーに参加すると、他のユーザーやNext.jsチームのメンバーとリアルタイムで交流し、質問や議論ができます。
7.4 ブログ記事、動画チュートリアル、オンラインコース
公式リソース以外にも、多くの開発者や企業がNext.jsに関するブログ記事や動画チュートリアルを公開しています。特定の機能の使い方や、実際のアプリケーション構築例などを学ぶのに役立ちます。UdemyやCourseraなどのオンライン学習プラットフォームでも、Next.jsに関するコースが提供されています。
ただし、Next.jsは活発に開発が進んでおり、特にApp Routerに関する情報は比較的新しいものが望ましいです。情報が公開された日付を確認し、最新のバージョンに基づいた内容であるかを確認することをお勧めします。
8. まとめ
Next.jsは、Reactを使ったWebアプリケーション開発において、高いパフォーマンス、優れた開発体験、そして柔軟な機能を開発者に提供する強力なフレームワークです。
本記事では、Next.jsの主要な特徴であるサーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、Incremental Static Regeneration(ISR)、ファイルシステムベースのルーティング、API Routes、Fast Refresh、コード分割、Image Optimizationなどを詳細に解説しました。これらの機能を活用することで、静的なブログから動的な大規模アプリケーション、Eコマースサイト、APIサーバーなど、幅広い種類のプロジェクトを効率的に開発できることを示しました。
また、Next.js 13以降の新しいルーティングシステムであるApp Routerを中心に、プロジェクトの作成方法、基本的なファイル構成、ルーティング、データ取得、API Routeの作成、スタイリング、画像の表示といった開発を始めるための具体的なステップを解説しました。App RouterはServer Componentsという新しい概念を導入し、パフォーマンスと開発効率の向上に大きく貢献しています。Pages Routerとの違いを理解し、App Routerを積極的に利用することを推奨しました。
最後に、Vercelをはじめとするデプロイ方法や、Next.jsをさらに深く学ぶための公式・非公式のリソースを紹介しました。
Next.jsは現在も進化を続けており、常に新しい機能や改善が取り込まれています。しかし、本記事で解説した基本的なコンセプトと始め方を理解すれば、Next.jsの世界にスムーズに入っていくことができるはずです。
Web開発の可能性を広げ、より高品質なアプリケーションを構築するために、ぜひNext.jsの学習に挑戦してみてください。この記事が、あなたのNext.jsの旅の強力な一歩となることを願っています。