pages から App Router への移行方法
このガイドは以下のことを支援します
- Next.js アプリケーションをバージョン 12 から 13 に更新する
pagesディレクトリとappディレクトリの両方で機能する新機能のアップグレード- 既存のアプリケーションを
pagesからappへ段階的に移行する
新機能のアップグレード
Node.js バージョン
最小 Node.js バージョンは v18.17 になりました。詳細については、Node.js ドキュメント を参照してください。
Next.js バージョン
Next.jsバージョン13に更新するには、お好みのパッケージマネージャーを使用して次のコマンドを実行してください。
npm install next@latest react@latest react-dom@latestESLint バージョン
ESLint を使用している場合、ESLint のバージョンをアップグレードする必要があります。
npm install -D eslint-config-next@latest知っておくと便利な情報: ESLint の変更を有効にするには、VS Code で ESLint サーバーを再起動する必要がある場合があります。コマンドパレット(Mac では
cmd+shift+p、Windows ではctrl+shift+p)を開き、「ESLint: Restart ESLint Server」を検索します。
次のステップ
更新後、次のセクションで次のステップを確認してください。
- 新機能のアップグレード: 改善された Image および Link コンポーネントなどの新機能へのアップグレードを支援するガイド。
pagesディレクトリからappディレクトリへの移行:pagesディレクトリからappディレクトリへ段階的に移行するためのステップバイステップガイド。
新機能のアップグレード
Next.js 13 では、新しい機能と規約を備えた新しい App Router が導入されました。新しい Router は app ディレクトリで利用可能であり、pages ディレクトリと共存します。
Next.js 13 へのアップグレードでは、App Router を使用する必要はありません。pages を引き続き使用し、更新された Image コンポーネント、Link コンポーネント、Script コンポーネント、Font の最適化 など、両方のディレクトリで機能する新機能を利用できます。
<Image/>コンポーネント
Next.js 12 では、一時的なインポート next/future/image を使用して Image コンポーネントに新しい改善が導入されました。これらの改善には、クライアントサイド JavaScript の削減、画像の拡張とスタイリングの簡素化、アクセシビリティの向上、ネイティブブラウザの遅延読み込みなどが含まれていました。
バージョン 13 では、この新しい動作が next/image のデフォルトになりました。
新しいImageコンポーネントへの移行を支援する2つのcodemodがあります。
next-image-to-legacy-imagecodemod:next/imageのインポートをnext/legacy/imageに安全かつ自動的にリネームします。既存のコンポーネントは同じ動作を維持します。next-image-experimentalcodemod: インラインスタイルを追加し、未使用のプロップを削除します。これにより、既存のコンポーネントの動作が新しいデフォルトに一致するように変更されます。この codemod を使用するには、まずnext-image-to-legacy-imagecodemod を実行する必要があります。
<Link>コンポーネント
<Link> コンポーネントでは、<a> タグを子として手動で追加する必要がなくなりました。この動作は、バージョン 12.2 で実験的なオプションとして追加され、現在はデフォルトとなっています。Next.js 13 では、<Link> は常に <a> をレンダリングし、下位のタグにプロップを転送できます。
例:
import Link from 'next/link'
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
<a>About</a>
</Link>
// Next.js 13: `<Link>` always renders `<a>` under the hood
<Link href="/about">
About
</Link>リンクを Next.js 13 にアップグレードするには、new-link codemod を使用できます。
<Script>コンポーネント
next/script の動作は、pages と app の両方をサポートするように更新されましたが、スムーズな移行を確実にするためにいくつかの変更を行う必要があります。
_document.jsに含めていたbeforeInteractiveスクリプトを、ルートレイアウトファイル(app/layout.tsx)に移動してください。- 実験的な
worker戦略は、appではまだ機能しません。この戦略で指定されたスクリプトは、削除するか、別の戦略(例:lazyOnload)を使用するように変更する必要があります。 onLoad、onReady、onErrorハンドラーは Server Component では機能しません。これらのハンドラーは、Client Component に移動するか、削除してください。
フォント最適化
以前は、Next.js は フォント CSS をインライン化することでフォントの最適化を支援していました。バージョン 13 では、新しい next/font モジュールが導入され、フォントの読み込みエクスペリエンスをカスタマイズしつつ、優れたパフォーマンスとプライバシーを確保できるようになりました。next/font は pages ディレクトリと app ディレクトリの両方でサポートされています。
pages では CSS のインライン化が引き続き機能しますが、app では機能しません。代わりに next/font を使用する必要があります。
next/font の使用方法については、Font Optimization ページを参照してください。
pages から app への移行
🎥 動画: App Router を段階的に採用する方法を学ぶ → YouTube (16分)。
App Router への移行は、Server Components、Suspense など、Next.js が基盤とする React の新機能を使用する初めての機会となるかもしれません。これらの新機能と、特殊ファイルやレイアウトなどの新しい Next.js の機能と組み合わせると、移行は新しい概念、メンタルモデル、および動作変更の学習を意味します。
これらの更新の複合的な複雑さを軽減するために、移行をより小さなステップに分割することをお勧めします。app ディレクトリは、pages ディレクトリと同時に機能するように意図的に設計されており、ページごとの段階的な移行を可能にします。
appディレクトリは、ネストされたルートとレイアウトをサポートしています。詳細はこちら。- ネストされたフォルダを使用してルートを定義し、特殊な
page.jsファイルを使用してルートセグメントを公開可能にします。詳細はこちら。 - 特殊ファイル規約 は、各ルートセグメントの UI を作成するために使用されます。最も一般的な特殊ファイルは
page.jsとlayout.jsです。page.jsを使用して、ルート固有の UI を定義します。layout.jsを使用して、複数のルートで共有される UI を定義します。- 特殊ファイルには、
.js、.jsx、または.tsxのファイル拡張子を使用できます。
- コンポーネント、スタイル、テストなど、その他のファイルを
appディレクトリ内に共存させることができます。詳細はこちら。 getServerSidePropsやgetStaticPropsのようなデータ取得関数は、appディレクトリ内の新しい API に置き換えられました。getStaticPathsはgenerateStaticParamsに置き換えられました。pages/_app.jsとpages/_document.jsは、単一のapp/layout.jsルートレイアウトに置き換えられました。詳細はこちら。pages/_error.jsは、より詳細なerror.js特殊ファイルに置き換えられました。詳細はこちら。pages/404.jsはnot-found.jsファイルに置き換えられました。pages/api/*API Routes は、appディレクトリ内のroute.js(Route Handler) 特殊ファイルに置き換えられました。
ステップ 1: app ディレクトリの作成
最新の Next.js バージョンに更新してください(13.4 以上が必要です)。
npm install next@latest次に、プロジェクトのルート(または src/ ディレクトリ)に新しい app ディレクトリを作成します。
ステップ 2: ルートレイアウトの作成
app ディレクトリ内に新しい app/layout.tsx ファイルを作成します。これは app 内のすべてのルートに適用されるルートレイアウトです。
export default function RootLayout({
// Layouts must accept a children prop.
// This will be populated with nested layouts or pages
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}appディレクトリには、ルートレイアウトを 含める必要があります。- ルートレイアウトには
<html>と<body>タグを定義する必要があります。Next.js はそれらを自動的に作成しません。 - ルートレイアウトは、
pages/_app.tsxおよびpages/_document.tsxファイルを置き換えます。 - レイアウトファイルには、
.js、.jsx、または.tsx拡張子を使用できます。
<head> HTML 要素を管理するには、組み込みの SEO サポートを使用できます。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Home',
description: 'Welcome to Next.js',
}_document.js と _app.js の移行
既存の _app または _document ファイルがある場合は、その内容(例: グローバルスタイル)をルートレイアウト(app/layout.tsx)にコピーできます。 app/layout.tsx のスタイルは pages/* には適用されません。 pages/* ルートが壊れないように、移行中は _app/_document を維持してください。完全に移行したら、安全に削除できます。
React Context プロバイダーを使用している場合、それらを Client Component に移動する必要があります。
getLayout() パターンからレイアウトへの移行(オプション)
Next.js では、pages ディレクトリでページごとのレイアウトを実現するために、Page コンポーネントにプロパティを追加することが推奨されていました。このパターンは、app ディレクトリのネストされたレイアウトのネイティブサポートに置き換えることができます。
変更前後の例を参照
変更前
export default function DashboardLayout({ children }) {
return (
<div>
<h2>My Dashboard</h2>
{children}
</div>
)
}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.jsexport default function Page() { return <p>My Page</p> } -
DashboardLayoutの内容を新しい Client Component に移動して、pagesディレクトリの動作を維持してください。app/dashboard/DashboardLayout.js'use client' // this directive should be at top of the file, before any imports. // This is a Client Component export default function DashboardLayout({ children }) { return ( <div> <h2>My Dashboard</h2> {children} </div> ) } -
DashboardLayoutをappディレクトリ内の新しいlayout.jsファイルにインポートしてください。app/dashboard/layout.jsimport DashboardLayout from './DashboardLayout' // This is a Server Component export default function Layout({ children }) { return <DashboardLayout>{children}</DashboardLayout> } -
DashboardLayout.js(Client Component) のインタラクティブでない部分をlayout.js(Server Component) に段階的に移動することで、クライアントに送信するコンポーネント JavaScript の量を減らすことができます。
next/head の移行
pages ディレクトリでは、next/head React コンポーネントは、title や meta などの <head> HTML 要素を管理するために使用されます。 app ディレクトリでは、next/head は新しい 組み込みの SEO サポートに置き換えられました。
変更前
import Head from 'next/head'
export default function Page() {
return (
<>
<Head>
<title>My page title</title>
</Head>
</>
)
}変更後
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'My Page Title',
}
export default function Page() {
return '...'
}ステップ 4: ページコンポーネントの移行
appディレクトリのページは、デフォルトで Server Components です。これは、ページが Client Components であったpagesディレクトリとは異なります。- データ取得は
appで変更されました。getServerSideProps、getStaticProps、およびgetInitialPropsは、よりシンプルな API に置き換えられました。 appディレクトリは、ネストされたフォルダを使用してルートを定義し、特殊なpage.jsファイルを使用してルートセグメントを公開可能にします。-
pagesディレクトリappディレクトリRoute index.jspage.js/about.jsabout/page.js/aboutblog/[slug].jsblog/[slug]/page.js/blog/post-1
ページの移行を 2 つの主なステップに分割することをお勧めします。
- ステップ 1: デフォルトでエクスポートされた Page Component を新しい Client Component に移動します。
- ステップ 2: 新しい Client Component を
appディレクトリ内の新しいpage.jsファイルにインポートします。
知っておくと便利な情報: これは、
pagesディレクトリに最も近い動作を持つため、最も簡単な移行パスです。
ステップ 1: 新しい Client Component を作成する
appディレクトリ内に新しい個別のファイル(例:app/home-page.tsxなど)を作成し、Client Component をエクスポートします。Client Component を定義するには、ファイルの先頭(インポートの前)に'use client'ディレクティブを追加します。- Pages Router と同様に、Client Component を初期ページロード時に静的 HTML に事前レンダリングするための 最適化ステップ があります。
pages/index.jsからデフォルトでエクスポートされたページコンポーネントをapp/home-page.tsxに移動します。
'use client'
// This is a Client Component (same as components in the `pages` directory)
// It receives data as props, has access to state and effects, and is
// prerendered on the server during the initial page load.
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.tsxClient Component をページにインポートします。 -
pages/index.jsでデータを取得していた場合、データ取得ロジックを新しい データ取得 API を使用して Server Component に直接移動します。詳細については、データ取得のアップグレードガイドを参照してください。app/page.tsx// Import your 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() { // Fetch data directly in a Server Component const recentPosts = await getPosts() // Forward fetched data to your Client Component return <HomePage recentPosts={recentPosts} /> } -
以前のページで
useRouterを使用していた場合、新しいルーティングフックに更新する必要があります。詳細はこちら。 -
開発サーバーを起動し、
https://:3000にアクセスします。既存のインデックスルートが表示され、app ディレクトリから提供されているはずです。
ステップ 5: ルーティングフックの移行
app ディレクトリでの新しい動作をサポートするために、新しいルーターが追加されました。
app では、next/navigation からインポートされた 3 つの新しいフックを使用します: useRouter()、usePathname()、および useSearchParams()。
- 新しい
useRouterフックはnext/navigationからインポートされ、pagesのuseRouterフック(next/routerからインポートされる)とは異なる動作をします。next/routerからインポートされたuseRouterフックは、appディレクトリではサポートされていませんが、pagesディレクトリでは引き続き使用できます。
- 新しい
useRouterはpathname文字列を返しません。代わりに個別のusePathnameフックを使用してください。 - 新しい
useRouterはqueryオブジェクトを返しません。検索パラメータと動的ルートパラメータは分離されました。代わりにuseSearchParamsとuseParamsフックを使用してください。 useSearchParamsとusePathnameを組み合わせて、ページ変更をリッスンできます。詳細については、Router Events セクションを参照してください。- これらの新しいフックは Client Component でのみサポートされています。Server Component では使用できません。
'use client'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
export default function ExampleClientComponent() {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
// ...
}さらに、新しい useRouter フックには以下の変更があります。
fallbackが置き換えられたため、isFallbackは削除されました。appディレクトリでは組み込みの i18n Next.js 機能が不要になったため、locale、locales、defaultLocales、domainLocalesの値が削除されました。i18n について詳しくはこちら。basePathは削除されました。代替はuseRouterの一部にはなりませんでした。まだ実装されていません。asPathは、新しいルーターからasの概念が削除されたため削除されました。isReadyは不要になったため削除されました。 静的レンダリング中、useSearchParams()フックを使用するコンポーネントは、事前レンダリングステップをスキップし、代わりに実行時にクライアントでレンダリングされます。routeは削除されました。usePathnameまたはuseSelectedLayoutSegments()が代替手段を提供します。
pages と app 間でのコンポーネント共有
コンポーネントを pages と app ルーター間で互換性を持たせるには、next/compat/router からの useRouter フックを参照してください。これは pages ディレクトリからの useRouter フックですが、ルーター間でコンポーネントを共有する際に使用することを意図しています。 app ルーターでのみ使用する準備が整ったら、新しい next/navigation からの useRouter に更新してください。
ステップ 6: データ取得メソッドの移行
pages ディレクトリは、ページデータを取得するために getServerSideProps と getStaticProps を使用します。 app ディレクトリ内では、これらの以前のデータ取得関数は、fetch() と async React Server Components 上に構築されたよりシンプルな API に置き換えられました。
export default async function Page() {
// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
const staticData = await fetch(`https://...`, { cache: 'force-cache' })
// This request should be refetched on every request.
// Similar to `getServerSideProps`.
const dynamicData = await fetch(`https://...`, { cache: 'no-store' })
// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
const revalidatedData = await fetch(`https://...`, {
next: { revalidate: 10 },
})
return <div>...</div>
}サーバーサイドレンダリング (getServerSideProps)
pages ディレクトリでは、getServerSideProps はサーバーでデータを取得し、そのプロップをファイル内のデフォルトでエクスポートされた React コンポーネントに転送するために使用されます。ページの初期 HTML はサーバーから事前レンダリングされ、その後ブラウザでページが「ハイドレーション」(インタラクティブにする)されます。
// `pages` directory
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 コンポーネント内にデータ取得を共存させることができます。これにより、サーバーからのレンダリング済み HTML を維持しながら、クライアントに送信する JavaScript を削減できます。
cache オプションを no-store に設定することで、取得したデータがキャッシュされないことを示すことができます。これは、pages ディレクトリの getServerSideProps に似ています。
// `app` directory
// This function can be named anything
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 オブジェクトを取得し、それを使用してリクエストのクッキーとヘッダーを取得できます。
// `pages` directory
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 内で使用してクッキーを取得できます。
// `app` directory
import { cookies, headers } from 'next/headers'
async function getData() {
const authHeader = (await headers()).get('authorization')
return '...'
}
export default async function Page() {
// You can use `cookies` or `headers` inside Server Components
// directly or in your data fetching function
const theme = (await cookies()).get('theme')
const data = await getData()
return '...'
}静的サイト生成 (getStaticProps)
pages ディレクトリでは、getStaticProps 関数はビルド時にページを事前レンダリングするために使用されます。この関数は、外部 API やデータベースから直接データを取得し、ビルド中に生成されるページ全体にそのデータを渡すために使用できます。
// `pages` directory
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` directory
// This function can be named anything
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` directory
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 ディレクトリでは、getStaticPaths は generateStaticParams に置き換えられました。
generateStaticParams は getStaticPaths と同様に機能しますが、ルートパラメータを返すための API が簡素化されており、レイアウト内で使用できます。 generateStaticParams の戻り値の形状は、ネストされた param オブジェクトの配列または解決されたパスの文字列ではなく、セグメントの配列です。
// `app` directory
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/${(await params).id}`)
const post = await res.json()
return post
}
export default async function Post({ params }) {
const post = await getPost(params)
return <PostLayout post={post} />
}generateStaticParams という名前は、app ディレクトリの新しいモデルにとって getStaticPaths よりも適切です。 getStaticProps および getServerSideProps が不要になったため、 get プレフィックスはより説明的な generate に置き換えられました。 Paths サフィックスは Params に置き換えられ、複数の動的セグメントを持つネストされたルーティングにより適しています。
fallback の置き換え
pages ディレクトリでは、getStaticPaths から返される fallback プロパティは、ビルド時に事前レンダリングされないページの動作を定義するために使用されます。このプロパティは、ページが生成されている間にフォールバックページを表示するために true に設定したり、404 ページを表示するために false に設定したり、リクエスト時にページを生成するために blocking に設定したりできます。
// `pages` directory
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 ディレクトリの getStaticPaths の fallback: true | false | 'blocking' オプションを置き換えます。 fallback: 'blocking' オプションは dynamicParams には含まれていません。これは、ストリーミングを使用すると 'blocking' と true の違いはほとんどないためです。
// `app` directory
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 ...
}dynamicParams が true (デフォルト) に設定されている場合、生成されていないルートセグメントがリクエストされると、オンデマンドでサーバーレンダリングされ、キャッシュされます。
インクリメンタル静的再生成 (revalidate を使用した getStaticProps)
pages ディレクトリでは、getStaticProps 関数により、一定時間後にページを自動的に再生成するために revalidate フィールドを追加できます。
// `pages` directory
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` directory
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 Routes
API Routes は、pages/api ディレクトリで変更なしで引き続き機能します。ただし、app ディレクトリでは Route Handlers に置き換えられました。
Route Handlers は、Web Request および Response API を使用して、指定したルートのカスタムリクエストハンドラーを作成できます。
export async function GET(request: Request) {}知っておくと便利な情報: 以前、クライアントから外部 API を呼び出すために API Routes を使用していた場合、Server Components を使用して安全にデータを取得できるようになりました。 データ取得について詳しくはこちら。
シングルページアプリケーション
同時に Next.js へのシングルページアプリケーション (SPA) からの移行も行っている場合は、ドキュメントを参照してください。
ステップ 7: スタイリング
pages ディレクトリでは、グローバルスタイルシートは pages/_app.js にのみ制限されていました。 app ディレクトリでは、この制限は解除されました。グローバルスタイルは、任意のレイアウト、ページ、またはコンポーネントに追加できます。
Tailwind CSS
Tailwind CSS を使用している場合、 tailwind.config.js ファイルに app ディレクトリを追加する必要があります。
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // <-- Add this line
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
}app/layout.js ファイルにグローバルスタイルをインポートする必要もあります。
import '../styles/globals.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}Tailwind CSS でのスタイリングについて詳しくはこちら。
App Router と Pages Router の併用
異なる Next.js ルーターによって提供されるルート間を移動する場合、ハードナビゲーションが発生します。 next/link による自動リンクプリフェッチは、ルーターをまたいでプリフェッチしません。
代わりに、ナビゲーションを最適化する して、プリフェッチされた高速なページ遷移を維持できます。App Router と Pages Router 間のナビゲーションを最適化する方法について詳しくはこちら。
Codemods
Next.js は、機能が非推奨になった場合にコードベースをアップグレードするのに役立つ Codemod 変換を提供します。詳細についてはCodemods を参照してください。
役に立ちましたか?