コンテンツにスキップ
ブログに戻る

2022年10月25日(火)

Next.js 13

投稿者

私たちがNext.js Confで発表したように、Next.js 13(安定版)は、限界のないダイナミックな機能を実現するための基盤を築きます。

Next.js 13とpagesディレクトリは安定しており、本番環境で使用できます。今すぐアップデートするには、以下を実行してください。

ターミナル
npm i next@latest react@latest react-dom@latest eslint-config-next@latest

新しいappディレクトリ(ベータ版)

本日、Next.jsにおけるルーティングとレイアウトの体験を向上させ、Reactの未来に沿ってappディレクトリを導入します。これは、コミュニティのフィードバックのために以前公開されたLayouts RFCのフォローアップです。

appディレクトリは現在ベータ版であり、本番環境での使用はまだ推奨しません。Next.js 13では、改善されたnext/imagenext/linkコンポーネントなどの安定した機能を持つpagesディレクトリを使用でき、必要に応じてappディレクトリをオプトインできます。pagesディレクトリは、今後もサポートされます。

appディレクトリは以下をサポートしています。

  • レイアウト: ルート間でUIを簡単に共有し、状態を維持しながら高コストな再レンダリングを回避します。
  • サーバーコンポーネント: 最もダイナミックなアプリケーションのデフォルトとしてサーバーファーストを実現します。
  • ストリーミング: 即時ローディング状態を表示し、レンダリングされるUIの単位をストリームします。
  • データ取得のサポート: asyncサーバーコンポーネントと拡張されたfetch APIにより、コンポーネントレベルでの取得が可能になります。
The app directory can be incrementally adopted from your existing pages/ directory.
appディレクトリは、既存のpages/ディレクトリから段階的に採用できます。

レイアウト

app/ディレクトリを使用すると、状態をナビゲーション間で維持し、高コストな再レンダリングを回避し、高度なルーティングパターンを可能にする複雑なインターフェースを簡単にレイアウトできます。さらに、レイアウトをネストしたり、コンポーネント、テスト、スタイルなどのアプリケーションコードをルートにコロケートしたりできます。

The app/ directory can be incrementally adopted from your existing pages/ directory.
app/ディレクトリは、既存のpages/ディレクトリから段階的に採用できます。

app/内にルートを作成するには、単一のファイル、page.jsが必要です。

app/page.js
// This file maps to the index route (/)
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

次に、ファイルシステムを通じてレイアウトを定義できます。レイアウトは複数のページ間でUIを共有します。ナビゲーション時、レイアウトは状態を維持し、インタラクティブなままで、再レンダリングされません。

app/blog/layout.js
export default function BlogLayout({ children }) {
  return <section>{children}</section>;
}

レイアウトとページの詳細はこちら、または例をデプロイして試してみてください

サーバーコンポーネント

app/ディレクトリは、Reactの新しいサーバーコンポーネントアーキテクチャのサポートを導入します。サーバーコンポーネントとクライアントコンポーネントは、サーバーとクライアントそれぞれが得意なことを利用します。これにより、優れた開発者体験を提供する単一のプログラミングモデルで、高速で高インタラクティブなアプリを構築できます。

サーバーコンポーネントにより、複雑なインターフェースを構築するための基盤を築き、クライアントに送信されるJavaScriptの量を削減し、高速な初期ページロードを可能にします。

ルートがロードされると、Next.jsとReactのランタイムがロードされます。これはキャッシュ可能で、サイズも予測可能です。このランタイムは、アプリケーションが大きくなってもサイズが増加することはありません。さらに、ランタイムは非同期でロードされるため、サーバーからのHTMLはクライアントで段階的に拡張できます。

サーバーコンポーネントの詳細はこちら、または例をデプロイして試してみてください

ストリーミング

app/ディレクトリは、UIのレンダリングされた単位を段階的にレンダリングし、クライアントにストリーム配信する機能をもたらします。

Next.jsのサーバーコンポーネントとネストされたレイアウトにより、データが特に必要ないページのパーツを即座にレンダリングし、データ取得中のページのパーツにはローディング状態を表示できます。このアプローチにより、ユーザーはページ全体がロードされるのを待つことなく、操作を開始できます。

You can colocate your application code, such as components, tests, and styles, with your routes.
コンポーネント、テスト、スタイルなどのアプリケーションコードをルートにコロケートできます。

Vercelにデプロイすると、app/ディレクトリを使用するNext.js 13アプリケーションは、パフォーマンス向上のために、Node.jsとEdgeの両方のランタイムでデフォルトでレスポンスをストリーミングします。

ストリーミングの詳細はこちら、または例をデプロイして試してみてください

Data Fetching

Reactの最近のPromises RFCのファーストクラスサポートは、コンポーネント内での強力な新しいデータ取得とPromiseの処理方法を導入します。

app/page.js
async function getData() {
  const res = await fetch('https://api.example.com/...');
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  return res.json();
}
 
// This is an async Server Component
export default async function Page() {
  const data = await getData();
 
  return <main>{/* ... */}</main>;
}

ネイティブのfetch Web APIも、ReactとNext.jsで拡張されました。これはfetchリクエストを自動的に重複排除し、コンポーネントレベルでのデータ取得、キャッシュ、再検証のための単一の柔軟な方法を提供します。これは、静的サイト生成(SSG)、サーバーサイドレンダリング(SSR)、およびインクリメンタル静的再生成(ISR)のすべてのメリットが、1つのAPIで利用可能になったことを意味します。

// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
fetch(URL, { cache: 'force-cache' });
 
// This request should be refetched on every request.
// Similar to `getServerSideProps`.
fetch(URL, { cache: 'no-store' });
 
// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
fetch(URL, { next: { revalidate: 10 } });

appディレクトリでは、レイアウト、ページ、およびコンポーネント内でデータ取得を行うことができ、サーバーからのストリーミングレスポンスのサポートも含まれます。

ローディング状態とエラー状態を処理し、UIがレンダリングされるにつれてストリーム配信するための人間工学に基づいた方法を可能にしています。将来のリリースでは、データミューテーションも改善・簡素化する予定です。

With the app/ directory, you can use a new special file loading.js to automatically create Instant Loading UI with Suspense boundaries.
app/ディレクトリを使用すると、新しい特別なファイル`loading.js`を使用して、Suspense境界で即時ローディングUIを自動的に作成できます。

Reactエコシステムに貢献しているオープンソースコミュニティ、パッケージメンテナー、その他の企業と協力して、ReactとNext.jsのこの新しい時代を築いていくことを楽しみにしています。データ取得をコンポーネント内にコロケートし、クライアントに送信するJavaScriptを削減できることは、app/ディレクトリに含めることができたコミュニティからの2つの重要なフィードバックでした。

データ取得の詳細はこちら、または例をデプロイして試してみてください

Turbopack(アルファ版)の紹介

Next.js 13には、Webpackの新しいRustベースの後継であるTurbopackが含まれています。

Webpackは30億回以上ダウンロードされています。Webの構築に不可欠なツールでしたが、JavaScriptベースのツールで可能なパフォーマンスの限界に達しました。

Next.js 12では、ネイティブRust搭載ツールの移行を開始しました。Babelからの移行から始め、トランスパイル速度が17倍向上しました。次にTerserを置き換え、ミニファイ速度が6倍向上しました。バンドルにネイティブを全面的に採用する時が来ました。

Turbopackアルファ版をNext.js 13で使用すると、以下のようになります。

  • Webpackより700倍高速な更新
  • Viteより10倍高速な更新
  • Webpackより4倍高速なコールドスタート
Turbopack is our Rust-based successor to Webpack, with 700x faster HMR for large applications.
TurbopackはWebpackのRustベースの後継であり、大規模アプリケーションでは700倍高速なHMRを実現します。

Turbopackは開発に必要な最小限のアセットのみをバンドルするため、起動時間は非常に高速です。3,000モジュールのアプリケーションでは、Turbopackの起動時間は1.8秒です。Viteは11.4秒Webpackは16.5秒かかります。

Turbopackは、サーバーコンポーネント、TypeScript、JSX、CSSなどを標準でサポートしています。アルファ版では、多くの機能はまだサポートされていません。ローカルでのイテレーションを高速化するためにTurbopackを使用することについて、皆様からのフィードバックをお待ちしています。

注意:Next.jsのTurbopackは現在next devのみをサポートしています。サポートされている機能をご確認ください。また、Turbopackによるnext buildのサポートも追加中です。

Next.js 13でTurbopackアルファ版をnext dev --turboで試してみてください。

next/image

Next.js 13は、強力な新しい画像コンポーネントを導入し、レイアウトシフトなしで画像を簡単に表示し、オンデマンドでファイルを最適化してパフォーマンスを向上させることができます。

Next.jsコミュニティ調査では、回答者の70%が本番環境でNext.js画像コンポーネントを使用しており、その結果Core Web Vitalsが改善されたと答えています。Next.js 13では、next/imageをさらに改善します。

新しい画像コンポーネント

  • クライアントサイドJavaScriptの量が少なくなります。
  • スタイリングと設定が容易になります。
  • altタグをデフォルトで要求するため、よりアクセシブルになります。
  • Webプラットフォームに準拠します。
  • ネイティブの遅延読み込みはハイドレーションを必要としないため、より高速です。
app/page.js
import Image from 'next/image';
import avatar from './lee.png';
 
export default function Home() {
  // "alt" is now required for improved accessibility
  // optional: image files can be colocated inside the app/ directory
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

画像コンポーネントの詳細はこちら、または例をデプロイして試してみてください

Next.js 13でのnext/imageのアップグレード

古い画像コンポーネントはnext/legacy/imageにリネームされました。既存のnext/imageの使用法をnext/legacy/imageに自動的に更新するcodemodを提供しています。例えば、ルートから実行した場合、このコマンドは./pagesディレクトリでcodemodを実行します。

ターミナル
npx @next/codemod next-image-to-legacy-image ./pages

codemodの詳細はこちら.

@next/font

Next.js 13は、全く新しいフォントシステムを導入しました。

  • カスタムフォントを含むフォントを自動的に最適化します。
  • プライバシーとパフォーマンス向上のために、外部ネットワークリクエストを削除します。
  • あらゆるフォントファイルを自動的に自己ホストします。
  • CSSのsize-adjustプロパティを使用して、レイアウトシフトを自動的にゼロにします。

この新しいフォントシステムにより、Google Fontsのすべてをパフォーマンスとプライバシーを念頭に置いて便利に使用できます。CSSとフォントファイルはビルド時にダウンロードされ、他の静的アセットと共に自己ホストされます。ブラウザからGoogleへのリクエストは送信されません。

app/layout.js / pages/_app.js
import { Inter } from '@next/font/google';
 
const inter = Inter();
 
<html className={inter.className}></html>;

カスタムフォントもサポートされており、フォントファイルの自動自己ホスト、キャッシュ、プリロードもサポートしています。

app/layout.js / pages/_app.js
import localFont from '@next/font/local';
 
const myFont = localFont({ src: './my-font.woff2' });
 
<html className={myFont.className}></html>;

パフォーマンスを損なわず、レイアウトシフトをゼロに保ちながら、font-display、プリロード、フォールバックなど、フォント読み込み体験のすべての部分をカスタマイズできます。

新しいフォントコンポーネントの詳細はこちら、または例をデプロイして試してみてください

next/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>`
<Link href="/about">
  About
</Link>

改善されたLinkコンポーネントの詳細はこちら、または例をデプロイして試してみてください

Next.js 13にリンクをアップグレードするには、コードベースを自動的に更新するcodemodを提供しています。例えば、ルートから実行した場合、このコマンドは./pagesディレクトリでcodemodを実行します。

ターミナル
npx @next/codemod new-link ./pages

codemodの詳細はこちら、またはドキュメントをご覧ください。

OG画像生成

ソーシャルカード、またはオープングラフ画像は、コンテンツへのクリックエンゲージメント率を大幅に向上させることができ、一部の実験ではコンバージョン率が40%向上するという結果も出ています。

静的なソーシャルカードは時間がかかり、エラーが発生しやすく、維持が困難です。そのため、ソーシャルカードはしばしば欠けていたり、スキップされたりします。本日まで、パーソナライズされ、オンザフライで計算する必要のある動的なソーシャルカードは、困難でコストがかかるものでした。

Next.jsとシームレスに連携し、動的なソーシャルカードを生成する新しいライブラリ@vercel/ogを作成しました。

pages/api/og.jsx
import { ImageResponse } from '@vercel/og';
 
export const config = {
  runtime: 'experimental-edge',
};
 
export default function () {
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
        }}
      >
        Hello, World!
      </div>
    ),
  );
}

このアプローチは、Vercel Edge Functions、WebAssembly、およびHTMLとCSSを画像に変換するための全く新しいコアライブラリを使用し、Reactコンポーネント抽象化を活用することで、既存のソリューションよりも5倍高速です。

OG画像生成の詳細はこちら、または例をデプロイして試してみてください

Middleware APIの更新

Next.js 12では、Next.jsルーターによる完全な柔軟性を実現するためにMiddlewareを導入しました。初期API設計に関するフィードバックを受け、開発者体験の向上と強力な新機能の追加のためにいくつかの機能を追加しました。

リクエストにヘッダーをより簡単に設定できるようになりました。

middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
 
export function middleware(request: NextRequest) {
  // Clone the request headers and set a new header `x-version`
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13');
 
  // You can also set request headers in NextResponse.rewrite
  const response = NextResponse.next({
    request: {
      // New request headers
      headers: requestHeaders,
    },
  });
 
  // Set a new response header `x-version`
  response.headers.set('x-version', '13');
  return response;
}

Middlewareから、rewriteredirectを必要とせずに、直接レスポンスを提供できるようになりました。

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';
 
// Limit the middleware to paths starting with `/api/`
export const config = {
  matcher: '/api/:function*',
};
 
export function middleware(request: NextRequest) {
  // Call our authentication function to check the request
  if (!isAuthenticated(request)) {
    // Respond with JSON indicating an error message
    return NextResponse.json(
      {
        success: false,
        message: 'Auth failed',
      },
      {
        status: 401,
      },
    );
  }
}

Middlewareからのレスポンス送信には、現在next.config.js内のexperimental.allowMiddlewareResponseBody設定オプションが必要です。

破壊的変更

  • 最小Reactバージョンが17.0.2から18.2.0に引き上げられました。
  • 最小Node.jsバージョンが12.22.0から14.6.0に引き上げられました(12.xはEOLに達したため)。(PR).
  • swcMinify設定プロパティがfalseからtrueに変更されました。詳細については、Next.js Compilerを参照してください。
  • next/imageのインポートがnext/legacy/imageにリネームされました。next/future/imageのインポートがnext/imageにリネームされました。codemodが利用可能で、インポートを安全かつ自動的にリネームできます。
  • next/linkの子は<a>ではなくなりました。レガシー動作を使用するにはlegacyBehaviorプロップを追加するか、<a>を削除してアップグレードしてください。codemodが利用可能で、コードを自動的にアップグレードします。
  • User-Agentがボットの場合、ルートのプリフェッチは行われなくなりました。
  • next.config.jsの非推奨になったtargetオプションが削除されました。
  • サポートされているブラウザが変更され、Internet Explorerが除外され、モダンブラウザが対象になりました。ターゲットブラウザは引き続きBrowserslistで変更できます。
    • Chrome 64+
    • Edge 79+
    • Firefox 67+
    • Opera 51+
    • Safari 12+

詳細については、アップグレードガイドをご覧ください。

コミュニティ

6年前、私たちはNext.jsを公開しました。ゼロコンフィギュレーションのReactフレームワークを構築し、開発者体験を簡素化することを目指しました。振り返ってみると、コミュニティがどのように成長し、共に何をリリースできたかを見るのは素晴らしいことです。これからも進み続けましょう。

Next.jsは、2,400人以上の個々の開発者、GoogleやMetaのような業界パートナー、そして私たちのコアチームの共同作業の結果です。週に300万以上のnpmダウンロードと94,000のGitHubスターを持つNext.jsは、Webを構築する最も人気のある方法の1つです。

このリリースにつながった基盤研究と実験に協力してくれたGoogle ChromeのAuroraチームに特に感謝します。

このリリースは、@ijjk、@huozhi、@HaNdTriX、@iKethavel、@timneutkens、@shuding、@rishabhpoddar、@hanneslund、@balazsorban44、@devknoll、@anthonyshew、@TomerAberbach、@philippbosch、@styfle、@mauriciomutte、@hayitsdavid、@abdennor、@Kikobeats、@cjdunteman、@Mr-Afonso、@kdy1、@jaril、@abdallah-nour、@North15、@feedthejim、@brunocrosier、@Schniz、@sedlukha、@hashlash、@Ethan-Arrowood、@fireairforce、@migueloller、@leerob、@janicklas-ralph、@Trystanr、@atilafassina、@nramkissoon、@kasperadk、@valcosmos、@henriqueholtz、@nip10、@jesstelford、@lorensr、@AviAvinav、@SukkaW、@jaycedotbin、@saurabhburade、@notrab、@kwonoj、@sanruiz、@angeloashmore、@falsepopsky、@fmontes、@Gebov、@UltiRequiem、@p13lgst、@Simek、@mrkldshv、@thomasballinger、@kyliau、@AdarshKonchady、@endymion1818、@pedro757、@perkinsjr、@gnoff、@jridgewell、@silvioprog、@mabels、@nialexsan、@feugy、@jackromo888、@crazyurus、@EarlGeorge、@MariaSolOs、@lforst、@maximbaz、@maxam2017、@teobler、@Nutlope、@sunwoo0706、@WestonThayer、@Brooooooklyn、@Nsttt、@charlypoly、@aprendendofelipe、@sviridoff、@jackton1、@nuta、@Rpaudel379、@marcialca、@MarDi66、@ismaelrumzan、@javivelasco、@eltociear、および@hiro0218による貢献によってもたらされました。