Next.js 15.1
投稿者: Janka Uryga @ lubieowoce、Jiachi Liu @ huozhi、Sebastian Silbermann @ sebsilbermann
Next.js 15.1では、コアアップグレード、新しいAPI、開発者体験の改善が提供されます。主要なアップデートには以下が含まれます:
- React 19 (stable): Pages RouterとApp Routerの両方でReact 19のサポートが正式に利用可能になりました。
- エラーデバッグの改善: 開発者体験の向上とブラウザ・ターミナル向けのより良いソースマップ。
- after (stable): レスポンスのストリーミングが完了した後にコードを実行する新しいAPI。
- forbidden / unauthorized (experimental): より細かい認証エラーハンドリングを可能にする新しいAPI。
今すぐアップグレードするか、以下で開始してください:
npx @next/codemod@canary upgrade latest
npm install next@latest react@latest react-dom@latest
npx create-next-app@latest
React 19 (stable)
Next.js 15.1では、React 19を完全にサポートしています:
- Pages Router: Release CandidateやCanaryリリースを必要とせずに、React 19 stableを使用できるようになりました。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で安定版)の両方に適用されます。
ソースマップの改善
ソースマップの改善された使用により、エラーの原因を追跡しやすくなりました。ソースマップのignoreListプロパティを実装し、Next.jsが外部依存関係のスタックフレームを非表示にして、アプリケーションコードを主要な焦点にできるようにしました。
メソッド名のより正確なソースマッピングのために、Turbopack(現在安定版)の採用をお勧めします。これは、Webpackよりもソースマップの処理と検出が改善されています。
ライブラリ作成者向け: ライブラリを公開する際、特に外部として設定されている場合(例:serverExternalPackages設定)は、ソースマップにignoreListプロパティを設定することをお勧めします。
折りたたまれたスタックフレーム
コードの最も関連性の高い部分を強調するために、スタックフレームを折りたたむロジックを改善しました。
- ブラウザとエラーオーバーレイ: サードパーティ依存関係のスタックフレームはデフォルトで非表示になり、アプリケーションコードに焦点を当てます。devtoolsまたはオーバーレイで「Show ignored frames」をクリックすることで、非表示のフレームを表示できます。
- ターミナル: サードパーティ依存関係のフレームもデフォルトで折りたたまれ、エラーフォーマットがブラウザ出力と一致して一貫したデバッグ体験を提供します。
開発中に重要な情報を見逃さないよう、完全なスタックトレースが必要な場合はエラーがブラウザで再生されます。
プロファイリングの改善
無視されたスタックフレームは、組み込みブラウザプロファイラーでも認識されます。これにより、外部ライブラリからのノイズなしに、コード内の遅い関数を特定してアプリケーションのプロファイリングが簡単になります。
Edge Runtimeでの改善
Edge runtimeを使用する際、エラーが開発環境全体で一貫して表示され、シームレスなデバッグが保証されます。以前は、ログに記録されたエラーにはメッセージのみが含まれ、スタックは含まれていませんでした。
Before and After
Before:
⨯ 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
After:
⨯ 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 (stable)
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 }) {
after(() => {
log();
});
return <>{children}</>;
}
after APIの詳細と活用方法については、ドキュメントをお読みください。
forbidden と unauthorized (experimental)
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();
if (session.role !== 'admin') {
forbidden();
}
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とforbidden APIのドキュメントをお読みください。
その他の変更
- [Feature] create-next-appでESLint 9を使用 (PR)
- [Feature] 最大キャッシュタグを128に増加 (PR)
- [Feature] 実験的CssChunkingPluginを無効にするオプションを追加 (PR)
- [Feature] 実験的CSSインライン化サポートを追加 (PR)
- [Improvement] Sass legacy-js-api警告を無音化 (PR)
- [Improvement] rewritesを使用する際の未処理拒否を修正 (PR)
- [Improvement] webpackワーカーが失敗した際の親プロセス終了を保証 (PR)
- [Improvement] catch-allルートでのルートインターセプションを修正 (PR)
- [Improvement] リクエスト重複排除でのレスポンスクローニング問題を修正 (PR)
- [Improvement] 複数のルートレイアウト間でのServer Actionリダイレクトを修正 (PR)
- [Improvement] Turbopack互換性のためのMDXプラグインの文字列提供をサポート (PR)
貢献者
Next.jsは3,000人以上の個人開発者の共同作業の結果です。このリリースは以下の方々によってもたらされました:
Next.jsチーム: Andrew、Hendrik、Janka、Jiachi、Jimmy、Jiwon、JJ、Josh、Jude、Sam、Sebastian、Sebbie、Wyatt、Zack
Turbopackチーム: Alex、Benjamin、Donny、Maia、Niklas、Tim、Tobias、Will
Next.js Docsチーム: Delba、Rich、Ismael、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の皆様に心から感謝します!