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

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でのルーティングとレイアウトの体験を改善し、app ディレクトリの導入によりReactの未来に合わせます。これは、以前コミュニティからのフィードバックのために公開されたLayouts RFCに続くものです。

app ディレクトリは現在ベータ版であり、まだ本番環境での使用は推奨しません。Next.js 13をpages ディレクトリで使用し、改善されたnext/imagenext/linkコンポーネントなどの安定した機能を利用できます。app ディレクトリへの移行はご自身のペースで行ってください。pages ディレクトリは今後もサポートされ続けます。

app ディレクトリは以下の機能をサポートします。

  • レイアウト: 状態を維持し、コストのかかる再レンダリングを回避しながら、UIをルーティング間で簡単に共有できます。
  • Server Components: 最も動的なアプリケーションのために、サーバーファーストをデフォルトにします。
  • ストリーミング: 即座にローディング状態を表示し、UIの各単位がレンダリングされるにつれてストリームで表示します。
  • データフェッチのサポート: async Server Componentsと拡張された 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>;
}

レイアウトとページの詳細を見る、または例をデプロイして試す

Server Components

app/ ディレクトリは、Reactの新しいServer Componentsアーキテクチャのサポートを導入します。Server ComponentsとClient Componentsは、それぞれが最も得意な分野でサーバーとクライアントを利用し、優れた開発者エクスペリエンスを提供する単一のプログラミングモデルで高速かつ高度にインタラクティブなアプリを構築できます。

Server Componentsを使用することで、複雑なインターフェースを構築しながらクライアントに送信されるJavaScriptの量を削減し、初回ページロードを高速化する基盤を築いています。

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

Server Componentsの詳細を見る、または例をデプロイして試す

ストリーミング

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

Next.jsのServer Componentsとネストされたレイアウトを使用すると、データが特に必要ないページの一部を即座にレンダリングし、データをフェッチしているページの一部にはローディング状態を表示できます。このアプローチにより、ユーザーはページ全体がロードされるのを待つことなく、操作を開始できます。

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

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

ストリーミングの詳細を見る、または例をデプロイして試す

データフェッチ

Reactの最近のPromiseサポート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で拡張されました。これにより、フェッチリクエストが自動的に重複排除され、コンポーネントレベルでデータをフェッチ、キャッシュ、再検証するための**単一の**柔軟な方法が提供されます。これは、Static Site Generation (SSG)、Server-Side Rendering (SSR)、Incremental Static Regeneration (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倍高速化しました。今こそ、バンドルにネイティブツールを全面的に導入する時です。

Next.js 13でTurbopackアルファ版を使用すると、次の結果が得られます。

  • 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は、Server Components、TypeScript、JSX、CSSなどをすぐにサポートします。アルファ版では、まだ多くの機能がサポートされていません。Turbopackを使用してローカルの反復作業を高速化することについて、皆様からのフィードバックをお待ちしております。

注: Next.jsのTurbopackは現在、next devのみをサポートしています。サポートされている機能を表示します。next buildのTurbopackによるサポートも追加する予定です。

本日、Next.js 13でnext dev --turboを使ってTurbopackアルファ版をお試しください。

next/image

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

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

新しい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" />;
}

Imageコンポーネントの詳細を見る、または例をデプロイして試す

next/imageをNext.js 13にアップグレードする

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

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

コードモッドの詳細を見る.

@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、プリロード、フォールバックなどを含め、優れたパフォーマンスとレイアウトシフトなしを保証しながら、フォントの読み込み体験のあらゆる部分をカスタマイズできます。

新しいFontコンポーネントの詳細を見る、または例をデプロイして試す

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にアップグレードするために、コードベースを自動的に更新するコードモッドを提供しています。例えば、ルートから実行すると、このコマンドは./pagesディレクトリでコードモッドを実行します。

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

コードモッドの詳細を見るか、ドキュメントを確認してください。

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はすでにサポート終了(PR)に達しているためです。
  • swcMinify 設定プロパティがfalseからtrueに変更されました。詳細についてはNext.js Compilerを参照してください。
  • next/imageのインポートはnext/legacy/imageに名称変更されました。next/future/imageのインポートはnext/imageに名称変更されました。コードモッドが利用可能で、安全かつ自動的にインポート名を変更できます。
  • next/linkの子に<a>を使用することはできなくなりました。従来の動作を使用するにはlegacyBehaviorプロパティを追加するか、アップグレードのために<a>を削除してください。コードを自動的にアップグレードするためのコードモッドが利用可能です。
  • 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, and @hiro0218。