フロントエンド界隈の最新情報を追いかけていると、Next.js 13 で導入された app ディレクトリについての記事をよく見かけるようになりました。
app ディレクトリとは、Next.js 13 から導入された App Router と呼ばれる新しいルーティングシステムのためのディレクトリです。
当時はあくまで実験的な機能であったため、experimental(実験的)という扱いでしたがNext.js 13.4 で正式に導入されました。
正式採用されたということで、これから Next.js を学ぼうとしている人にとっては、app ディレクトリについて理解することは重要です。
そこで今回の記事では app ディレクトリについて、どのように使用するのかを解説します。
また、本記事の著者は以下のような経験を持っており、わかりやすくプログラミングを教えるプロですのでご安心ください!
- 現役のフルスタックWebエンジニアとして活躍中
- プログラミングスクールで教材を執筆した経験アリ
- 副業でプログラミングスクール講師をしている教育のプロ
App Routerと新たなappディレクトリの違い
Next.jsはそのファイルシステムベースのルーティング機能で有名です。
そしてNext.jsのバージョン13において、appディレクトリという新機能が導入され、多くのタスクがこれまでとは異なる方法で行えるようになりました。

以前からのpagesディレクトリを使用したルーティングは引き続きサポートされていますが、新たなappディレクトリでは、レイアウト、エラーコンポーネント、ローディングコンポーネントなど新たなコンセプトが導入されました。
pagesディレクトリとappディレクトリの違いを理解する
もし前のNext.jsのバージョンを使用した経験があるならば、pages ディレクトリについてはすでにご存知かもしれません。
ですが、初めて読んだ人のためにも説明しておきましょう。
pagesディレクトリ内のファイルは、それぞれが UI 上のパスとしてマッピングされます。
たとえば、pages/home.tsxは/homeというパス(URLの末尾)に相当します。
しかし、新しく導入されたappディレクトリはpagesディレクトリと協調して、新たなサーバーサイドレンダリングや静的サイト生成などの機能を提供します。
appディレクトリでのルーティングの詳細
appディレクトリ内の各フォルダは、pagesディレクトリと同じくルーティングの管理に利用されます。
appディレクトリ内のフォルダは、pagesディレクトリ内のファイルと同じように、URLのパスとしてマッピングされます。
具体的な例を見てみましょう。
/app/books/page.tsxというパスのページファイルと、
さらに/app/books/sf/page.tsxというパスのページファイルがあるとします。

このとき、URLにおける/app/booksというパスは/app/books/page.tsxというファイルにマッピングされます。
一方、/app/books/sfというパスは/app/books/sf/page.tsxというファイルにマッピングされます。
| URL例 | マッピングされるファイル |
| http://localhost:3000/app/books | /app/books/page.tsx |
| http://localhost:3000/app/books/sf | /app/books/sf/page.tsx |
その結果、例えばhttp://localhost:3000/app/books
というURLにアクセスすると、/app/books/page.tsxの内容が表示されます。
同様に、http://localhost:3000/app/books/sf
というURLにアクセスすると、/app/books/sf/page.tsxの内容が表示されます。
これはPages Routerにおけるindex.tsxと同様の考え方であり、簡潔で直感的なルーティング管理を実現しています。
layout(レイアウト) ファイル
各ページに共通する部品は layout.tsx という名前でレイアウトとして定義していきます。
※Pages Router における _document.tsx や _app.tsx が廃止されました。appフォルダ直下のlayout.tsxが代わりとなっています。

また、レイアウトは app フォルダ以外にも app フォルダ内の各フォルダに 1つずつ配置でき、ページごとにレイアウトを追加することができます。
※ただ、上位階層の layout.tsx にネストして適用されるため、あまり深くネストすることはおすすめしません。
例えば、/app/blog/page.tsxのページには、app/layout.tsx と /app/blog/layout.tsx の両方のレイアウトが適用されます。

なお、npx create-next-appで作成した場合は、appフォルダ直下にlayout.tsxが作成されており、以下のようになっていました。
import './globals.css'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body className={inter.className}>
{children}
</body>
</html>
)
}page ページファイル
page.tsx が実際に表示されるページのファイルです。
画面表示を変えたいときは、基本的にこのファイルを修正することになります。

これまではpagesフォルダ内の.tsxファイルは全てページとして扱われてきました。
一方、App Routerではpage.tsxというファイルのみがページとして扱われます。
記述方法はこれまでとほとんど変わりません。
export default function Page() {
return (
<h1>This is Page</h1>
)
}Next.js 13.4:appディレクトリを使った新しいプロジェクト作成手順
では、実際に app ディレクトリを活用してみましょう。
プロジェクトのセットアップ
まずは、Next.jsの新プロジェクトを作成しましょう。 ターミナルで以下のコマンドを入力します。
$ npx create-next-app@latest --typescript portofolio-next-appこのとき、おそらく以下のように聞かれるはずので、yを入力してください。
バージョンが 13.4 以上であることを確認しましょう。
Need to install the following packages: create-next-app@13.4.7 Ok to proceed? (y)いくつか質問されるはずですが、すべてデフォルトにします。

このうち、App router に関する質問はappディレクトリを使用するかどうかを聞かれています。
今回はApp router を使用するので、yを入力することに注意してください。
(13.4 では “recommended”、つまり推奨機能になっていますね!
作成されたフォルダ構成を見てみると、appディレクトリが作成されていることがわかります。

一旦、起動してみましょう。
$ cd portofolio-next-app
$ npm run devhttp://localhost:3000にアクセスすると、以下のような画面が表示されるはずです。
※ポート番号は環境によって変わる場合があります。

新しいページの追加
では次に /blog にアクセスできるようにしてみましょう。
app/blog/page.tsx という新しいファイルを作成し、以下のように記述します。
import Head from 'next/head'
export default function BlogPage() {
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2">
<h2 className="text-6xl font-bold">Blog Page</h2>
</div>
)
}今回、セットアップ時に Tailwind CSS を使用することをデフォルトとして選択していたので、 Tailwind CSS を使って装飾しています。
http://localhost:3000/blog にアクセスすると、以下のような画面が表示されるはずです。

なお、現在のディレクトリ構成は以下のようになっています。
app
├── blog
│ └── page.tsx
├── favicon.ico
├── globals.css
├── layout.tsx
└── page.tsx次は、blog ディレクトリの中だけに適用するレイアウトファイルを作っていきます。
layout.tsx の活用
では layout.tsx を試してみましょう。
Next.js 13 から layout.tsx が新たに導入され、ページごとのレイアウトを柔軟に設定することが可能になりました。
試しにapp/blog/layout.tsx というファイルを作成し、以下のように記述します。
import type { ReactNode } from 'react';
export const metadata = {
title: 'PageTitle',
}
export default function Layout({ children }: { children: ReactNode }) {
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2 bg-lime-800">
<h1 className="text-6xl font-bold mt-10">Blog Layout</h1>
{children}
</div>
);
}ここでは children というpropsを受け取っています。
ここにpage.tsx で記述したコンポーネントが入り、結果的にapp/blog/page.tsx 全体に layout.tsx のレイアウトが適用されます。
HTMLでいうところの、親要素のスタイルが子要素にも適用されるようなイメージです。
また、metadata という箇所にも注目してください。
これまでは Head という要素を作ってその中にタイトルなどを埋め込んでいましたが、Next.js 13.4 ではこのような形でページのメタデータを埋め込むことができます。
では、画面で確認してみましょう。
再度 http://localhost:3000/blog にアクセスすると、今度は以下のような画面が表示されます。

上の方に表示されている Blog Layout が layout.tsx で記述したコンポーネントです。
また、全体として bg-lime-800 という、layout.tsxで設定した背景色(濃い緑)が適用されていることがわかります。
また、ブラウザのタブをみると、metadata で設定したタイトルが表示されていますね。

ここで、親のページをもう一度みてみましょう。http://localhost:3000 にアクセスすると、最初と変わらず以下のような画面が表示されるはずです。

このように layout.tsx は、同じディレクトリの page.tsx で記述したコンポーネントをラップし、限定した範囲でレイアウトを変更することができます。
まとめ
新たに導入された app ディレクトリは Next.js 13.4 で正式にリリースされたことから、フロントエンド開発において重要な役割を果たしていくことでしょう。
今後、従来のpagesによるルーティングから徐々にトレンドが移行していくことが予想されるため、新しいプロジェクト作成時の App Router 導入や、既存のプロジェクトではpagesからの移行が推奨されていくと思われます。
フロントエンド開発は変化が早い分野ですので、今後も最新情報のウォッチが欠かせませんね。
フルスタックエンジニアを目指している方へおすすめの記事
本記事ではフロントエンド技術にのみ焦点をあて、バックエンドについては触れませんでした。
バックエンドも学び、フルスタックエンジニアになりたい方には以下の記事もおすすめです。

