🚀

Next.js 13.4まとめ

2023/05/05に公開

基本的には以下のNext.js 13.4のブログを翻訳してまとめたものになります。
https://nextjs.org/blog/next-13-4

TL;DR

  • Appルーター(安定版):
    • サーバーコンポーネント
    • ネストされたルート&レイアウト
    • 簡略化されたデータ取得
    • ストリーミング&サスペンス
    • ビルトインSEO対応
  • Turbopack(ベータ版): より速く、安定性が改善されたローカル開発サーバー
  • サーバーアクション(アルファ版): ゼロクライアントJavaScriptでサーバーのデータを更新

半年前にNext.js 13でベータ版としてAppルーターがリリースされましたが、今回ついに安定版となりました(開発スピードが速すぎる…)。

アップデート詳細

Next.js Appルーター

今回のアップデートでは特に新機能の追加はありませんが、安定版となりました。

しかし、Appルーターは2016年にNext.jsをリリースして以来の新時代の始まりを告げる、エポックメイキングな機能であるようで、当時から変わらない以下の4つのNext.jsの設計思想がAppルーター以前と以後でどのように実装されているかについて紹介されています。

  • ゼロセットアップ。APIとしてファイルシステムを使用
  • JavaScriptのみ。全てが関数
  • 全自動のサーバーレンダリングとコード分割
  • データ取得は開発者次第

興味のある方はぜひ原文を読んでみてください。
https://nextjs.org/blog/next-13-4#nextjs-app-router

また、Appルーターのドキュメントも安定版となり、ドキュメントが一新され、AppルーターとPagesディレクトリを切り替えられるようになっています(デフォルトはAppルーター)。
https://nextjs.org/docs

Turbopack(ベータ版)

今回のアップデートでは特に新機能の追加はありませんが、ベータ版となりました。

現状では開発環境でのみ使用できます(next dev --turbo)が、将来のNext.jsのバージョンでは本番環境でも使用できるようになる(next build --turbo)予定のようです。

https://nextjs.org/docs/architecture/turbopack

サーバーアクション(アルファ版)

Reactエコシステムでは、フォームやフォームの状態の管理、データのキャッシュと再検証に関するアイデアについて多くのイノベーションと探求がされてきました。時間が経つにつれて、Reactはこれらのパターンのいくつかについてより意見を持つようになりました。例えば、フォームの状態については「非制御コンポーネント」を推奨しています。

現在のエコシステムの解決策は再利用可能なクライアントサイドの解決策か、フレームワークに組み込まれたプリミティブのどちらかでした。今まで、サーバーミューテーションとデータプリミティブを合成する方法はありませんでした。Reactチームはミューテーションのためのファーストパーティの解決策に取り組んでいるところです

中間のAPI層を作成することなく直接関数を呼び出して、サーバーのデータの更新を可能にする、実験的なNext.jsのサーバーアクションが登場しました。

app/post/[id]/page.tsx
import kv from './kv';

export default function Page({ params }) {
  async function increment() {
    'use server';
    await kv.incr(`post:id:${params.id}`);
  }

  return (
    <form action={increment}>
      <button type="submit">Like</button>
    </form>
  );
}

サーバーアクションを使用することで、クライアントサイドのJavaScriptを削減し、フォームを段階的に改良できる、強力なサーバーファーストなデータ更新が可能になります。

app/dashboard/posts/page.tsx
import db from './db';
import { redirect } from 'next/navigation';

async function create(formData: FormData) {
  'use server';
  const post = await db.post.insert({
    title: formData.get('title'),
    content: formData.get('content'),
  });
  redirect(`/blog/${post.slug}`);
}

export default function Page() {
  return (
    <form action={create}>
      <input type="text" name="title" />
      <textarea name="content" />
      <button type="submit">Submit</button>
    </form>
  );
}

Next.jsのサーバーアクションは、Next.js Cacheや定期的な静的再生成(ISR)、クライアントルーターといった、データライフサイクルの他の部分と深く統合されるように設計されています。

revalidatePathrevalidateTagの新しいAPIを使用したデータの再検証は、更新やページの再レンダリング、リダイレクトを1回のネットワークラウンドトリップで行うことができ、たとえ上流のプロバイダーが遅い場合でも、正しいデータがクライアントに表示されることを保証します。

app/dashboard/posts/page.tsx
import db from './db';
import { revalidateTag } from 'next/server';

async function update(formData: FormData) {
  'use server';
  await db.post.update({
    title: formData.get('title'),
  });
  revalidateTag('posts');
}

export default async function Page() {
  const res = await fetch('https://...', { next: { tags: ['posts'] } });
  const data = await res.json();
  // ...
}

サーバーアクションは組み合わせできるように設計されています。Reactコミュニティの誰もがサーバーアクションを構築・公開して、エコシステムにそれらを配布することができます。サーバーコンポーネントと同様に、クライアントとサーバーの両方がプリミティブで組み合わせできる新時代になります。

サーバーアクションはNext.js 13.4でアルファ版の使用が可能です。以下のように設定してサーバーアクションの使用をオプトインすることで、Next.jsはReactの実験的なリリースチャンネルを使用するようになります。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverActions: true,
  },
};

module.exports = nextConfig;

https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions

その他の改善

  • 下書きモード: ヘッドレスCMSからの下書きコンテンツを取得してレンダリングできます。下書きモードはpagesappの両方で動作します。既存のプレビューモードAPIを改良して簡略化し、引き続きpagesでも動作します。プレビューモードはappでは動作しないので、下書きモードを使用してください

Discussion