2023年2月23日(木)
Next.js 13.2
投稿者Next.js 13.2では、安定版リリースに向けてApp Router(app
)に大幅な改善が加えられました
- 組み込みSEOサポート: 静的および動的な
meta
タグを設定するための新しいMetadata API。 - ルートハンドラ: Web
Request
およびResponse
を基盤としたカスタムリクエストハンドラ。 - Server Components向けMDX: Markdown内でReactコンポーネントを使用(サーバーサイドのみ)。
- Rust MDXパーサー: 新しいRustプラグインによる高速なMarkdown解析。
- 改良されたエラーオーバーレイ: Next.jsとReactのスタックトレースを分離し、可読性を向上。
- 静的型付きリンク (ベータ):
next/link
とTypeScriptでリンク切れを防止。 - Turbopackの改善 (アルファ): Webpackローダーとの互換性とサポートの向上。
- Next.jsキャッシュ (ベータ): プログレッシブISRとコード変更のデプロイ高速化。
今すぐアップデートするには、以下を実行してください。
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
新しいMetadata APIによる組み込みSEOサポート
Next.jsは、当初から検索エンジン向けに最適化できるように設計されています。
プリレンダリングされたHTMLコンテンツを提供することは、検索エンジンのインデックス作成を向上させるだけでなく、アプリケーションのパフォーマンスも向上させます。Next.jsは、長年にわたりアプリケーションのメタデータ(next/head
)を変更するためのシンプルなAPIを提供してきましたが、App Router(app
)を使用して検索エンジン向けに最適化する方法を再設計し、強化したいと考えました。
新しいMetadata APIを使用すると、Server Componentである任意のレイアウトまたはページで、明示的なメタデータ設定によりメタデータ(HTML head
要素内のmeta
およびlink
タグなど)を定義できます。
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Home',
description: 'Welcome to Next.js',
};
このAPIはシンプルで構成可能であり、ストリーミングサーバーレンダリングとの互換性を持つように設計されています。たとえば、ルートレイアウトでアプリケーション全体の共通のメタデータ属性を設定し、アプリケーションの他のルートについてはメタデータオブジェクトを合成およびマージすることができます。
これには、静的なものだけでなく動的なメタデータのサポートも含まれます。
// Static metadata
export const metadata = {
title: '...',
};
// Dynamic metadata
export async function generateMetadata({ params, searchParams }) {
const product = await getProduct(params.id);
return { title: product.title };
}
すべてのメタデータオプションが利用可能であり、カスタムメタデータを提供できます。TypeScriptプラグインを使用するか、Metadata
型を追加することでTypeScriptのサポートも利用できます。
たとえば、メタデータを通じてOpen Graph画像を定義できます。
export const metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
url: 'https://nextjs.dokyumento.jp',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.dokyumento.jp/og.png',
width: 800,
height: 600,
},
],
locale: 'en-US',
type: 'website',
},
};
export default function Layout({ children }) {}
Metadata APIは、以前のhead.js
特別ファイルに代わり、App Router(app
)向けに13.2で利用可能です。pages
ディレクトリでは利用できません。
SEOについてさらに学ぶ、またはMetadataのAPIリファレンスを参照する。コミュニティパッケージでの作業と初期API設計に関するフィードバックを提供してくださったnext-seoに感謝いたします。
カスタムルートハンドラ
App Router(app
)の最初のベータリリースで欠けていた要素の一つは、pages/api
ディレクトリに存在するAPI Routesでした。私たちはこの機会に、app
の新しいルーティングシステムに深く統合された、よりモダンなバージョンのAPI Routesを作成したいと考えました。
ルートハンドラを使用すると、Web RequestおよびResponse APIを使用して、特定のルートに対するカスタムリクエストハンドラを作成できます。
export async function GET(request: Request) {}
ルートハンドラは、EdgeとNode.jsのランタイムをシームレスにサポートするアイソモーフィックなAPIを備えており、ストリーミングレスポンスもサポートしています。ルートハンドラはページやレイアウトと同じルートセグメント設定を使用するため、汎用的な静的レンダリングや再検証といった待望の機能をサポートしています。
route.ts
ファイルは、HTTP動詞(GET
、HEAD
、OPTIONS
、POST
、PUT
、DELETE
、PATCH
)で名前付けされた非同期関数をエクスポートできます。これらの関数は、カスタムルートロジック用のヘルパー/再利用可能なロジックを作成するためにラップおよび抽象化できます。
cookies
や headers
といった他のサーバー関数も、これらの抽象化が構築されているWeb APIとともに、ルートハンドラ内で使用できます。これにより、Server Componentsとルートハンドラ間でコードを共有することが可能になります。
import { cookies } from 'next/headers';
export async function GET(request: Request) {
const cookieStore = cookies();
const token = cookieStore.get('token');
return new Response('Hello, Next.js!', {
status: 200,
headers: { 'Set-Cookie': `token=${token}` },
});
}
ルートハンドラは、route.ts
特別ファイルを使用してApp Router(app
)向けに13.2で利用可能です。API Routesの代替であるため、pages
ディレクトリでは利用できません。
ルートハンドラについてさらに学ぶ、またはAPIリファレンスを参照する。SvelteKitの先行事例とインスピレーションに感謝いたします。
Server Components向けMDX
MDXは、Markdownファイル内に直接JSXを記述できるMarkdownのスーパーセットです。これは、動的なインタラクティビティを追加し、コンテンツ内にReactコンポーネントを埋め込むための強力な方法です。
13.2では、MDXを完全にReact Server Componentsで使用できるようになりました。これにより、クライアントサイドJavaScriptが減り、ページの読み込みが高速化され、動的なUIをテンプレート化するReactの強力な機能を維持できます。必要に応じて、MDXコンテンツにインタラクティビティを散りばめることができます。
@next/mdx
プラグインは、カスタムコンポーネントを提供するためにアプリケーションのルートで定義される新しい特殊ファイル mdx-components.js|ts
のサポートを含むように更新されました。
// This file allows you to provide custom React components
// to be used in MDX files. You can import and use any
// React component you want, including components from
// other libraries.
function H1({ children }) {
// ...
}
function H2({ children }) {
// ...
}
export function useMDXComponents(components) {
return { h1: H1, h2: H2, ...components };
}
さらに、MDXコンテンツをフェッチするためのコミュニティパッケージnext-mdx-remote
およびcontentlayer
と協力し、React Server Componentsのサポートを追加しました。
Server ComponentsでMDXをセットアップする方法についてさらに学ぶ、またはサンプルをデプロイする。
Rust MDXパーサー
Server Components向けMDXを有効にする一環として、パフォーマンスを向上させるためMDXパーサーをRustで書き直しました。これは、多数のMDXファイルを処理する際に著しい速度低下が見られた以前のJavaScriptベースのパーサーに比べて、大幅な改善です。
next.config.js
でRustパーサーの使用を選択できます。たとえば、@next/mdx
を使用する場合:
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
mdxRs: true,
},
};
const withMDX = require('@next/mdx')();
module.exports = withMDX(nextConfig);
このプロジェクトに取り組むためにスポンサーしたTitus Wormerに感謝いたします。Next.js以外でこれを使用したい場合は、新しいパッケージmdxjs-rsをご覧ください。
静的型付きリンク
Next.jsでは、app
ディレクトリ内のリンクを静的に型付けできるようになり、next/link
を使用する際のタイプミスやその他のエラーを防ぎ、ページ間の移動における型安全性を向上させます。
import Link from 'next/link'
// ✅
<Link href="/about" />
// ✅
<Link href="/blog/nextjs" />
// ✅
<Link href={`/blog/${slug}`} />
// ❌ TypeScript errors if href is not a valid route
<Link href="/aboot" />
この機能を使用するには、新しいApp RouterとTypeScriptが必要です。
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
typedRoutes: true,
},
};
module.exports = nextConfig;
この機能は現在ベータ版で利用可能です。rewrites
と redirects
はまだサポートされていません。
改良されたエラーオーバーレイ
エラーの可読性とデバッグ性を向上させるため、Next.jsのエラーオーバーレイにいくつかの改善を加えました。
13.2では、Next.jsとReactのスタックトレースが分離され、エラーの発生源を特定しやすくなりました。さらに、エラーオーバーレイには現在のNext.jsのバージョンが表示され、ご自身のバージョンが最新であるかを確認するのに役立ちます。

また、Reactのハイドレーションエラーに対するエラー出力も改善され、より読みやすくデバッグしやすくなりました。
Turbopackの改善
Next.js 13でアルファ版として発表されたTurbopackは、ローカル開発と将来のプロダクションビルドの両方を高速化するために設計されたインクリメンタルなバンドラです。
私たちはTurbopackにおける既存のNext.js機能のサポートと、ベータ版への移行に向けた全体的な安定性の向上に注力してきました。前回のリリース以降、以下の機能が追加されました。
next/dynamic
のサポートnext.config.js
におけるrewrites
、redirects
、headers
、pageExtensions
のサポートpages
における404エラーとその他のエラーのサポート- CSSモジュールの
composes: ... from ...
のサポート - Fast Refreshの信頼性とエラーリカバリの向上
- CSSの優先順位処理の改善
- コンパイル時評価の改善
また、Turbopackを社内最大規模のNext.jsアプリケーションや初期のVercelのお客様にdogfooding(自社製品を自社で利用)する中で、多くのバグを修正し、安定性を向上させました。
Webpackローダーによるカスタムファイル変換
Turbopackは現在、一部のwebpackローダーのサポートと互換性を提供しています。これにより、Webpackエコシステムから多くのローダーを使用して、異なるタイプのファイルをJavaScriptに変換できます。@mdx-js/loader
、@svgr/webpack
、babel-loader
などのローダーがサポートされています。Turbopackのカスタマイズについて詳しく学ぶ。
たとえば、experimental.turbo.loaders
を使用して、各ファイル拡張子のローダーリストを設定できます。
module.exports = {
experimental: {
turbo: {
loaders: {
'.md': [
{
// Option format
loader: '@mdx-js/loader',
options: {
format: 'md',
},
},
],
'.svg': ['@svgr/webpack'],
},
},
},
};
完全な例については、ローダーを使用したTurbopackの例をご覧ください。
WebpackスタイルのResolveエイリアス
Turbopackは、webpackのresolve.alias
と同様に、エイリアスを介してモジュール解決を変更するように設定できるようになりました。これはexperimental.turbo.resolveAlias
で設定します。
module.exports = {
experimental: {
turbo: {
resolveAlias: {
underscore: 'lodash',
mocha: { browser: 'mocha/browser-entry.js' },
},
},
},
};
Next.jsキャッシュ
Next.js 13.2では、ISRの進化形である新しいNext.jsキャッシュ(ベータ版)が導入され、以下の機能が利用可能になります:
- コンポーネントレベルでのプログレッシブISR
- ネットワークリクエストなしでの高速リフレッシュ
- 静的ページへのコード変更のデプロイ高速化
完全に静的なページの場合、ISRはこれまでと同様に機能します。より詳細なデータフェッチ(静的と動的の組み合わせ)を行うページの場合、Next.jsキャッシュはよりきめ細かく、一時的なキャッシュを使用します。
Next.js App Router(app
)におけるReact Server Componentsとコロケーションされたデータフェッチの基盤により、静的または動的なデータを、それを利用するコンポーネントとともにカプセル化できるようになりました。
export default async function Page() {
const [staticData, dynamicData, revalidatedData] = await Promise.all([
// Cached until manually invalidated
fetch(`https://...`),
// Refetched on every request
fetch(`https://...`, { cache: 'no-store' }),
// Cached with a lifetime of 10 seconds
fetch(`https://...`, { next: { revalidate: 10 } }),
]);
return <div>...</div>;
}
App Routerを使用してローカルで開発する場合、next dev
ではnext start
での本番環境と同じキャッシュ動作が表示されるようになります。これにより、Server Componentやデータロードコードが変更された際のFast Refreshの速度が向上します。
Next.jsキャッシュでは、サードパーティAPIではなく、アプリケーションがキャッシュを制御します。これは、アップストリームが値のキャッシュ期間を制御するcache-control
ヘッダーとは異なります。
Vercel Cache APIとのNext.jsキャッシュ
Vercel上のNext.jsは、フレームワークによって定義されたインフラストラクチャを提供します。fetch
によるコンポーネントレベルのデータフェッチのようなアプリケーションコードを記述するだけで、追加の労力なしにグローバルに分散されたインフラストラクチャを構築します。
新しいNext.jsキャッシュにより、コードの変更とデータの変更が独立します。これにより、既存のキャッシュを使用してページの生成ができるため、静的ページの再デプロイが劇的に高速化されます。
この新しいVercel Cache APIは、あらゆるフレームワークで動作するように設計されていますが、Next.jsキャッシュとのネイティブ統合が実現しています。ISRがNext.jsキャッシュにどのように進化したか、およびVercelにデプロイする際のNext.jsキャッシュの動作について詳しく学ぶ。
セルフホスト時のNext.jsキャッシュ
セルフホストの場合、デフォルトで50MBのLRUキャッシュが使用されます。キャッシュへのすべてのエントリは、デフォルトで自動的にディスクに書き込まれます。このファイルシステムキャッシュは、今日のISRの動作と同様に、同じキャッシュキーを持つノード間で共有できます。
Next.jsキャッシュのコアをさらにカスタマイズおよび変更したい開発者は、基盤となるキャッシュキーを変更したり、キャッシュエントリがどのように、どこに永続化されるかを変更したりできます。永続化を完全に無効にすることも可能です。
その他の改善
- フォント: コミュニティで素晴らしい採用実績を挙げたため、
@next/font
はnext/font
としてNext.jsに組み込まれました。これにより、@next/font
を別途インストールする必要がなくなります。詳細を見る。 - フォント: コミュニティからのフィードバックに基づき、
next/font
のデフォルトのfont-display
プロパティがoptional
からfont-display: swap
に変更されました。 - パフォーマンス: ビルドプロセスを最適化し、使用メモリを削減しました。テストでは約550MBの節約になりました (PR)。
- パフォーマンス: プロジェクト構成の複数回読み込みを回避し、テストでは平均約400msのビルド高速化につながりました (PR)。
- パフォーマンス: エラーコンポーネントを最適化し、スタイリングを変更せずにHTMLペイロードを0.4kb削減しました (PR)。
- パフォーマンス: エッジバンドルサイズを約130KB削減し、ほぼ半分のサイズにして、Vercelのようなエッジ環境にデプロイする際のコールドブートサイズをさらに減少させました (PR)。
- セキュリティ: Image Optimization APIを直接訪れた際に画像を強制ダウンロードさせるための設定
images.contentDispositionType: "attachment"
を追加しました (PR)。
コミュニティ
Next.jsは、2,500人以上の個人開発者、GoogleやMetaなどの業界パートナー、そしてVercelのコアチームの共同作業の成果です。週に390万回以上のnpmダウンロードと10万以上のGitHubスターを獲得し、Next.jsはWebを構築するための最も人気のある方法の1つです。
GitHub Discussions、Reddit、Discordでコミュニティに参加しましょう。
このリリースは以下の方々によって提供されました:
- Next.jsチーム: Balazs, Hannes, Jan, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, Wyatt, and Andrew。
- Turbopackチーム: Alex, Donny, Justin, Leah, LongYinan, Maia, OJ, Tobias, and Will。
および、以下の貢献者の方々: @timneutkens, @loettz, @okcoker, @clive-h-townsend, @shuding, @JanKaifer, @sepiropht, @hanneslund, @huozhi, @aralroca, @balazsorban44, @cristobaldominguez95, @vinaykulk621, @Brooooooklyn, @feedthejim, @samsisle, @MarDi66, @styfle, @therealrinku, @sebmarkbage, @cravend, @hu0p, @kdy1, @ijjk, @juzhiyuan, @IvanKiral, @LukeSchlangen, @wojtekolek, @samdenty, @Josehower, @bennettdams, @SCG82, @mike-plummer, @kwonoj, @David0z, @denchance, @joulev, @wbinnssmith, @alexkirsz, @UnknownMonk, @leerob, @sairajchouhan, @imranbarbhuiya, @jomeswang, @ductnn, @thomasballinger, @chibicode, @jridgewell, @sreetamdas, @Juneezee, @SukkaW, @wyattjoh, @michaeloliverx, @cattmote, @joefreeman, @valentincostam, @qrohlf, @ossan-engineer, @rishabhpoddar, @vasucp1207, @Schniz, @andrii-bodnar, @gergelyke, @abstractvector, @wherehows, @BrodaNoel, @taep96, @abe1272001, @0xadada, @nbouvrette, @teobler, @lubakravche, @molebox, and @hiddenest。