メインコンテンツまでスキップ

App Router Incremental Adoption Guide

このガイドでは、以下のことを行う方法を説明します:

アップグレード

Node.jsのバージョン

最低限必要なNode.jsのバージョンはv18.17です。詳細はNode.jsのドキュメントを参照してください。

Next.jsのバージョン

Next.jsのバージョン13に更新するには、お好みのパッケージマネージャーを使用して次のコマンドを実行してください:

Terminal
npm install next@latest react@latest react-dom@latest

ESLintのバージョン

ESLintを使用している場合、ESLintのバージョンをアップグレードする必要があります:

Terminal
npm install -D eslint-config-next@latest

Good to know: ESLintの変更を反映させるために、VS CodeでESLintサーバーを再起動する必要があるかもしれません。コマンドパレット(Macではcmd+shift+p、Windowsではctrl+shift+p)を開き、ESLint: Restart ESLint Serverを検索してください。

次のステップ

更新が完了したら、次のセクションを参照して次のステップを確認してください:

新機能のアップグレード

Next.js 13では、新しい機能と規約を備えた新しいApp Routerが導入されました。新しいRouterはappディレクトリで利用可能で、pagesディレクトリと共存します。

Next.js 13へのアップグレードは、App Routerの使用を必要としません。pagesを引き続き使用し、両方のディレクトリで動作する新機能、例えば更新されたImageコンポーネントLinkコンポーネントScriptコンポーネント、およびフォント最適化を利用できます。

<Image/> コンポーネント

Next.js 12では、next/future/imageという一時的なインポートを使用してImageコンポーネントの新しい改善が導入されました。これらの改善には、クライアントサイドのJavaScriptの削減、画像の拡張とスタイルの簡素化、アクセシビリティの向上、ネイティブブラウザの遅延読み込みが含まれていました。

バージョン13では、この新しい動作がnext/imageのデフォルトになりました。

新しいImageコンポーネントへの移行を支援するために、2つのコードモッドがあります:

  • next-image-to-legacy-image codemodnext/imageインポートをnext/legacy/imageに安全かつ自動的にリネームします。既存のコンポーネントは同じ動作を維持します。
  • next-image-experimental codemod:インラインスタイルを危険に追加し、未使用のpropsを削除します。これにより、既存のコンポーネントの動作が新しいデフォルトに一致するように変更されます。このコードモッドを使用するには、最初にnext-image-to-legacy-imageコードモッドを実行する必要があります。

<Link> コンポーネントは、子として手動で<a>タグを追加する必要がなくなりました。この動作はバージョン12.2で実験的なオプションとして追加され、現在はデフォルトです。Next.js 13では、<Link>は常に<a>をレンダリングし、propsを基になるタグに転送できるようにします。

例:

import Link from 'next/link'

// Next.js 12: `<a>`はネストされていないと除外されます
<Link href="/about">
<a>About</a>
</Link>

// Next.js 13: `<Link>`は常に内部で`<a>`をレンダリングします
<Link href="/about">
About
</Link>

Next.js 13にリンクをアップグレードするには、new-link codemodを使用できます。

<Script> コンポーネント

next/scriptの動作は、pagesappの両方をサポートするように更新されましたが、スムーズな移行を確保するためにいくつかの変更が必要です:

  • 以前に_document.jsに含めていたbeforeInteractiveスクリプトをroot レイアウトファイル(app/layout.tsx)に移動します。
  • 実験的なworker戦略はまだappで動作しないため、この戦略で指定されたスクリプトは削除するか、別の戦略(例:lazyOnload)を使用するように変更する必要があります。
  • onLoadonReady、およびonErrorハンドラはServer Componentsでは動作しないため、Client Componentに移動するか、完全に削除してください。

フォント最適化

以前は、Next.jsはフォントCSSをインライン化することでフォントを最適化するのを支援していました。バージョン13では、新しいnext/fontモジュールが導入され、フォントの読み込み体験をカスタマイズしながら、優れたパフォーマンスとプライバシーを確保することができます。next/fontpagesappの両方のディレクトリでサポートされています。

CSSのインライン化pagesで引き続き動作しますが、appでは動作しません。代わりにnext/fontを使用する必要があります。

next/fontの使用方法については、フォント最適化ページを参照してください。

pagesからappへの移行

🎥 視聴: App Routerを段階的に採用する方法を学ぶ → YouTube (16分)

App Routerへの移行は、Next.jsが基盤として構築しているReactの機能(Server Components、Suspenseなど)を初めて使用することを意味するかもしれません。新しいNext.jsの機能(特別なファイルレイアウトなど)と組み合わせることで、移行は新しい概念、メンタルモデル、行動の変化を学ぶことを意味します。

これらの更新の複雑さを軽減するために、移行を小さなステップに分解することをお勧めします。appディレクトリは、ページごとに段階的に移行できるように、pagesディレクトリと同時に動作するように意図的に設計されています。

  • appディレクトリは、ネストされたルートとレイアウトをサポートしています。詳細はこちら
  • ネストされたフォルダを使用してルートを定義し、特別なpage.jsファイルを使用してルートセグメントを公開します。詳細はこちら
  • 特別なファイルの規約は、各ルートセグメントのUIを作成するために使用されます。最も一般的な特別なファイルはpage.jslayout.jsです。
    • page.jsを使用して、ルートに固有のUIを定義します。
    • layout.jsを使用して、複数のルートに共通するUIを定義します。
    • 特別なファイルには.js.jsx、または.tsxの拡張子を使用できます。
  • appディレクトリ内にコンポーネント、スタイル、テストなどの他のファイルを配置できます。詳細はこちら
  • getServerSidePropsgetStaticPropsのようなデータフェッチ関数は、app内の新しいAPIに置き換えられました。getStaticPathsgenerateStaticParamsに置き換えられました。
  • pages/_app.jspages/_document.jsは、単一のapp/layout.js root レイアウトに置き換えられました。詳細はこちら
  • pages/_error.jsは、より細かいerror.js特別なファイルに置き換えられました。詳細はこちら
  • pages/404.jsnot-found.jsファイルに置き換えられました。
  • pages/api/* APIルートは、route.js(Route Handler)特別なファイルに置き換えられました。

ステップ1:appディレクトリの作成

最新のNext.jsバージョンに更新します(13.4以上が必要です):

npm install next@latest

次に、プロジェクトのルート(またはsrc/ディレクトリ)に新しいappディレクトリを作成します。

ステップ2:Root レイアウトの作成

appディレクトリ内に新しいapp/layout.tsxファイルを作成します。これは、app内のすべてのルートに適用されるRoot レイアウトです。

app/layout.tsx
export default function RootLayout({
// レイアウトはchildren propを受け入れる必要があります。
// これはネストされたレイアウトやページで埋められます
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
  • appディレクトリには必ずroot レイアウトが含まれている必要があります。
  • root レイアウトは<html>および<body>タグを定義する必要があります。Next.jsは自動的にこれらを作成しません。
  • root レイアウトはpages/_app.tsxおよびpages/_document.tsxファイルを置き換えます。
  • レイアウトファイルには.js.jsx、または.tsxの拡張子を使用できます。

<head> HTML要素を管理するには、組み込みのSEOサポートを使用できます:

app/layout.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Home',
description: 'Welcome to Next.js',
}

_document.js_app.jsの移行

既存の_appまたは_documentファイルがある場合、その内容(例:グローバルスタイル)をroot レイアウト(app/layout.tsx)にコピーできます。app/layout.tsxのスタイルはpages/*には適用されません。移行中に_app/_documentを保持して、pages/*ルートが壊れないようにする必要があります。完全に移行が完了したら、それらを安全に削除できます。

React Contextプロバイダーを使用している場合、それらはClient Componentに移動する必要があります。

getLayout()パターンをレイアウトに移行する(オプション)

Next.jsは、pagesディレクトリでページごとのレイアウトを実現するためにページコンポーネントにプロパティを追加することを推奨していました。このパターンは、appディレクトリでのネストされたレイアウトのネイティブサポートに置き換えることができます。

前後の例を参照

components/DashboardLayout.js
export default function DashboardLayout({ children }) {
return (
<div>
<h2>My Dashboard</h2>
{children}
</div>
)
}
pages/dashboard/index.js
import DashboardLayout from '../components/DashboardLayout'

export default function Page() {
return <p>My Page</p>
}

Page.getLayout = function getLayout(page) {
return <DashboardLayout>{page}</DashboardLayout>
}

  • pages/dashboard/index.jsからPage.getLayoutプロパティを削除し、appディレクトリへのページ移行の手順に従います。

    app/dashboard/page.js
    export default function Page() {
    return <p>My Page</p>
    }
  • DashboardLayoutの内容を新しいClient Componentに移動して、pagesディレクトリの動作を保持します。

    app/dashboard/DashboardLayout.js
    'use client' // このディレクティブはファイルの先頭、インポートの前に配置する必要があります。

    // これはClient Componentです
    export default function DashboardLayout({ children }) {
    return (
    <div>
    <h2>My Dashboard</h2>
    {children}
    </div>
    )
    }
  • DashboardLayoutappディレクトリ内の新しいlayout.jsファイルにインポートします。

    app/dashboard/layout.js
    import DashboardLayout from './DashboardLayout'

    // これはServer Componentです
    export default function Layout({ children }) {
    return <DashboardLayout>{children}</DashboardLayout>
    }
  • DashboardLayout.js(Client Component)の非インタラクティブな部分をlayout.js(Server Component)に段階的に移動して、クライアントに送信するコンポーネントJavaScriptの量を減らすことができます。

ステップ3:next/headの移行

pagesディレクトリでは、next/head Reactコンポーネントを使用してtitlemetaなどの<head> HTML要素を管理します。appディレクトリでは、next/headは新しい組み込みのSEOサポートに置き換えられます。

前:

pages/index.tsx
import Head from 'next/head'

export default function Page() {
return (
<>
<Head>
<title>My page title</title>
</Head>
</>
)
}

後:

app/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
title: 'My Page Title',
}

export default function Page() {
return '...'
}

すべてのメタデータオプションを参照

ステップ4:ページの移行

  • appディレクトリのページはデフォルトでServer Componentsです。これは、pagesディレクトリのページがClient Componentsであるのとは異なります。
  • appでのデータフェッチは変更されました。getServerSidePropsgetStaticProps、およびgetInitialPropsは、よりシンプルなAPIに置き換えられました。
  • appディレクトリは、ネストされたフォルダを使用してルートを定義し、特別なpage.jsファイルを使用してルートセグメントを公開します。
  • pagesディレクトリappディレクトリルート
    index.jspage.js/
    about.jsabout/page.js/about
    blog/[slug].jsblog/[slug]/page.js/blog/post-1

ページの移行を2つの主要なステップに分解することをお勧めします:

  • ステップ1:デフォルトでエクスポートされたページコンポーネントを新しいClient Componentに移動します。
  • ステップ2:新しいClient Componentをappディレクトリ内の新しいpage.jsファイルにインポートします。

Good to know: これはpagesディレクトリに最も類似した動作を持つため、最も簡単な移行パスです。

ステップ1:新しいClient Componentを作成する

  • appディレクトリ内に新しいファイル(例:app/home-page.tsxなど)を作成し、Client Componentをエクスポートします。Client Componentsを定義するには、ファイルの先頭に'use client'ディレクティブを追加します(インポートの前)。
    • Pages Routerと同様に、初回ページロード時にClient Componentsを静的HTMLにプリレンダリングする最適化ステップがあります。
  • pages/index.jsからデフォルトでエクスポートされたページコンポーネントをapp/home-page.tsxに移動します。
app/home-page.tsx
'use client'

// これはClient Componentです(`pages`ディレクトリのコンポーネントと同じ)
// データをpropsとして受け取り、状態とエフェクトにアクセスでき、
// 初回ページロード時にサーバーでプリレンダリングされます。
export default function HomePage({ recentPosts }) {
return (
<div>
{recentPosts.map((post) => (
<div key={post.id}>{post.title}</div>
))}
</div>
)
}

ステップ2:新しいページを作成する

  • appディレクトリ内に新しいapp/page.tsxファイルを作成します。これはデフォルトでServer Componentです。
  • home-page.tsx Client Componentをページにインポートします。
  • pages/index.jsでデータをフェッチしていた場合、新しいデータフェッチAPIを使用してServer Component内にデータフェッチロジックを直接移動します。詳細については、データフェッチのアップグレードガイドを参照してください。
app/page.tsx
// Client Componentをインポートします
import HomePage from './home-page'

async function getPosts() {
const res = await fetch('https://...')
const posts = await res.json()
return posts
}

export default async function Page() {
// Server Component内でデータを直接フェッチします
const recentPosts = await getPosts()
// フェッチしたデータをClient Componentに転送します
return <HomePage recentPosts={recentPosts} />
}
  • 以前のページでuseRouterを使用していた場合、新しいルーティングフックに更新する必要があります。詳細はこちら
  • 開発サーバーを起動し、http://localhost:3000にアクセスします。appディレクトリを通じて提供される既存のインデックスルートが表示されるはずです。

ステップ5:ルーティングフックの移行

新しいルーターがappディレクトリの新しい動作をサポートするために追加されました。

appでは、next/navigationからインポートされた3つの新しいフック:useRouter()usePathname()、およびuseSearchParams()を使用する必要があります。

  • 新しいuseRouterフックはnext/navigationからインポートされ、pagesuseRouterフック(next/routerからインポート)とは異なる動作をします。
  • 新しいuseRouterpathname文字列を返しません。代わりに別のusePathnameフックを使用してください。
  • 新しいuseRouterqueryオブジェクトを返しません。検索パラメータと動的ルートパラメータは別々になりました。代わりにuseSearchParamsuseParamsフックを使用してください。
  • useSearchParamsusePathnameを一緒に使用してページの変更を監視できます。詳細はルーターイベントセクションを参照してください。
  • これらの新しいフックはClient Componentsでのみサポートされています。Server Componentsでは使用できません。
app/example-client-component.tsx
'use client'

import { useRouter, usePathname, useSearchParams } from 'next/navigation'

export default function ExampleClientComponent() {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()

// ...
}

さらに、新しいuseRouterフックには以下の変更があります:

  • isFallbackは削除されました。fallback置き換えられました
  • localelocalesdefaultLocalesdomainLocalesの値は削除されました。組み込みのi18n Next.js機能はappディレクトリでは不要です。i18nについて詳しく学ぶ
  • basePathは削除されました。代替案はuseRouterの一部にはなりません。まだ実装されていません。
  • asPathは削除されました。新しいルーターからasの概念が削除されたためです。
  • isReadyは削除されました。もはや必要ありません。静的レンダリング中に、useSearchParams()フックを使用するコンポーネントはプリレンダリングステップをスキップし、代わりにクライアントで実行時にレンダリングされます。
  • routeは削除されました。usePathnameまたはuseSelectedLayoutSegments()が代替手段を提供します。

useRouter() APIリファレンスを表示

pagesapp間でのコンポーネントの共有

コンポーネントをpagesappルーター間で互換性を保つために、next/compat/routerからのuseRouterフックを参照してください。 これはpagesディレクトリからのuseRouterフックですが、ルーター間でコンポーネントを共有する際に使用することを意図しています。appルーターでのみ使用する準備ができたら、新しいnext/navigationからのuseRouterに更新してください。

ステップ6:データフェッチメソッドの移行

pagesディレクトリでは、getServerSidePropsgetStaticPropsを使用してページのデータをフェッチします。appディレクトリ内では、これらの以前のデータフェッチ関数は、fetch()async React Server Componentsの上に構築されたよりシンプルなAPIに置き換えられました。

app/page.tsx
export default async function Page() {
// このリクエストは手動で無効化されるまでキャッシュされるべきです。
// `getStaticProps`に類似しています。
// `force-cache`はデフォルトであり、省略可能です。
const staticData = await fetch(`https://...`, { cache: 'force-cache' })

// このリクエストは毎回リフェッチされるべきです。
// `getServerSideProps`に類似しています。
const dynamicData = await fetch(`https://...`, { cache: 'no-store' })

// このリクエストは10秒間キャッシュされるべきです。
// `revalidate`オプションを使用した`getStaticProps`に類似しています。
const revalidatedData = await fetch(`https://...`, {
next: { revalidate: 10 },
})

return <div>...</div>
}

サーバーサイドレンダリング(getServerSideProps

pagesディレクトリでは、getServerSidePropsを使用してサーバー上でデータをフェッチし、ファイル内のデフォルトでエクスポートされたReactコンポーネントにpropsを転送します。ページの初期HTMLはサーバーからプリレンダリングされ、その後ブラウザでページを「ハイドレート」(インタラクティブにする)します。

pages/dashboard.js
// `pages`ディレクトリ

export async function getServerSideProps() {
const res = await fetch(`https://...`)
const projects = await res.json()

return { props: { projects } }
}

export default function Dashboard({ projects }) {
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}

App Routerでは、Server Componentsを使用してReactコンポーネント内にデータフェッチを配置できます。これにより、クライアントに送信するJavaScriptの量を減らしながら、サーバーからレンダリングされたHTMLを維持できます。

cacheオプションをno-storeに設定することで、フェッチされたデータが決してキャッシュされないことを示すことができます。これはpagesディレクトリのgetServerSidePropsに類似しています。

app/dashboard/page.tsx
// `app`ディレクトリ

// この関数は任意の名前を付けることができます
async function getProjects() {
const res = await fetch(`https://...`, { cache: 'no-store' })
const projects = await res.json()

return projects
}

export default async function Dashboard() {
const projects = await getProjects()

return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}

リクエストオブジェクトへのアクセス

pagesディレクトリでは、Node.js HTTP APIに基づいてリクエストベースのデータを取得できます。

たとえば、getServerSidePropsからreqオブジェクトを取得し、リクエストのcookieやヘッダーを取得することができます。

pages/index.js
// `pages`ディレクトリ

export async function getServerSideProps({ req, query }) {
const authHeader = req.getHeaders()['authorization'];
const theme = req.cookies['theme'];

return { props: { ... }}
}

export default function Page(props) {
return ...
}

appディレクトリでは、リクエストデータを取得するための新しい読み取り専用関数が公開されています:

  • headers:Web Headers APIに基づいており、Server Components内でリクエストヘッダーを取得するために使用できます。
  • cookies:Web Cookies APIに基づいており、Server Components内でcookieを取得するために使用できます。
app/page.tsx
// `app`ディレクトリ
import { cookies, headers } from 'next/headers'

async function getData() {
const authHeader = (await headers()).get('authorization')

return '...'
}

export default async function Page() {
// `cookies`または`headers`をServer Components内で
// 直接またはデータフェッチ関数内で使用できます
const theme = (await cookies()).get('theme')
const data = await getData()
return '...'
}

静的サイト生成(getStaticProps

pagesディレクトリでは、getStaticProps関数を使用してビルド時にページをプリレンダリングします。この関数は、外部APIやデータベースからデータをフェッチし、このデータをビルド中に生成されるページ全体に渡すために使用できます。

pages/index.js
// `pages`ディレクトリ

export async function getStaticProps() {
const res = await fetch(`https://...`)
const projects = await res.json()

return { props: { projects } }
}

export default function Index({ projects }) {
return projects.map((project) => <div>{project.name}</div>)
}

appディレクトリでは、fetch()を使用したデータフェッチはデフォルトでcache: 'force-cache'となり、リクエストデータが手動で無効化されるまでキャッシュされます。これはpagesディレクトリのgetStaticPropsに類似しています。

app/page.js
// `app`ディレクトリ

// この関数は任意の名前を付けることができます
async function getProjects() {
const res = await fetch(`https://...`)
const projects = await res.json()

return projects
}

export default async function Index() {
const projects = await getProjects()

return projects.map((project) => <div>{project.name}</div>)
}

動的パス(getStaticPaths

pagesディレクトリでは、getStaticPaths関数を使用してビルド時にプリレンダリングされる動的パスを定義します。

pages/posts/[id].js
// `pages`ディレクトリ
import PostLayout from '@/components/post-layout'

export async function getStaticPaths() {
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
}
}

export async function getStaticProps({ params }) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()

return { props: { post } }
}

export default function Post({ post }) {
return <PostLayout post={post} />
}

appディレクトリでは、getStaticPathsgenerateStaticParamsに置き換えられました。

generateStaticParamsgetStaticPathsと同様に動作しますが、ルートパラメータを返すための簡素化されたAPIを持ち、レイアウト内で使用できます。generateStaticParamsの戻り値の形状は、ネストされたparamオブジェクトの配列ではなく、解決されたパスの文字列の配列です。

app/posts/[id]/page.js
// `app`ディレクトリ
import PostLayout from '@/components/post-layout'

export async function generateStaticParams() {
return [{ id: '1' }, { id: '2' }]
}

async function getPost(params) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()

return post
}

export default async function Post({ params }) {
const post = await getPost(params)

return <PostLayout post={post} />
}

appディレクトリの新しいモデルにおいて、generateStaticParamsという名前を使用することはgetStaticPathsよりも適切です。getプレフィックスは、getStaticPropsgetServerSidePropsがもはや必要ないため、より説明的なgenerateに置き換えられました。PathsサフィックスはParamsに置き換えられ、複数の動的セグメントを持つネストされたルーティングにより適しています。


fallbackの置き換え

pagesディレクトリでは、getStaticPathsから返されるfallbackプロパティを使用して、ビルド時にプリレンダリングされないページの動作を定義します。このプロパティは、ページが生成される間にフォールバックページを表示するためにtrueに設定したり、404ページを表示するためにfalseに設定したり、リクエスト時にページを生成するためにblockingに設定したりできます。

pages/posts/[id].js
// `pages`ディレクトリ

export async function getStaticPaths() {
return {
paths: [],
fallback: 'blocking'
};
}

export async function getStaticProps({ params }) {
...
}

export default function Post({ post }) {
return ...
}

appディレクトリでは、config.dynamicParamsプロパティgenerateStaticParamsの外でのパラメータの処理方法を制御します:

  • true: (デフォルト)generateStaticParamsに含まれていない動的セグメントはオンデマンドで生成されます。
  • false: generateStaticParamsに含まれていない動的セグメントは404を返します。

これはpagesディレクトリのgetStaticPathsfallback: true | false | 'blocking'オプションを置き換えます。dynamicParamsにはfallback: 'blocking'オプションは含まれていません。'blocking'trueの違いはストリーミングではわずかです。

app/posts/[id]/page.js
// `app`ディレクトリ

export const dynamicParams = true;

export async function generateStaticParams() {
return [...]
}

async function getPost(params) {
...
}

export default async function Post({ params }) {
const post = await getPost(params);

return ...
}

dynamicParamstrue(デフォルト)に設定されている場合、生成されていないルートセグメントがリクエストされると、サーバーレンダリングされてキャッシュされます。

インクリメンタル静的再生成(getStaticProps with revalidate

pagesディレクトリでは、getStaticProps関数を使用して、一定時間後にページを自動的に再生成するためのrevalidateフィールドを追加できます。

pages/index.js
// `pages`ディレクトリ

export async function getStaticProps() {
const res = await fetch(`https://.../posts`)
const posts = await res.json()

return {
props: { posts },
revalidate: 60,
}
}

export default function Index({ posts }) {
return (
<Layout>
<PostList posts={posts} />
</Layout>
)
}

appディレクトリでは、fetch()を使用したデータフェッチでrevalidateを使用でき、指定された秒数の間リクエストをキャッシュします。

app/page.js
// `app`ディレクトリ

async function getPosts() {
const res = await fetch(`https://.../posts`, { next: { revalidate: 60 } })
const data = await res.json()

return data.posts
}

export default async function PostList() {
const posts = await getPosts()

return posts.map((post) => <div>{post.name}</div>)
}

APIルート

APIルートはpages/apiディレクトリで変更なしで動作し続けます。ただし、appディレクトリではRoute Handlersに置き換えられました。

Route Handlersを使用すると、Web RequestおよびResponse APIを使用して、特定のルートのカスタムリクエストハンドラを作成できます。

app/api/route.ts
export async function GET(request: Request) {}

Good to know: 以前にAPIルートを使用してクライアントから外部APIを呼び出していた場合、代わりにServer Componentsを使用してデータを安全にフェッチできます。データフェッチについて詳しく学ぶ。

シングルページアプリケーション

同時にシングルページアプリケーション(SPA)からNext.jsに移行している場合は、ドキュメントを参照して詳細を学んでください。

ステップ7:スタイリング

pagesディレクトリでは、グローバルスタイルシートはpages/_app.jsにのみ制限されています。appディレクトリでは、この制限が解除されました。グローバルスタイルは任意のレイアウト、ページ、またはコンポーネントに追加できます。

Tailwind CSS

Tailwind CSSを使用している場合、tailwind.config.jsファイルにappディレクトリを追加する必要があります:

tailwind.config.js
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // <-- この行を追加
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
}

また、グローバルスタイルをapp/layout.jsファイルにインポートする必要があります:

app/layout.js
import '../styles/globals.css'

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

Tailwind CSSでのスタイリングについて詳しく学ぶ

コードモッド

Next.jsは、機能が廃止されたときにコードベースをアップグレードするのを支援するためのコードモッド変換を提供します。詳細はコードモッドを参照してください。