フロントエンド界隈の最新情報を追いかけていると、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 dev
http://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
からの移行が推奨されていくと思われます。
フロントエンド開発は変化が早い分野ですので、今後も最新情報のウォッチが欠かせませんね。
フルスタックエンジニアを目指している方へおすすめの記事
本記事ではフロントエンド技術にのみ焦点をあて、バックエンドについては触れませんでした。
バックエンドも学び、フルスタックエンジニアになりたい方には以下の記事もおすすめです。