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@latest
ESLintのバージョン
ESLintを使用している場合は、ESLintのバージョンをアップグレードする必要があります
npm install -D eslint-config-next@latest
知っておくと便利:ESLintの変更を有効にするには、VS CodeでESLintサーバーを再起動する必要がある場合があります。コマンドパレット(Macでは
cmd + shift + p
、Windowsではctrl + shift + p
)を開き、ESLint: ESLintサーバーの再起動
を検索してください。
次のステップ
アップデートが完了したら、次のステップについて以下のセクションを参照してください。
- 新機能のアップグレード:改善された Image コンポーネントや Link コンポーネントなどの新機能へのアップグレードを支援するガイドです。
pages
ディレクトリからapp
ディレクトリへの移行:pages
ディレクトリからapp
ディレクトリへの段階的な移行を支援するステップバイステップガイドです。
新機能のアップグレード
Next.js 13 では、新しい機能と規約を備えた新しい App Router が導入されました。新しい Router は app
ディレクトリで使用でき、pages
ディレクトリと共存します。
Next.js 13 へのアップグレードでは、新しい App Router を使用する必要はありません。更新された Image コンポーネント、Link コンポーネント、Script コンポーネント、フォントの最適化など、両方のディレクトリで機能する新機能を使用して pages
を引き続き使用できます。
<Image/>
コンポーネント
Next.js 12 では、next/future/image
という一時的なインポートを使用して、Image コンポーネントに新しい改善が導入されました。これらの改善には、クライアント側の JavaScript の削減、画像の拡張とスタイルの設定の容易化、アクセシビリティの向上、およびネイティブブラウザの遅延読み込みが含まれていました。
バージョン 13 では、この新しい動作が next/image
のデフォルトになりました。
新しい Image コンポーネントへの移行を支援するための 2 つの codemod があります。
next-image-to-legacy-image
codemod:next/image
インポートをnext/legacy/image
に安全かつ自動的に名前変更します。既存のコンポーネントは同じ動作を維持します。next-image-experimental
codemod: インラインスタイルを追加し、未使用の props を危険に削除します。これにより、既存のコンポーネントの動作が新しいデフォルトと一致するように変更されます。この codemod を使用するには、最初にnext-image-to-legacy-image
codemod を実行する必要があります。
<Link>
コンポーネント
<Link>
コンポーネントは、子として手動で <a>
タグを追加する必要がなくなりました。この動作は、バージョン 12.2で実験的なオプションとして追加され、現在はデフォルトになっています。Next.js 13 では、<Link>
は常に <a>
をレンダリングし、基になるタグに props を転送できます。
例:
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
ハンドラーは、サーバーコンポーネントでは機能しないため、それらを必ず クライアントコンポーネント に移動するか、完全に削除してください。
フォントの最適化
以前は、Next.js は フォント CSS をインライン化することでフォントの最適化を支援していました。バージョン 13 では、新しい next/font
モジュールが導入され、優れたパフォーマンスとプライバシーを確保しながら、フォントの読み込みエクスペリエンスをカスタマイズできるようになりました。next/font
は、pages
ディレクトリと app
ディレクトリの両方でサポートされています。
CSS のインライン化は pages
では引き続き機能しますが、app
では機能しません。代わりに next/font
を使用する必要があります。
next/font
の使用方法については、フォントの最適化のページを参照してください。
pages
から app
への移行
🎥 視聴: App Router を段階的に採用する方法をご覧ください → YouTube (16 分)。
App Router への移行は、サーバーコンポーネント、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 ルートは、route.js
(ルートハンドラー) 特殊ファイルに置き換えられました。
ステップ 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
ディレクトリには、必ずルートレイアウトを含める必要があります。- ルートレイアウトは、Next.jsが自動的に作成しないため、
<html>
タグと<body>
タグを定義する必要があります。 - ルートレイアウトは、
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プロバイダーを使用している場合は、クライアントコンポーネントに移動する必要があります。
getLayout()
パターンからレイアウトへの移行(オプション)
Next.jsでは、pages
ディレクトリでページごとのレイアウトを実現するために、ページコンポーネントにプロパティを追加することを推奨していました。このパターンは、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> }
-
pages
ディレクトリの動作を保持するために、DashboardLayout
の内容を新しいクライアントコンポーネントに移動します。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
(クライアントコンポーネント) の非インタラクティブな部分をlayout.js
(サーバーコンポーネント) に段階的に移動して、クライアントに送信するコンポーネント JavaScript の量を減らすことができます。
ステップ 3: 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
ディレクトリのページは、デフォルトでサーバーコンポーネントです。これは、ページがクライアントコンポーネントであるpages
ディレクトリとは異なります。app
では、データ取得が変更されています。getServerSideProps
、getStaticProps
、およびgetInitialProps
は、よりシンプルなAPIに置き換えられました。app
ディレクトリは、ネストされたフォルダーを使用してルートを定義し、特別なpage.js
ファイルを使用してルートセグメントを公開します。-
pages
ディレクトリapp
ディレクトリルート index.js
page.js
/
about.js
about/page.js
/about
blog/[slug].js
blog/[slug]/page.js
/blog/post-1
ページの移行を2つの主なステップに分解することをお勧めします
- ステップ 1: デフォルトでエクスポートされるページコンポーネントを新しいクライアントコンポーネントに移動します。
- ステップ 2: 新しいクライアントコンポーネントを、
app
ディレクトリ内の新しいpage.js
ファイルにインポートします。
知っておくと良いこと:これは、
pages
ディレクトリに最も近い動作を持つため、最も簡単な移行パスです。
ステップ 1: 新しいクライアントコンポーネントを作成する
app
ディレクトリ内に新しい別のファイル(例:app/home-page.tsx
など)を作成し、クライアントコンポーネントをエクスポートします。クライアントコンポーネントを定義するには、ファイルの先頭(インポートの前)に'use client'
ディレクティブを追加します。- ページルーターと同様に、クライアントコンポーネントを最初のページ読み込み時に静的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
ファイルを作成します。これはデフォルトでサーバーコンポーネントです。 -
home-page.tsx
クライアントコンポーネントをページにインポートします。 -
pages/index.js
でデータを取得していた場合は、新しいデータ取得APIを使用して、データ取得ロジックをサーバーコンポーネントに直接移動します。詳細については、データ取得アップグレードガイドを参照してください。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
からインポートされ、next/router
からインポートされたpages
のuseRouter
フックとは異なる動作をします。next/router
からインポートされたuseRouter
フックはapp
ディレクトリではサポートされていませんが、pages
ディレクトリでは引き続き使用できます。
- 新しい
useRouter
はpathname
文字列を返しません。代わりに、別のusePathname
フックを使用してください。 - 新しい
useRouter
はquery
オブジェクトを返しません。検索パラメーターと動的ルートパラメーターは、現在は別々になっています。代わりにuseSearchParams
フックとuseParams
フックを使用してください。 useSearchParams
とusePathname
を組み合わせて、ページ変更をリッスンできます。詳細については、ルーターイベントのセクションを参照してください。- これらの新しいフックは、クライアントコンポーネントでのみサポートされています。サーバーコンポーネントでは使用できません。
'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
は削除されました。locale
、locales
、defaultLocales
、domainLocales
の値は、組み込みのi18n Next.js機能がapp
ディレクトリでは不要になったため、削除されました。i18nの詳細を参照してください。basePath
は削除されました。代替はuseRouter
の一部にはなりません。まだ実装されていません。- 新しいルーターから
as
の概念が削除されたため、asPath
は削除されました。 - 静的レンダリング中、
useSearchParams()
フックを使用するコンポーネントはプリレンダリングステップをスキップし、代わりに実行時にクライアントでレンダリングされるため、isReady
は不要になったため削除されました。 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 コンポーネントにpropsを転送します。ページの初期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コンポーネント内にデータ取得を配置できます。これにより、クライアントに送信するJavaScriptの量を減らしながら、サーバーからのレンダリングされたHTMLを維持できます。
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/${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
ディレクトリの新しいモデルでは、getStaticPaths
よりもgenerateStaticParams
という名前を使用する方が適切です。get
プレフィックスは、より説明的なgenerate
に置き換えられました。これは、getStaticProps
とgetServerSideProps
が不要になったため、単独で使用する方が適しています。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'
オプションは、ストリーミングを使用した場合、'blocking'
とtrue
の違いがごくわずかであるため、dynamicParams
には含まれていません。
// `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
(デフォルト) に設定されている場合、生成されていないルートセグメントがリクエストされると、サーバーレンダリングされ、キャッシュされます。
インクリメンタル静的再生成 (getStaticProps
とrevalidate
)
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 ルート
APIルートは、変更を加えることなく、pages/api
ディレクトリで引き続き機能します。ただし、app
ディレクトリではルートハンドラーに置き換えられました。
ルートハンドラーを使用すると、Web Request および Response APIを使用して、特定のルートのカスタムリクエストハンドラーを作成できます。
export async function GET(request: Request) {}
知っておくと便利: 以前にAPIルートを使用してクライアントから外部APIを呼び出していた場合は、Server Componentsを使用してデータを安全にフェッチできます。データ取得の詳細をご覧ください。
ステップ 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 を使用したスタイリングについてさらに詳しく学ぶ
Codemods
Next.js は、機能が非推奨になった場合にコードベースのアップグレードを支援する Codemod 変換を提供します。詳細については、Codemods を参照してください。
この記事は役に立ちましたか?