2024年12月10日(火)
Next.js 15.1
投稿者Next.js 15.1では、コアアップグレード、新しいAPI、および開発者エクスペリエンスの改善が提供されます。主な更新内容は以下の通りです。
- React 19 (安定版): React 19のサポートが、Pages RouterとApp Routerの両方で正式に利用可能になりました。
- エラーデバッグの改善: ブラウザとターミナル向けに開発者エクスペリエンスが向上し、より優れたソースマップが提供されます。
after
(安定版): レスポンスのストリーミング完了後にコードを実行するための新しいAPI。forbidden
/unauthorized
(実験的): より詳細な認証エラー処理を可能にする新しいAPI。
今すぐアップグレードするか、以下から始めましょう
# Use the automated upgrade CLI
npx @next/codemod@canary upgrade latest
# ...or upgrade manually
npm install next@latest react@latest react-dom@latest
# ...or start a new project
npx create-next-app@latest
React 19 (安定版)
Next.js 15.1はReact 19を完全にサポートしました
- Pages Routerの場合: React 19の安定版が、Release CandidateやCanaryリリースなしで利用可能になり、React 18のサポートも継続されます。
- App Routerの場合: 引き続きReact Canaryリリースを内蔵して提供します。これには、React 19の安定版のすべての変更に加え、新しいReactリリースに先立ってフレームワークで検証されている最新機能が含まれます。
Next.js 15のリリース以降、React 19への重要な追加機能として「sibling pre-warming」が挙げられます。
React 19の更新点の包括的な概要については、公式のReact 19ブログ記事を参照してください。
エラーデバッグの改善
Next.jsのエラーデバッグが改善され、ターミナル、ブラウザ、接続されたデバッガのどこに問題が現れても、素早く原因を特定できるようになりました。これらの改善は、WebpackとTurbopackの両方に適用されます(Next.js 15で安定版になりました)。
ソースマップの強化
ソースマップの利用が改善されたことで、エラーの発生源をより簡単に追跡できるようになりました。Next.jsはソースマップのignoreList
プロパティを実装しました。これにより、Next.jsは外部依存関係のスタックフレームを非表示にし、アプリケーションコードに焦点を当てることができます。
メソッド名のソースマッピングをより正確にするには、Turbopack(現在安定版)の採用をお勧めします。Turbopackは、Webpackよりもソースマップの処理と検出が改善されています。
ライブラリ作者の方へ: ライブラリを公開する際には、特に外部として設定されている場合(例:
serverExternalPackages
設定内)、ソースマップのignoreList
プロパティに値を設定することを推奨します。
スタックフレームの折りたたみ
スタックフレームの折りたたみロジックを改善し、コードの最も関連性の高い部分を強調表示するようにしました。
- ブラウザおよびエラーオーバーレイ: サードパーティの依存関係からのスタックフレームはデフォルトで非表示になり、アプリケーションコードに焦点が当てられます。開発ツールまたはオーバーレイで「無視されたフレームを表示」をクリックすると、非表示のフレームを表示できます。
- ターミナル: サードパーティの依存関係のフレームもデフォルトで折りたたまれており、エラーの書式設定はブラウザの出力と一致するようになり、一貫したデバッグエクスペリエンスを提供します。開発中に完全なスタックトレースが必要な場合でも重要な情報を見逃さないよう、エラーはブラウザで再生されます。
プロファイリングの強化
無視されたスタックフレームは、ブラウザの内蔵プロファイラでも認識されます。これにより、外部ライブラリのノイズなしでコード内の遅い関数を特定でき、アプリケーションのプロファイリングが容易になります。
Edge Runtimeでの改善
Edgeランタイムを使用する場合、エラーは開発環境全体で一貫して表示されるようになり、シームレスなデバッグが保証されます。以前は、ログに記録されるエラーにはメッセージのみが含まれ、スタックは含まれていませんでした。
変更前と変更後
ターミナル 変更前
⨯ app/page.tsx (6:11) @ eval
⨯ Error: boom
at eval (./app/page.tsx:12:15)
at Page (./app/page.tsx:11:74)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at stringify (<anonymous>)
at AsyncLocalStorage.run (node:async_hooks:346:14)
at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
digest: "380744807"
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError()
GET / 500 in 2354ms
ターミナル 変更後
⨯ Error: boom
at eval (app/page.tsx:6:10)
at Page (app/page.tsx:5:32)
4 | export default function Page() {
5 | const throwError = myCallback(() => {
> 6 | throw new Error('boom')
| ^
7 | }, [])
8 |
9 | throwError() {
digest: '225828171'
}
エラーオーバーレイ 変更前

エラーオーバーレイ 変更後

これらの改善により、エラーがより明確で直感的になり、デバッグに時間を費やすのではなく、アプリケーションの構築に集中できるようになります。
また、今後のリリースでエラーオーバーレイのUIを再設計して導入することを発表できることを大変嬉しく思います。
after
(安定版)
after()
APIは、最初のNext.js 15 RCでの導入後、安定版となりました。
after()
は、プライマリレスポンスをブロックすることなく、ユーザーへのレスポンスストリーミングが完了した後に、ロギング、分析、その他のシステム同期などのタスクを実行する方法を提供します。
主な変更点
導入以来、after()
を安定させ、以下を含むフィードバックに対応しました。
- 自己ホスト型Next.jsサーバーのサポート改善。
after()
が他のNext.js機能と相互作用するシナリオでのバグ修正。- 拡張性の向上により、他のプラットフォームが独自の
waitUntil()
プリミティブを注入してafter()
を強化できるようになりました。 - Server ActionsおよびRoute Handlersにおける
cookies()
やheaders()
などのランタイムAPIのサポート。
import { after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Secondary task
after(() => {
log();
});
// Primary task
return <>{children}</>;
}
after
APIの詳細と、ドキュメントでの活用方法についてご覧ください。
forbidden
と unauthorized
(実験的)
Next.js 15.1には、コミュニティからのフィードバックに基づいて、2つの実験的なAPI、forbidden()
と unauthorized()
が含まれています。
皆様からのフィードバックをお待ちしております — 開発環境でお試しいただき、このディスカッションスレッドでご意見をお聞かせください。
概要
App Routerに慣れている方なら、カスタマイズ可能なnot-found.tsx
ファイルと合わせて、404動作をトリガーするためにnotFound()
を使用したことがあるでしょう。バージョン15.1では、このアプローチを認証エラーにも拡張します
• forbidden()
は、forbidden.tsx
を介してカスタマイズ可能なUIとともに403エラーをトリガーします。
• unauthorized()
は、unauthorized.tsx
を介してカスタマイズ可能なUIとともに401エラーをトリガーします。
注意:
notFound()
エラーと同様に、最初のレスポンスヘッダが送信された後にエラーがトリガーされた場合、ステータスコードは200
になります。詳細はこちら。
機能の有効化
この機能はまだ実験的なので、next.config.ts
ファイルで有効にする必要があります。
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
authInterrupts: true,
},
};
export default nextConfig;
注:
next.config.ts
のサポートはNext.js 15で導入されました。詳細はこちら。
forbidden()
と unauthorized()
の使用
forbidden()
とunauthorized()
は、Server Actions、Server Components、Client Components、またはRoute Handlersで使用できます。例を挙げます
import { verifySession } from '@/app/lib/dal';
import { forbidden } from 'next/navigation';
export default async function AdminPage() {
const session = await verifySession();
// Check if the user has the 'admin' role
if (session.role !== 'admin') {
forbidden();
}
// Render the admin page for authorized users
return <h1>Admin Page</h1>;
}
カスタムエラーページの作成
エラーページをカスタマイズするには、以下のファイルを作成します
import Link from 'next/link';
export default function Forbidden() {
return (
<div>
<h2>Forbidden</h2>
<p>You are not authorized to access this resource.</p>
<Link href="/">Return Home</Link>
</div>
);
}
import Link from 'next/link';
export default function Unauthorized() {
return (
<div>
<h2>Unauthorized</h2>
<p>Please log in to access this page.</p>
<Link href="/login">Go to Login</Link>
</div>
);
}
この機能をPRで提案し、APIのプロトタイプ作成を支援してくれたClerkに感謝いたします。バージョン15.2でこの機能を安定させる前に、より幅広いユースケースをサポートするために、APIにさらなる機能と改善を追加する予定です。
詳細については、unauthorized
APIおよびforbidden
APIのドキュメントを参照してください。
その他の変更
- [機能]
create-next-app
でESLint 9を使用 (PR) - [機能] キャッシュタグの最大数を128に増加 (PR)
- [機能] 実験的なCssChunkingPluginを無効にするオプションを追加 (PR)
- [機能] 実験的なCSSインラインサポートを追加 (PR)
- [改善] Sass
legacy-js-api
警告を抑制 (PR) - [改善] リライト使用時の未処理の拒否を修正 (PR)
- [改善] webpackワーカーが失敗した場合に親プロセスが終了するようにする (PR)
- [改善] キャッチオールルートでのルートインターセプトを修正 (PR)
- [改善] リクエストの重複排除におけるレスポンスのクローン作成の問題を修正 (PR)
- [改善] 複数のルートレイアウト間でのServer Actionリダイレクトを修正 (PR)
- [改善] Turbopack互換性のためにMDXプラグインを文字列として提供するサポートを追加 (PR)
貢献者
Next.jsは、3,000人以上の個人開発者の共同作業の成果です。このリリースは、以下の人々によって実現されました
- Next.jsチーム: Andrew, Hendrik, Janka, Jiachi, Jimmy, Jiwon, JJ, Josh, Jude, Sam, Sebastian, Sebbie, Wyatt, and Zack。
- Turbopackチーム: Alex, Benjamin, Donny, Maia, Niklas, Tim, Tobias, and Will。
- Next.js Docsチーム: Delba, Rich, Ismael, and Lee。
@sokra, @molebox, @delbaoliveira, @eps1lon, @wbinnssmith, @JamBalaya56562, @hyungjikim, @adrian-faustino, @mottox2, @lubieowoce, @bgw, @mknichel, @wyattjoh, @huozhi, @kdy1, @mischnic, @ijjk, @icyJoseph, @acdlite, @unstubbable, @gaojude, @devjiwonchoi, @cena-ko, @lforst, @devpla, @samcx, @styfle, @ztanner, @Marukome0743, @timneutkens, @JeremieDoctrine, @ductnn, @karlhorky, @reynaldichernando, @chogyejin, @y-yagi, @philparzer, @alfawal, @Rhynden, @arlyon, @MJez29, @Goodosky, @themattmayfield, @tobySolutions, @kevinmitch14, @leerob, @emmanuelgautier, @mrhrifat, @lid0a, @boar-is, @nisabmohd, @PapatMayuri, @ovogmap, @Reflex2468, @LioRael, @betterthanhajin, @HerringtonDarkholme, @bpb54321, @ahmoin, @Kikobeats, @abdelrahmanAbouelkheir, @lumirlumir, @yeeed711, @petter, @suu3 の皆様、ご協力ありがとうございました!