Next.jsのプロジェクトを開くと、index.htmlstyle.cssだけで作るサイトとは違い、見慣れないフォルダーや設定ファイルがいくつも並んでいます。

srcpublicには画面を作るためのファイルがあり、package.jsonにはプロジェクトを動かすための情報が書かれています。その一方で、.nextnode_modulesのように、ツールが自動で作るものもあります。すべてを同じように読む必要はありません。

まず見分けたいのは、次の三つです。

  • 画面や機能を作っているファイル
  • プロジェクト全体の動かし方を決める設定ファイル
  • ツールが自動で作る、手で編集しないファイル

この区別がつくと、コーディングエージェントがどこを変更したのかも追いやすくなります。

なぜAI開発でNext.jsを使うのか

内容がほとんど変わらない案内ページなら、HTMLとCSSだけで十分な場合もあります。Next.jsを使えば、すべてのWebサイトが良くなるわけではありません。

ただし、問い合わせフォーム、ログイン、データの保存、外部API、AI機能などを加えると、HTMLとCSSだけでは扱う範囲が広がっていきます。画面を部品に分け、URLごとにページを用意し、サーバー側の処理や公開用のビルドも管理しなければなりません。Next.jsは、これらを一つのプロジェクトで扱うための枠組みです。

ReactとNext.jsには、公式資料だけでなく、公開されているコードや実装例も豊富にあります。コーディングエージェントがよくある実装パターンを提案しやすく、変更された側も既存の資料を手がかりに内容を確かめられます。AIにWebアプリの実装を頼むとき、Next.jsがよく選ばれる理由の一つです。

HTML、React、Next.jsの関係

ReactとNext.jsは、どちらか一方を選ぶものではありません。Next.jsはReactを使ってWebサイトやWebアプリを作るフレームワークです。

それぞれの役割は、次のように重なっています。

技術 主な役割
HTML 見出し、文章、画像など、ページの構造を表す
CSS 色、余白、文字サイズ、配置など、見た目を整える
JavaScript クリックへの反応やデータ処理など、ページに動きを加える
React 画面を再利用できる「コンポーネント」として組み立てる
Next.js Reactのコンポーネントを、ページ、URL、サーバー処理、ビルドなどと結び付ける

Reactでは、ボタン、カード、ヘッダーなどをコンポーネントという部品にします。Next.jsは、その部品を使いながら、ページの分け方、共通レイアウト、データの取得、公開用ファイルの作成などを扱います。

最初は「Reactが画面の部品を作り、Next.jsがそれらをWebサイトとして動かす」と捉えれば十分です。

セットアップ直後のプロジェクトを眺める

srcフォルダーを使うNext.jsプロジェクトは、たとえば次のような構成です。追加した機能やプロジェクトの方針によって、実際の名前や数は変わります。

my-app/
├── public/
├── src/
│   ├── app/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── components/
│   └── lib/
├── docs/
├── scripts/
├── .github/
├── .gitignore
├── eslint.config.mjs
├── next.config.ts
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json

この一覧には、Next.jsが決まった用途で使う名前、よく使われる慣習、プロジェクトが独自に追加した名前が混ざっています。さらに、実際にコマンドを実行すると、自動生成されるフォルダーも増えます。

コマンドを実行すると増えるフォルダー

新しいプロジェクトを次のようなコマンドで作ると、必要なファイル一式が作成されます。

npx create-next-app@latest my-app

通常はライブラリのインストールも続けて行われるため、node_modules/が作られます。GitHubなどから既存のプロジェクトを取得した場合は、プロジェクトのフォルダーでnpm installまたはnpm ciを実行するとnode_modules/が作られます。

npm ci

その後、開発用サーバーを起動するnpm run dev、または公開用ファイルを作るnpm run buildを実行すると、.next/が作られます。

npm run dev

node_modules/にはインストールされたライブラリが入り、.next/にはNext.jsが作ったキャッシュやビルド結果が入ります。どちらもアプリのコードを書く場所ではありません。

.next.githubのように、名前が.で始まるファイルやフォルダーは、macOSやLinuxでは隠しファイルとして扱われます。Finderなどでは通常表示されません。VS Codeでは表示されることが多いものの、設定によって非表示になっている場合があります。

app/src/app/はどちらも使える

Next.jsでは、ページを置くappフォルダーに二つの配置方法があります。

  • プロジェクト直下に置く場合:my-app/app/page.tsx
  • srcの中に置く場合:my-app/src/app/page.tsx

どちらもNext.jsで認められている構成です。srcは、アプリのソースコードと、プロジェクト直下の設定ファイルを分けたいときに使います。

一つのプロジェクトで、同じ役割のapp/src/app/を両方作る必要はありません。この記事ではsrc/app/を使います。開いたプロジェクトがapp/を使っている場合は、以降のパスからsrc/を外して読んでください。

フォルダーは役割ごとに見る

ファイルツリーを読むときは、すべての名前を暗記するより、「誰が何のために使う場所か」を考えると整理しやすくなります。

Next.jsプロジェクトのファイルを、予約名、プロジェクトの慣習、独自ファイル、自動生成の四種類に分け、手で編集する範囲を示した図

app/public/next.config.tsなどは、Next.jsが決まった用途で使う名前です。場所や名前そのものに意味があります。

components/lib/は、多くのプロジェクトで使われている慣習です。別の名前でも動きますが、同じ用途のコードを見つけやすくするために使われます。

docs/scripts/AGENTS.mdなどは、チームやプロジェクトが必要に応じて加えるものです。Next.jsが必須としているわけではありません。

.next/node_modules/next-env.d.tsは、コマンドやツールによって作られます。原則として手で編集しません。

画面や処理を置くsrc/

src/は、アプリのソースコードをまとめる場所です。Next.jsでは任意ですが、採用しているプロジェクトではappcomponentslibなどがこの中に置かれます。画面や機能を直すとき、最初に見る範囲です。

src/app/またはapp/は、Next.jsがページを探す場所です。この中に、ページやレイアウトを作るファイルを置きます。普段から編集する場所です。

components/には、ボタン、カード、ヘッダーなど、複数の場所で使う部品を置きます。Next.jsの必須フォルダーではなく、ui/という名前や、機能ごとのフォルダーを使うプロジェクトもあります。

lib/には、データの読み込み、文字列の変換、外部サービスとの接続など、画面そのものではない共通処理を置くことがあります。「画面に表示された値がどこから来たのか」を追うときに確認する場所です。

画像などを置くpublic/

public/には、画像、アイコン、PDFなど、そのまま配信するファイルを置きます。

たとえばpublic/logo.pngという画像を置くと、ページからは/logo.pngというパスで参照できます。HTMLサイトで画像フォルダーを作る感覚に近い場所です。

ただし、すべての画像がpublic/にあるとは限りません。ファイルをimportして使ったり、外部の画像サービスから取得したりするプロジェクトもあります。

プロジェクトが独自に加えるフォルダー

scripts/には、データの変換や一括チェックなど、繰り返し行う作業を自動化するプログラムが入ります。Next.jsの必須フォルダーではありません。実行するとファイルやデータが書き換わる場合もあるため、先にREADME.mdpackage.jsonで使い方を確認します。

docs/には、設計、操作手順、運用ルールなどの資料が置かれます。Next.jsはこのフォルダーを特別扱いしません。プロジェクトの背景や決まりを知りたいときは、コードより先に読むこともあります。

.github/は、Next.jsではなくGitHubが使うフォルダーです。GitHub Actionsの設定や、Issue、Pull Requestのテンプレートなどが入ります。画面のコードではありませんが、テストや公開処理に関わることがあります。

AGENTS.mdは、Codexなどのコーディングエージェントへ作業ルールを伝えるファイルです。実行するテスト、編集してはいけない範囲、ブランチの扱いなどが書かれます。エージェントへ作業を頼む前に、人間が読んでも役立ちます。

プロジェクト直下のファイルを一つずつ見る

フォルダーの外側には、プロジェクト全体の動かし方を決めるファイルが並びます。画面を作るコードとは役割が違うため、名前だけで読み飛ばさず、何を管理しているのかを確認します。

package.json:使うライブラリとコマンドの一覧

package.jsonには、プロジェクト名、使用するライブラリ、実行できるコマンドなどがJSON形式で書かれています。

特に確認するのはscriptsdependenciesです。scriptsを見ると、npm run devnpm run buildが内部で何を実行するか分かります。dependenciesを見ると、そのプロジェクトがNext.js以外にどのライブラリを使っているか分かります。

コーディングエージェントがpackage.jsonを変更した場合は、新しいライブラリやコマンドを追加した可能性があります。変更理由を確認したいファイルです。

package-lock.json:インストール内容を同じにする記録

package-lock.jsonには、実際にインストールするライブラリの正確なバージョンと組み合わせが記録されます。同じプロジェクトを別のパソコンやCIで動かすとき、できるだけ同じ内容を再現するために使います。

npm installなどを実行すると、npmがpackage.jsonと合わせて更新します。差分に現れるのは異常ではありません。内容を手で書き換えず、通常はpackage.jsonと一緒にGitへ登録します。

README.md:最初に読む説明書

README.mdには、セットアップ方法、使用するコマンド、必要な環境変数、プロジェクト固有の決まりなどが書かれます。

すべてのREADMEが詳しいとは限りませんが、初めてプロジェクトを開いたときは最初に確認します。記事や一般的な解説より、そのプロジェクトのREADMEに書かれた手順を優先します。

next.config.jsnext.config.ts:Next.jsの設定

next.config.jsnext.config.mjsnext.config.tsなどは、Next.jsの動作を設定するファイルです。画像を読み込める外部ドメイン、URLの書き換え、ビルド方法などの設定が入ることがあります。

すべてのプロジェクトで変更するものではありません。エージェントがこのファイルを触ったときは、どのNext.jsの動作を変えたのか確認します。

tsconfig.json:TypeScriptの読み方を決める設定

tsconfig.jsonには、TypeScriptがどのファイルを検査するか、どの書き方を許すか、@/のようなimport用の短いパスがどこを指すかなどが書かれます。

普段は頻繁に編集しません。importが急に解決できなくなったときや、型検査の範囲が変わったときに確認します。

eslint.config.jseslint.config.mjs:コードを検査するルール

ESLintは、間違いにつながりやすい書き方や、プロジェクトで統一したい書き方を検査する道具です。eslint.config.jseslint.config.mjsには、その検査ルールが書かれます。

エージェントがエラーを消すためにこの設定を緩めることもあります。コードを直したのではなく検査を無効にしていないか、差分を確認したいファイルです。

.gitignore:Gitへ登録しないものの一覧

.gitignoreには、Gitの変更履歴へ含めないファイルやフォルダーが書かれます。.next/node_modules/.env.localなどが代表例です。

自動生成物や秘密情報を誤ってGitHubへ送らないための設定なので、理由なく項目を削除しません。

.env.local:手元で使う秘密情報や設定値

.env.localには、APIキー、データベースの接続先、外部サービスの設定値などを置きます。プログラムからは環境変数として読み取ります。

APIキーなどの値は、ソースコードや記事へ貼り付けず、Gitにも登録しません。エージェントへ確認を頼むときも、値そのものを回答へ出さないよう伝えます。

手で編集しないもの

Next.jsのプロジェクトでは、コードと自動生成物が同じファイルツリーに並びます。次のものは、まず「原則として手で直さない」と判断できれば十分です。

.next/

npm run devnpm run buildを実行したときに、Next.jsが作るキャッシュやビルド結果です。中身を書き換えても、次の実行で作り直されます。アプリを修正するときは、appsrcなど元のコードを直します。

問題の切り分けで.next/を削除して作り直す場合はありますが、必要かどうかを確認してから行います。

node_modules/

npm installnpm ciでインストールされたライブラリ本体です。非常に多くのファイルが入ります。直接修正しても再インストールで消えるため、通常は編集せず、Gitにも登録しません。

ライブラリを追加・更新したいときは、node_modules/の中ではなく、npmのコマンドとpackage.jsonを使います。

next-env.d.ts

Next.jsがTypeScriptへ必要な型情報を知らせるために作るファイルです。Gitに登録されているプロジェクトもありますが、内容はNext.jsに管理させ、手では編集しません。

HTMLファイルはどこへ行ったのか

App Routerを使うNext.jsでは、トップページの内容をsrc/app/page.tsxに書きます。ブラウザで/を開くと、このファイルの内容が表示されます。

export default function Page() {
  return (
    <main className="content">
      <h1>はじめてのNext.js</h1>
      <p>HTMLに似ていますが、これはJSXです。</p>
    </main>
  )
}

<main><h1>はHTMLによく似ていますが、.tsxファイルの中ではJSXという記法として扱われます。多くのHTML要素はそのまま読めます。目につきやすい違いは、HTMLのclassがJSXではclassNameになることです。

関数やexport defaultをすぐに書けなくても、コードを読むことはできます。まずreturnの内側を探してください。そこに画面の構造があります。

別のページを作るときは、appの中にフォルダーを増やします。たとえばsrc/app/about/page.tsxは、/aboutを開いたときに表示されます。

layout.tsxは複数ページの共通部分

HTMLファイルをページごとに作ると、同じヘッダーやフッターを各ファイルへ書くことがあります。Next.jsでは、layout.tsxが内側のページを包みます。

export default function RootLayout({ children }) {
  return (
    <html lang="ja">
      <body>
        <Header />
        {children}
        <Footer />
      </body>
    </html>
  )
}

childrenの位置に、そのURLで表示するpage.tsxの内容が入ります。ヘッダーを一度直せば、同じレイアウトを使うページへまとめて反映されます。

コンポーネントは繰り返すHTMLを部品にする

同じ形の商品カードを何度も表示する場面を考えます。Reactでは、繰り返す見た目をコンポーネントとして分けられます。

function ProductCard({ name, price }) {
  return (
    <article>
      <h2>{name}</h2>
      <p>{price}円</p>
    </article>
  )
}

namepriceはpropsです。関数へ渡す引数のように、部品へ表示内容を渡します。{name}の波括弧は、JSXの中でJavaScriptの値を表示する場所です。

開始タグと終了タグの間に入れた内容を受け取るchildrenもpropsの一つです。layout.tsxだけの特別な仕組みではありません。

別ファイルのコンポーネントを使うときは、exportで外から使えるようにし、利用側でimportします。

import ProductCard from '@/components/ProductCard'

@/がどこを指すかはtsconfig.jsonなどで設定されます。srcを指す構成なら、この例はsrc/components/ProductCard.tsxを読んでいます。

商品が配列になっているときは、mapで一件ずつコンポーネントへ渡すコードをよく見かけます。

{products.map((product) => (
  <ProductCard
    key={product.id}
    name={product.name}
    price={product.price}
  />
))}

mapは、配列の各要素を順番に処理するJavaScriptの機能です。keyは、Reactが各商品を見分けるための目印です。ここでは「商品データの件数だけカードを作っている」と読めれば十分です。

ファイルの先頭にある"use client"は、クリック、入力、ブラウザの機能などを扱うコンポーネントで見かけます。詳しい仕組みを覚える前に、「ブラウザ上の操作がある部品の目印」として確認しておきます。

/productsから表示される値まで追ってみる

ブラウザで/productsを開き、「パン 240円」と表示されているとします。どこを直せば260円になるのか、画面から順に追います。

追う順番は次のとおりです。

  1. ブラウザで/productsを開く
  2. src/app/products/page.tsxがページの入口になる
  3. ページからsrc/components/ProductList.tsxが読み込まれる
  4. ProductListへ渡されたデータをたどり、src/lib/products.tsを確認する
  5. Reactが画面を組み立て、ブラウザに表示する

ブラウザから価格の出どころを探す順序と、products.tsの商品データがpage.tsx、ProductList.tsxを経て画面へ届く順序を比較した図

src/app/products/page.tsxは、/productsで表示するページです。そこでProductListをimportしていれば、次にそのファイルを開きます。ProductListproducts.map(...)で一覧を作り、価格をpropsから受け取っているなら、productsがどこから来たのかをimportでたどります。

src/lib/products.tsに次のデータがあれば、価格の変更場所はここです。

export const products = [
  { id: 1, name: 'りんご', price: 180 },
  { id: 2, name: 'パン', price: 240 },
]

価格を変えたいならデータ、の表示位置を変えたいならコンポーネント、ページ見出しを変えたいならpage.tsxを確認します。このように、URLから始めてimportを一つずつたどると、エージェントが変更した場所と理由を確かめられます。

サーバー側でproducts.tsからpage.tsxとProductListを通して表示結果を作り、ブラウザにはその結果を渡す境界の図

エージェントの変更を確認する

コーディングエージェントへ作業を頼んだ後、すべてのコードを一行ずつ理解する必要はありません。最初に、変更されたファイルの一覧を見ます。

画面を変えたなら、page.tsxlayout.tsxcomponents、CSS関連のファイルが変更されているはずです。表示するデータを変えた場合は、libやデータファイルも対象になります。

package.jsonpackage-lock.jsonが変わっていたら、ライブラリを追加または更新した可能性があります。画面の文章を変えただけなのに依存関係まで増えているなら、なぜ必要だったのかを確認します。

.next/node_modules/が変更成果物として並んでいたら、Gitへ含めようとしていないかを確認します。.env.localやAPIキーが差分に入っている場合は、そのまま共有したりコミットしたりしてはいけません。

最後に、エージェントへ次の二点を説明してもらいます。

  1. どのファイルを、なぜ変更したか
  2. どのコマンドを実行し、どの画面で確認したか

「できました」という回答だけでは、実際に動いたかどうかまでは分かりません。変更理由と確認方法が分かれば、コードをすべて読めなくても、作業内容を判断しやすくなります。

次にNext.jsのプロジェクトを開いたら、まずREADME.mdを読み、src/appまたはappを探してください。その後、表示したいURLに対応するpage.tsxを開き、importを一つずつたどります。分からないファイルがあっても、画面のコード、設定、慣習、自動生成物のどれかに分ければ、プロジェクト全体を一度に理解する必要はありません。