はじめに
本記事では、Next.js 15 を用いたプロジェクト作成からフォルダ構成、App Router の基本的な使い方までを解説します。
想定読者
- React の基礎知識をお持ちの方
- Next.js での開発を始めてみたい方
本記事の目標
- Next.js 15 のプロジェクトを立ち上げる手順を理解する
-
src/app
フォルダを基点とした基本的なフォルダ構成を把握する - App Router によるルーティング、レイアウトなどの仕組みを学ぶ
1. 開発環境
以下の環境で動作を確認しながら進めます。
- Node.js v20.11.1 以上
- npm v9.x 以上
- TypeScript Version 5.3.3
2. プロジェクトの作成
ターミナルで任意のディレクトリに移動し、次のコマンドを実行して Next.js 15 のプロジェクトを作成します。
npx create-next-app@^15
実行すると、いくつかの質問が対話形式で表示されます。それぞれの質問に対して、以下のように回答してください。
質問内容 | 推奨回答 | 説明 |
---|---|---|
What is your project named? | 任意(例: my-next-app) | プロジェクト名を入力します。カレントディレクトリを使う場合は . を入力します。 |
Would you like to use TypeScript? | Yes | 型安全な開発ができるため、TypeScriptの利用をおすすめします。 |
Would you like to use ESLint? | Yes | コード品質を保つために、ESLint(コードリントツール)を有効にします。 |
Would you like to use Tailwind CSS? | Yes | スタイリングを効率化するため、Tailwind CSSを使用することをおすすめします。 |
Would you like your code inside a src/ directory? | Yes | ソースコードを src/ ディレクトリ以下にまとめることで、構成が整理されます。 |
Would you like to use App Router (recommended)? | Yes | Next.js 15以降はApp Routerが標準のルーティングシステムとなるため、有効化します。 |
Would you like to use Turbopack for next dev? | No または Yes | Turbopackは開発サーバーのパフォーマンスを向上させます。試してみたい場合はYesを選びますが、Noでも問題ありません。 |
Would you like to customize the default import alias (@/*)? | No | デフォルトのエイリアス設定(@/)のままで問題ありません。必要に応じて後から変更できます。 |
このように進めることで、最新の推奨構成に沿ったNext.js 15プロジェクトを簡単に作成できます。
また、これらの設定をすべてスキップして一括指定したい場合は、以下のようなコマンドも利用できます。
npx create-next-app@^15 --typescript --eslint --tailwind --src-dir --app
3. 基本のフォルダ構成(src/app
)
プロジェクト作成後、最初にフォルダ構成を確認します。
src/
└── app/
├── layout.tsx # 共通レイアウト
├── page.tsx # トップページ
├── about/ # /about ページ
│ └── page.tsx
└── contact/ # /contact ページ
└── page.tsx
-
layout.tsx
:ヘッダーやフッターなど、全ページで共通する UI を定義します。 -
page.tsx
:各フォルダごとにトップレベルのページコンポーネントとして扱われます。 - フォルダ名がそのまま URL パスになります(例:
/about
、/contact
)。
4. 開発サーバーの起動と本番ビルド
4.1 開発サーバーの起動
npm run dev
http://localhost:3000
で開発中のサイトを確認できます。
4.2 本番ビルドと起動
npm run build
npm run start
npm run build
で生成される.next
フォルダをもとに、本番サーバーが立ち上がります。
5. App Router の基本
Next.js 15 の App Router では、ファイルシステムをもとに自動的にルーティングが設定されます。以下の機能を順に見ていきます。
5.1 ページとレイアウト
5.1.1 ルートレイアウト(layout.tsx
)
// src/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<body>
<header>
<h1>タイトル</h1>
</header>
{children}
<footer>© 2025 hoge Company</footer>
</body>
</html>
);
}
すべてのページで共通のヘッダー・フッターを表示できます。
5.1.2 ページコンポーネント(page.tsx
)
// src/app/page.tsx
export default function HomePage() {
return <p>Hello, Next.js 15!</p>;
}
URL ルートに対応したフォルダ直下のpage.tsx
がページとしてレンダリングされます。
5.2 動的ルーティング
フォルダ名を[param]
の形式にすると、動的ルーティングを実現できます。
src/
└── app/
└── blog/
└── [id]/
└── page.tsx
// src/app/blog/[id]/page.tsx
type PageProps = { params: { id: string } };
export default async function BlogPostPage({ params }: PageProps) {
const { id } = params;
return <div>Blog ID: {id}</div>;
}
/blog/10
にアクセスするとid
が文字列"10"
として取得できます。
5.3 ルーティンググループ
グループ化したいフォルダを(group)
の形式で作成すると、URL には含まれずグループだけを論理的にまとめられます。
src/
└── app/
└── (auth)/
├── login/
│ └── page.tsx
└── register/
└── page.tsx
// src/app/(auth)/login/page.tsx
export default function LoginPage() {
return <p>ログインページ</p>;
}
/login
、/register
でそれぞれアクセスできます。
5.4 NotFound ページ
app/not-found.tsx
を作成すると、存在しないパスで表示される 404 ページをカスタマイズできます。
// src/app/not-found.tsx
export default function NotFound() {
return <h2>このページは存在しません</h2>;
}
5.5 Loading ページ
loading.tsx
を配置するとデータフェッチ中に表示されるローディング UI を定義できます。
src/
└── app/
└── blog/
├── loading.tsx
└── [id]/
└── page.tsx
// src/app/blog/loading.tsx
export default function Loading() {
return <p>Loading...</p>;
}
5.6 Error ページ
error.tsx
を置くと、データフェッチエラー時などの表示をカスタマイズできます。
src/
└── app/
└── blog/
└── [id]/
├── error.tsx
└── page.tsx
// src/app/blog/[id]/error.tsx
"use client";
export default function ErrorPage() {
return <p>エラーが発生しました。</p>;
}
5.7 API ルート(Route Handlers)
src/app/api/
配下にroute.ts
を置くと、サーバーサイドの API エンドポイントを作成できます。
開発初期のモックAPIとしても、実運用時のエンドポイントとしても使用されます。
src/
└── app/
└── api/
└── users/
└── route.ts
// src/app/api/users/route.ts
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json([
{ id: 1, name: "yamada" },
{ id: 2, name: "tanaka" },
]);
}
5.8 メタデータ設定
各ページでexport const metadata
またはexport async function generateMetadata
を使い、タイトルや description を設定できます。
// src/app/blog/[id]/page.tsx
import { Metadata } from "next";
export async function generateMetadata({
params,
}: {
params: { id: string };
}): Promise<Metadata> {
return { title: `記事ID: ${params.id}` };
}
5.9 ミドルウェア
src/middleware.ts
を作成すると、リクエストが到達する前に実行される「事前処理」を定義することができます。
例えば、ログインしていないユーザーをログインページにリダイレクトしたり、リクエストのログを記録するなどの用途で使われます。
src/
├── app/
│ └── dashboard/
│ └── page.tsx
└── middleware.ts
// src/middleware.ts
import { NextResponse, NextRequest } from "next/server";
// ダミーの認証トークン(実際はCookieやヘッダーから取得)
const validTokens = ["token123", "token456"];
export function middleware(request: NextRequest) {
// クッキーからトークンを取得(本来は署名付きCookieやJWTを使います)
const token = request.cookies.get("auth-token")?.value;
// トークンが無効な場合はログインページにリダイレクト
if (!token || !validTokens.includes(token)) {
return NextResponse.redirect(new URL("/login", request.url));
}
// 認証済みの場合はリクエストをそのまま進める
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*"], // /dashboard配下のページすべてに適用
};
上記の例では、/dashboard
にアクセスすると/login
にリダイレクトします。
まとめ
本記事では、Next.js 15 を使ったプロジェクトの作成方法から、App Router を中心とした基本的なフォルダ構成やルーティング機能までを解説しました。
この記事を通じて、Next.js 15 を用いたモダンな Web アプリケーション開発の第一歩となれば幸いです。