こんにちは、新卒エンジニアの鈴木です。
Reactを一通り触って開発に慣れてくると、だいたい次に出てくるのがNext.jsです。
ただ、最初に公式ドキュメントや技術記事を読むと、
- App Router
- Server Components / Client Components
- SSG / ISR / SSR
といった聞き慣れない用語が次々と出てきて、英弱な僕はそっとブラウザを閉じた記憶があります。
この記事では、Reactをある程度触ったことがある人向けに、Next.jsの何が良いか、Reactとどう違うのかを初心者目線で整理していきます。
目次
Next.jsって何者?
Next.jsは、Vercel社が中心となって開発しているReactフレームワークです。
Reactが「UIを作るためのライブラリ」なのに対して、Next.jsは「Webアプリを作るためのフレームワーク」と言えます。
React単体でもアプリは作れますが、実務では次のような要素を自分で選び、組み合わせる必要があります。
- ルーティングの仕組み
- ページ共通レイアウト
- SEOを意識した画面表示
- データ取得の設計
Next.jsは、これらを統一された設計思想で、最初からまとめて提供してくれるのが大きな特徴です。「Reactで何をどう組み合わせればいいか」と考える負担を、かなり減らしてくれます。
App Routerの仕組み
App Routerは、Next.jsにおける「画面構成とデータ取得の設計をまとめて管理する仕組み」です。
ルーティング・レイアウト・レンダリング方式・Server / Client Componentsの使い分けを、ディレクトリ構造をベースに一体として扱えるのが特徴です。
具体的には、次のような要素をまとめて設計します。
- Server Components / Client Components の使い分け
- レイアウト構造
- レンダリング戦略(SSG / SSR など)
では、App Routerを構成する具体的な機能について、一つずつ見ていきましょう。
ファイルベースルーティング
Next.jsの代表的な機能のひとつが、ファイルベースルーティングです。
App Routerでは、page.tsxが存在するディレクトリだけが「ルーティングに含まれる」というルールになっています。
app/ └ users/ └ page.tsx
このようにpage.tsxを配置すると、そのディレクトリがページとして扱われ、/usersというURLが自動的に作られます。
逆に言えば、page.tsxが存在しないディレクトリは、ルーティングには含まれません。このルールのおかげで、「どこが画面なのか」がディレクトリ構成を見るだけで分かるようになっています。
Reactでルーティングを行う場合、React Routerを使って次のように定義するのが一般的でした。
<Route path="/users" element={<Users />} />
ただ、この書き方は面倒であり、何よりページが増えれば増えるほど読みづらいです。Next.jsであれば「ファイルを置く=ページを作る」という感覚で画面を増やしていけます。しかもライブラリも一切不要。直感的で分かりやすいですね。
React Routerによる方法は柔軟ではありますが、ページが増えるにつれて設定が煩雑になり、URLとコンポーネントの対応関係を追うのが大変になりがちです。
では、URLの一部を可変にしたい場合はどうなるのでしょうか。
app/
└ users/
└ [id]/
└ page.tsx
ディレクトリ名を[]で囲むことで、/users/1や/users/abcのような動的なURLを表現できます。
ではファイル構成上は整理したいけれど、ルーティングに含めたくない場合はどのようにしたらよいのでしょうか。
そのために用意されているのが、()です。
app/
└ (auth)/
└ login/
└ page.tsx
()で囲んだディレクトリは、URLには含まれません。この例では、URLは/loginになります。
また、_で始まるディレクトリも、ルーティングの対象外になります。
app/
└ users/
└ _components/
└ UserCard.tsx
└ page.tsx
このように、ページ専用のコンポーネントや補助的なファイルを「ルーティングに影響させずに同じ階層に置ける」のが特徴です。
Server Components / Client Components
Next.jsを勉強するうえで一番最初の壁になるであろう、Server Components / Client Components。しっかり押さえましょう。
実行される場所の違い
一番大きな違いは、実行される場所です。Server Componentsはサーバーで実行され、Client Componentsはブラウザで実行されます。
この違いによって、書けることやできること、パフォーマンスが大きく変わります。
Server Componentsに任せるべき処理
Server Componentsはサーバー上で実行され、画面を描画する前にデータを取得した状態でHTMLを生成することができます。
空のHTMLを送りJavaScriptでレンダリングするReactとは違い、あらかじめサーバー上で実行され、描画を始める前にデータを取得するため、初期表示が速くなると同時に、ブラウザに送るJavaScriptを最小限に抑えられます。
単に表示するだけのページであれば、Server Componentsに任せることで、無駄のない構成になります。
逆に言えば、ユーザー操作に応じて状態が変わるUIには向いていません。クリックイベントや useState、useEffectなどのフックは使えず、入力フォームやモーダル、動的に切り替わる表示などは扱えません。
そのため、「データを取得して表示するだけ」の部分はServer Components、「ユーザー操作が必要な部分」だけをClient Componentsに切り出す、という役割分担が重要になります。
Client Componentsが必要になる場面
一方、Client Componentsはブラウザ上で実行されるコンポーネントです。
ボタンのクリックやフォーム入力などの処理はブラウザで発生するため、こうしたインタラクションを伴うUIはClient Componentsが担当します。useStateやuseEffectが使えるのも、ブラウザ上で実行されているからです。
ただし、Client ComponentsはJavaScriptをブラウザに送る必要があるため、使いすぎると初期表示やパフォーマンスに影響します。
そのため、必要な部分だけをClient Componentsにするという意識が重要になります。
使い分けの考え方
| Server Components | Client Components | |
|---|---|---|
| 主な役割 | データ取得・表示 | ユーザー操作・状態管理 |
| 実行される場所 | サーバー | ブラウザ(ユーザー端末) |
| 描画前のデータ取得 | 〇 | × |
fetchによるデータ取得 |
〇(描画前に取得可能) | △(useEffectなどが必要) |
useState/useEffect |
× | 〇 |
イベント処理(onClickなど) |
× | 〇 |
ブラウザ API(window/document) |
× | 〇 |
| 送信されるJavaScript量 | 少ない | 多くなりがち |
レンダリング方式の違い(CSR / SSR / SSG / ISR)
Reactでは、画面は基本的に「ブラウザで描画されるもの(CSR)」でした。一方Next.jsでは、ページが「いつ」「どこで」描画されるかを選べるようになります。
どの方式を選ぶかによって初期表示の速さや、サーバー負荷のかかり方が変わります。名前が多くて一瞬ひるみますが、用途ごとに最適な方式を選ぶためにも違いを理解しておきましょう。
それぞれの特徴を整理すると、次のようになります。
| 方式 | 生成のタイミング | 特徴 | 向いている用途 |
|---|---|---|---|
| CSR | ブラウザ表示後(JavaScript 実行時) | 柔軟だが初期表示が遅い | SPA 的な操作画面 |
| SSR | リクエストごと | 常に最新だがサーバー負荷あり | 管理画面・ユーザー別画面 |
| SSG | ビルド時 | 高速だが更新頻度に弱い | ブログ・固定ページ |
| ISR | ビルド後+一定時間ごとに再生成 | 速度と更新頻度のバランスが良い | ニュース・一覧画面 |
Next.jsの強みは、これらを用途ごとに選択できる点にあります。
どれが一番優れているという話ではなく、向いている用途に合わせて使い分けることが大切です。
layout.tsxについて
Reactで開発していた頃は、レイアウトの共通化は少し面倒な作業でした。
ページごとにヘッダーやフッターを配置したり、共通レイアウト用のコンポーネントを作ってラップしたり、レンダリングのタイミングを考えたり……
layout.tsxは、気づくとApp.tsxがごちゃごちゃになっている現象を解消するための仕組みで、そのディレクトリ配下のページすべてに適用される共通レイアウトを定義するファイルです。
app/
├ layout.tsx
├ page.tsx
└ users/
└ page.tsx
この構成の場合、
app/layout.tsxは全ページ共通のレイアウトapp/page.tsxとapp/users/page.tsxは、その内側に描画される
という関係になります。
layout.tsxのなかでは、ヘッダー・フッター・ナビゲーションなど、どのページでも共通で表示したいUIを定義します。
重要なのは、layout.tsxがただの見た目用ファイルではない、という点です。このファイルは一度だけ読み込まれ、ページ遷移時にも再レンダリングされません。
そのため、
- ページ遷移のたびにヘッダーが作り直されない
- 状態を持ったレイアウトを安全に維持できる
といったメリットがあります。
これはReactでありがちな「ページ遷移のたびにレイアウトが再マウントされる問題」を根本的に解決しています。
さらに、layout.tsxはネストできます。
app/
├ layout.tsx // 全体レイアウト
└ users/
├ layout.tsx // users配下専用レイアウト
└ page.tsx
このように書くことで、全体共通のレイアウトと特定セクション専用のレイアウトを自然に分けて管理できます。
Reactでよくあった「どこでレイアウトを分けるべきか悩む問題」も、ディレクトリ構造そのままで表現できるのが特徴です。
ページ遷移まわりも、Next.jsでは専用の仕組みが用意されています。
Reactでは、ページ遷移といえばReact Routerを使うのが一般的でしたが、Next.jsではルーティングだけでなく、画面遷移まで含めてフレームワーク側で設計されています。
Linkコンポーネント
Next.jsでページ遷移用のリンクを作るときは、Linkコンポーネントを使います。
import Link from 'next/link' <Link href="/users">Users</Link>
一見すると普通のハイパーリンクに見えますが、LinkにはNext.jsならではの役割があります。
Linkを使うことで、ページ全体を再読み込みせずに遷移できます。これはReact SPAと同じように、画面が一瞬白くなることなく遷移できる、ということです。
さらに、Linkは遷移先のページを事前に読み込む「プリフェッチ」という仕組みを持っています。ユーザーがリンクをクリックする前から、次のページに必要な情報を裏で取得しておくため、実際の遷移が非常にスムーズになります。
ただのリンクに見えて、ユーザー体験(UX)の最適化まで含まれているのが、Linkの特徴です。
navigation API(useRouter)
ボタン押下や処理完了後など、「コードから画面遷移したい」場面もあります。
そのときに使うのが、next/navigationのuseRouterです。
'use client' // ← これが必須!
import { useRouter } from 'next/navigation' //next/routerはエラーになるので注意
export default function LoginButton() {
const router = useRouter()
const handleLogin = () => {
router.push('/users')
}
return <button onClick={handleLogin}>Login</button>
}
router.pushは、指定したURLに画面遷移します。フォーム送信後や、保存完了後に一覧画面へ戻すようなケースで使われます。
もう一つよく使うのがrouter.replaceです。
router.replace('/login')
pushとreplaceの違いは、「履歴に残るかどうか」です。
pushは履歴に追加されるため、ブラウザの戻るボタンで元のページに戻れます。replaceは履歴を置き換えるため、戻るボタンでは戻れません。
ログイン後やリダイレクトなど、「戻らせたくない遷移」ではreplaceを使うとよいでしょう。
React Routerとの違い
React Routerは設定や管理が複雑になりがちです。
一方、Next.jsのnavigationは、
- ルーティング設定が不要
- APIが最小限で覚えやすい
という特徴があります。
SEOについて(Next.jsはなぜSEOに強いと言われるのか)
Next.jsを調べると、「Next.jsはSEOに強い」という説明をよく見かけます。
ただしこれは半分正しくて、半分は誤解されやすい表現です。
Next.jsを使えば自動的にSEOが良くなるわけではありません。正確には、SEOに必要なことを正しく実装しやすい設計になっている、というのが実態です。
SEOを考えるうえで重要なのは、検索エンジンがページの内容を正しく取得・理解できること、そしてユーザーが快適に閲覧でき、すぐに離脱しないことです。
Next.jsでは、Server ComponentsやSSG / ISR / SSRを活用することで、最初から中身のあるHTMLを返しやすくなります。その結果、検索エンジンがページ内容を把握しやすくなり、初期表示速度も改善されやすくなります。
また、App RouterではServer Componentsを基本とし、本当にユーザー操作が必要な部分だけをClient Componentsに切り出す設計を取りやすくなっています。これにより、無駄なJavaScriptを減らしつつ、ページごとにSSG / ISR / SSRを適切に選択できます。
さらに、titleやdescriptionの設定、見出し構造(h1〜h3)の整理、不要な再レンダリングを避けるといった、本来SEOで意識すべきポイントも自然と実装しやすくなります。
つまりNext.jsが「SEOに強い」と言われる理由は、魔法のように順位を上げてくれるからではなく、SEOに必要な設計を正攻法で積み上げやすいフレームワークだからです。
まとめ
今回は、Next.jsについてReactとの違いや、App Routerを軸とした基本的な考え方を整理しました。
Reactを触っていた身としては便利な機能が豊富な分、理解しなければならないこともあり大変ですが、基礎的な用語は押さえられたかと思います。実際にレンダリングやServer / Clientの役割分担を意識するとNext.jsの良さがより実感できるので、皆さんも試してみてください。
最後までご覧いただき、ありがとうございました。