😽

【Next.js 16入門⑤】プロジェクト作成とディレクトリ構造(最後にクイズ付き!)

に公開

メタディスクリプション

本記事は、Next.js 16 入門シリーズ第 5 回です。
Next.js 16 公式ドキュメントに基づき、create-next-app を使った プロジェクト作成手順 と、App Router における標準的なディレクトリ構造 を解説します。pnpm を推奨パッケージマネージャとして採用し、layout.tsx, page.tsx に加えて loading.tsx, not-found.tsx, error.tsx などの重要ファイルについてもコード例付きで整理します(最後にクイズ付き)。


はじめに

「Next.js を始めたいけれど、どのファイルを触ればいいのか分からない」
app/ フォルダの中にいろいろなファイルがあって混乱する」

そんな状態から一歩抜け出すのが、この第 5 回のゴールです。

本記事では、次の 2 点に絞って解説します。

  • Next.js 16 プロジェクトを自分の PC 上に作成・起動できるようになる
  • App Router の「ディレクトリ構造」と「特殊ファイル」の役割を理解する

特に、Next.js 16(v16.0.3 以降)からは開発・ビルドツールである Turbopack がデフォルト となり、より高速な開発体験が標準で提供されるようになりました。そのあたりの最新事情も含めて解説します。


Next.js 16 プロジェクトを作成する

1. 前提環境を確認しよう

Next.js 16 プロジェクトを作成する前に、最低限以下の環境を用意しておきましょう。

  • Node.js
    • バージョン 20.9 以上
      Next.js 16 の公式ドキュメントでは、Node.js 20.9 以上が必要とされています。
    • node -v コマンドで確認できます。
  • パッケージマネージャ
    • 本記事では pnpm / npm / yarn の 3 つを例に説明します。
    • どれでも動きますが、モダンなフロントエンド開発では pnpm を特におすすめ します。
      • 理由(かんたんに):
        • 依存パッケージを効率的に管理するため、インストールが速く、ディスク容量も節約 できます。
        • 「幽霊依存(Phantom Dependencies)」を防ぐ仕組みがあり、大規模開発でもトラブルが起きにくいです。
      • pnpm / npm / yarn などのパッケージマネージャの詳しい比較や使い分けについても、もし興味があればぜひ「いいね」やコメントで教えてください!リクエストが多ければ、特集記事を組みたいと思います。
  • エディタ
    • VS Code など、お好みの IDE で OK
    • TypeScript / ESLint / Prettier などの拡張機能を入れておくと快適です。

2. create-next-app で新規プロジェクトを作る

Next.js 公式は、create-next-app を使ったプロジェクト作成を推奨しています。

2-1. コマンドの実行(pnpm / npm / yarn の例)

ターミナルで以下のコマンドを実行します。

  • pnpm を使う場合(おすすめ)
pnpm create next-app@latest
  • npm を使う場合
npx create-next-app@latest
  • yarn を使う場合
yarn create next-app@latest

2-2. 対話的な質問とおすすめ設定

コマンドを実行すると、いくつか質問されます。Next.js 16 の推奨設定(入門者向け)は以下の通りです。

質問内容(英語例) おすすめ回答 理由
TypeScript? Yes 型の恩恵を受けるため、基本は Yes。
ESLint? Yes コード品質チェックのため必須。
Tailwind CSS? Yes 多くのチュートリアルやモダンな開発で標準的に使われています。
src/ directory? No / Yes どちらでも OK ですが、今回は公式の最小例に合わせて No でも可。
App Router? Yes Next.js 16 の標準ルーターです。必ず Yes にしましょう。
Import alias? Yes @/components/... のようにパスを書けるようになります。

💡 Turbopack について
v16.0.3 以降、Next.js プロジェクトでは Turbopack が標準(デフォルト) として組み込まれました。

Turbopack とは?
Vercel(Next.js の開発元)が開発した、Rust 製の次世代バンドルツールです。「Webpack の後継」として設計されており、圧倒的な高速性が特徴です。

特徴 Webpack (従来) Turbopack (Next.js 16~)
言語 JavaScript Rust (高速・並列処理が得意)
開発サーバー起動 プロジェクト規模に比例して遅くなる 超高速 (規模が大きくても爆速)
HMR (保存時の更新) ファイル数が増えると遅くなる 常に数ミリ秒 (定数時間)

以前はインストール時に「Turbopack を使いますか?」と聞かれていましたが、現在はデフォルトで有効化されているため、質問されなくなりました。
※ Webpack / Vite / Turbopack など、フロントエンドのビルドツールの詳しい比較・解説記事に興味がある方は、ぜひ「いいね」やコメントで教えてください!反響が大きければ、別記事として執筆する予定です。


3. 開発サーバーを起動してみる

プロジェクトが作成されたら、ディレクトリに移動して起動してみましょう。

  • pnpm の場合
cd my-app
pnpm dev
  • npm の場合
cd my-app
npm run dev
  • yarn の場合
cd my-app
yarn dev

ブラウザで http://localhost:3000 を開いて、Next.js のウェルカムページが表示されれば成功です!


Next.js 16 のディレクトリ構造と重要ファイル

ここからは、作成されたプロジェクトの中身を見ていきます。
Next.js 16(App Router)では、「ファイル名」に特別な意味がある のが大きな特徴です。

1. プロジェクトの全体像(最小構成)

create-next-app 直後のシンプルな構成は、だいたい以下のようになっています。

my-app/
  app/                 ← App Router のメインディレクトリ
    layout.tsx         ← 全ページ共通のレイアウト
    page.tsx           ← トップページ ("/") の中身
    globals.css        ← 全体共通のスタイル
  public/              ← 静的ファイル(画像など)
  next.config.ts       ← Next.js の設定ファイル
  package.json         ← 依存パッケージ管理
  tsconfig.json        ← TypeScript 設定
  ...

2. app/ ディレクトリと「Routing Files」

App Router では、フォルダがそのまま URL のパス(ルート)になり、その中に置く 「特定の名前のファイル」 が役割を持ちます。
これらは Routing Files と呼ばれます。

主要なファイルを以下の表にまとめました。これだけ覚えれば、まずは自由にページを作れます。

ファイル名 役割 拡張子
page ページ本体。そのルート(URL)で表示されるメインコンテンツ。 .tsx / .js
layout レイアウト。ヘッダーやフッターなど、複数のページで共有される外枠。 .tsx / .js
loading ローディング UI。データ取得中などに表示されるスケルトンやスピナー。 .tsx / .js
not-found 404 ページ。存在しないパスにアクセスしたときに表示される UI。 .tsx / .js
error エラー UI。予期せぬエラーが発生したときに表示される画面。 .tsx / .js
route API ルート。画面(UI)ではなく、JSON などを返す API エンドポイントを作る場合に使用。 .ts / .js

📚 公式ドキュメント参照
より詳細なファイル一覧は、Next.js 公式の Project Structure に網羅されています。

構成例:ブログ機能を作る場合

例えば、「記事一覧 (/blog)」と「記事詳細 (/blog/post-1)」を作りたい場合、ディレクトリ構造は次のようになります。

app/
  layout.tsx          ← アプリ全体の共通レイアウト(<html>タグなど)
  page.tsx            ← トップページ ("/")
  not-found.tsx       ← アプリ全体の 404 ページ

  blog/               ← "/blog" というパスに対応するフォルダ
    layout.tsx        ← ブログコーナー専用のレイアウト(任意)
    page.tsx          ← 記事一覧ページ ("/blog")
    loading.tsx       ← ブログ読み込み中のローディング表示
    error.tsx         ← ブログコーナーでエラーが出たときの表示
    [slug]/           ← 動的ルート("/blog/xxx")
      page.tsx        ← 記事詳細ページ

このように、フォルダで階層を作り、その中に役割ごとのファイルを置く のが App Router の基本ルールです。


3. 各ファイルの役割とコード例

layout.tsx(レイアウト)

  • ページの外側(ヘッダー、サイドバー、<body> タグなど)を定義します。
  • ページ遷移しても レイアウト部分は再レンダリングされず、状態が維持 されます。
  • 最上位の app/layout.tsxRoot Layout と呼ばれ、必ず <html><body> タグを含む必要があります。
// app/layout.tsx の例
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>
        <header>共通ヘッダー</header>
        <main>{children}</main>
      </body>
    </html>
  );
}

page.tsx(ページ)

  • そのルート固有の UI(中身)を記述します。
  • layout.tsx{children} の部分に差し込まれて表示されます。
// app/page.tsx の例
export default function HomePage() {
  return <h1>ようこそ Next.js 16 の世界へ!</h1>;
}

loading.tsx(ローディング)

  • ページの内容をサーバーで準備している間、即座に表示される「待機画面」です。
  • React Suspense という仕組みを使って自動的に制御されます。
  • 同じフォルダの page.tsx や、下の階層のルートが読み込まれている間に表示されます。
// app/blog/loading.tsx の例
export default function Loading() {
  // スケルトンUIやスピナーを表示
  return <div className="loader">読み込み中...</div>;
}

not-found.tsx(404 ページ)

  • 該当するパスが存在しない場合や、プログラムから notFound() 関数を呼び出した場合に表示されます。
  • Root (app/not-found.tsx) に置くと、アプリ全体の 404 ページになります。
// app/not-found.tsx の例
import Link from 'next/link'

export default function NotFound() {
  return (
    <div>
      <h2>ページが見つかりません</h2>
      <p>お探しのページは削除されたか、URLが間違っている可能性があります。</p>
      <Link href="/">ホームに戻る</Link>
    </div>
  )
}

error.tsx(エラー)

  • そのルート配下で予期せぬエラーが発生したときに表示される UI です。
  • React Error Boundary として機能します。
  • 必ずクライアントコンポーネント('use client')である必要があります。
// app/error.tsx の例
'use client' // エラーコンポーネントは必ずクライアントコンポーネント

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // エラーログサービスに送信するなどの処理
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>予期せぬエラーが発生しました!</h2>
      <button onClick={() => reset()}>再試行する</button>
    </div>
  )
}

📝 コラム:なぜファイルを作るだけで機能するの?

ここで疑問に思った方もいるかもしれません。
SuspenseErrorBoundary というコンポーネントを書いていないのに、なぜ loading.tsxerror.tsx が動くの?」 と。

実は、Next.js がビルド(実行)するときに、裏側で自動的にコンポーネントをラップしてくれている のです。

イメージとしては、以下のように変換されています。

// 概念的なイメージ(実際に出力されるコードではありません)
<AppLayout>
  <ErrorBoundary fallback={<Error />}> {/* error.tsx の中身 */}
    <Suspense fallback={<Loading />}>   {/* loading.tsx の中身 */}
      <Page />                          {/* page.tsx の中身 */}
    </Suspense>
  </ErrorBoundary>
</AppLayout>

つまり、私たちがファイルを作って置いておくだけで、Next.js が「あ、loading.tsx があるから Suspense で囲っておこう」「error.tsx があるから ErrorBoundary で守っておこう」と気を利かせてくれるわけです。

これが App Router の「ファイルベースルーティング」の強力なマジックです。


4. すこし「実務」を意識したフォルダ構成

公式のファイル規約を守りつつ、コンポーネントやロジックを整理するために、以下のようなフォルダを追加するのが一般的です。

my-app/
  app/
    ... (Routing Files)
  
  components/         ← ボタンやカードなどの UI 部品
    ui/
    common/
  
  lib/                ← ユーティリティ関数や API クライアント
    utils.ts
  
  types/              ← TypeScript の型定義
  
  public/             ← 画像やフォントなどの静的ファイル

これらは Next.js のルールで決まっているわけではなく、一般的な React プロジェクトの慣習 としてよく使われます。
app/ フォルダの中にコンポーネントを置く「Colocation」というスタイルもありますが、初心者のうちは app(ルーティング)と components(部品)を分けたほうが分かりやすいでしょう。)


まとめ

本記事では、Next.js 16 入門シリーズ第 5 回として、以下の内容を解説しました。

  • Next.js 16 プロジェクトの作成
    • Node.js 20.9 以上が必要
    • pnpm 推奨(高速・容量節約)
    • Turbopack は v16.0.3 以降デフォルト で有効化されている
  • App Router のディレクトリ構造
    • フォルダ=URLパス、ファイル=役割
    • 重要ファイル:
      • page.tsx: ページ本体
      • layout.tsx: 共通レイアウト
      • loading.tsx: 読み込み中の表示(Suspense)
      • not-found.tsx: 404 表示
      • error.tsx: エラーハンドリング('use client' 必須)

「ファイル名で役割が決まる」というルールさえ覚えてしまえば、Next.js の開発はとても直感的になります。

今回は React SuspenseReact Error Boundary といった用語が出てきました。これらはモダンな React 開発において非常に重要な概念です。もし興味があれば、これらについても今後詳しく解説する記事を書きたいと思いますので、楽しみにしていてください!

次回は、このプロジェクトを使って 「実際にページを追加し、リンクで遷移する」 方法を実践していきます!


📝クイズコーナー:理解度チェック

1. `layout.tsx` と `page.tsx` の役割の違いは何ですか?

【回答例】

  • layout.tsx は「ページの外枠(レイアウト)」を定義します。ヘッダーやフッター、<html> タグなどを記述し、ページ遷移しても再レンダリングされずに維持されます。
  • page.tsx は「ページの中身(コンテンツ)」を定義します。その URL にアクセスしたときに表示されるメインの UI です。

layout の中に page がはめ込まれて表示されるイメージです。

2. `loading.tsx` を配置すると自動的にローディング画面が表示されるのはなぜですか?内部的に使われている React の機能名も答えてください。

【回答例】

Next.js がビルド時に page.tsx などのコンテンツを React Suspense で自動的にラップするからです。
loading.tsx の中身は Suspense の fallback として渡されるため、データの読み込み待ちの間、自動的にそのローディング UI が表示される仕組みになっています。

3. `error.tsx` はどのような目的で使われますか?また、内部的に使われている React の仕組みは何ですか?

【回答例】

  • 目的: ルート配下で発生した予期せぬエラーをキャッチし、アプリ全体をクラッシュさせずに「エラー画面」だけを表示して復旧を促すため。
  • 仕組み: React Error Boundary。Next.js が自動的にページコンポーネントを Error Boundary でラップすることで、エラー発生時に error.tsx の内容(フォールバック UI)を表示します。

🔗 参考情報


前回/次回

Discussion