Next.js 13.3では、以下のようなコミュニティから要望の多かった機能が追加されました:
- ファイルベースのメタデータAPI:サイトマップ、robots.txt、ファビコンなどを動的に生成
- 動的Open Graph画像生成:JSX、HTML、CSSを使用してOG画像を生成
- App Routerの静的エクスポート:サーバーコンポーネントの静的/シングルページアプリケーション(SPA)サポート
- 並列ルートとインターセプション:App Router向けの高度なルーティング機能
以下のコマンドを実行して今日からアップデートできます:
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
次のマイナーリリースでApp Routerを安定版としてマークする準備を進めており、パフォーマンスの最適化、動作の改善、バグ修正に注力しています。
Mutationsなどのいくつかの機能についてはまだ作業中ですが、これらが他のApp Router機能のAPIサーフェスに影響を与えることはないと予想しています。App Routerで皆さんが何を構築するのか楽しみにしています。フィードバックをお待ちしています。
ファイルベースのメタデータAPI
Next.js 13.2では、レイアウトやページからMetadataオブジェクトをエクスポートすることでメタデータ(HTMLのhead
要素内のtitle
、meta
、link
タグなど)を定義できる新しいMetadata APIを発表しました。
// 静的メタデータ
export const metadata = {
title: 'Home',
};
// 出力:
// <head>
// <title>Home</title>
// </head>
// または動的メタデータ
export async function generateMetadata({ params, searchParams }) {
const product = await getProduct(params.id);
return { title: product.title };
}
// 出力:
// <head>
// <title>My Unique Product</title>
// </head>
export default function Page() {}
設定ベースのメタデータに加え、Metadata APIでは新しいファイル規約がサポートされ、SEOやウェブ上での共有を改善するためにページを便利にカスタマイズできるようになりました:
opengraph-image.(jpg|png|svg)
twitter-image.(jpg|png|svg)
favicon.ico
icon.(ico|jpg|png|svg)
sitemap.(xml|js|jsx|ts|tsx)
robots.(txt|js|jsx|ts|tsx)
manifest.(json|js|jsx|ts|tsx)
例えば、ファイルベースのメタデータを使用してアプリのファビコンや/about
ページのOpen Graph画像を追加できます:
app
├── favicon.ico
├── layout.js
├── page.js
└── about
├── opengraph-image.jpg
└── page.js
Next.jsは本番環境でこれらのファイルをハッシュ付き(ファイル名用)で自動的に提供し、アセットのURL、ファイルタイプ、画像サイズなどの正しいメタデータ情報で関連するhead
要素を更新します。
// "/"にアクセス時
<link rel="icon" href="<computedUrl>"/>
// "/about"にアクセス時
<link rel="icon" href="<computedUrl>"/>
<meta property="og:image" content="<computedUrl>" type="<computedType>" ... />
アプリケーションに静的ファイルを追加するのが最も簡単なアプローチですが、ファイルを動的に作成する必要がある場合もあります。各静的ファイル規約には、ファイルを生成するコードを記述できる動的な(.js|.jsx|.ts|.tsx)
バリアントが用意されています。
例えば、静的なsitemap.xml
ファイルを追加できますが、ほとんどのサイトには外部データソースを使用して動的に生成されるページがあります。動的なサイトマップを生成するには、動的ルートの配列を返すsitemap.js
ファイルを追加できます。
export default async function sitemap() {
const res = await fetch('https://.../posts');
const allPosts = await res.json();
const posts = allPosts.map((post) => ({
url: `https://acme.com/blog/${post.slug}`,
lastModified: post.publishedAt,
}));
const routes = ['', '/about', '/blog'].map((route) => ({
url: `https://acme.com${route}`,
lastModified: new Date().toISOString(),
}));
return [...routes, ...posts];
}
設定ベースと新しいファイルベースのオプションにより、静的および動的メタデータの両方をカバーする包括的なMetadata APIが利用可能になりました。
Metadata APIはApp Router(app
)で13.3から利用可能です。pages
ディレクトリでは利用できません。ファイルベースのメタデータとAPIリファレンスについて詳しく学ぶ。
動的Open Graph画像生成
6ヶ月前に、JSX、HTML、CSSを使用して画像を動的に生成できるライブラリ@vercel/ogとSatoriをリリースしました。
@vercel/og
はNext.js Confでテストされ、すべての参加者向けに10万枚以上の動的なチケット画像を生成しました。Vercelの顧客間での広範な採用とリリース以来90万回以上のダウンロードを経て、外部パッケージなしで全てのNext.jsアプリケーションに動的に生成された画像を提供できることを嬉しく思います。
next/server
からImageResponse
をインポートして画像を生成できるようになりました:
import { ImageResponse } from 'next/server';
export const size = { width: 1200, height: 600 };
export const alt = 'About Acme';
export const contentType = 'image/png';
export const runtime = 'edge';
export default function og() {
return new ImageResponse();
// ...
}
ImageResponse
は、Route HandlersやファイルベースのMetadataを含む他のNext.js APIと自然に統合されます。例えば、opengraph-image.tsx
ファイルでImageResponse
を使用して、ビルド時またはリクエスト時に動的にOpen GraphとTwitter画像を生成できます。
App Routerの静的エクスポート
Next.js App Routerで完全な静的エクスポートがサポートされました。
静的サイトまたはシングルページアプリケーション(SPA)として開始し、後で必要に応じてサーバーを必要とするNext.js機能を使用するようにアップグレードできます。
next build
を実行すると、Next.jsはルートごとにHTMLファイルを生成します。厳密なSPAを個別のHTMLファイルに分割することで、Next.jsはクライアントサイドで不要なJavaScriptコードの読み込みを回避し、バンドルサイズを削減してページの読み込みを高速化できます。
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
output: 'export',
};
module.exports = nextConfig;
静的エクスポートは、静的Route Handlers、Open Graph画像、Reactサーバーコンポーネントなど、app
ルーターの新機能と連携します。
例えば、サーバーコンポーネントはビルド中に実行され、従来の静的サイト生成と同様に、初期ページ読み込み用の静的HTMLとルート間のクライアントナビゲーション用の静的ペイロードにコンポーネントがレンダリングされます。
以前は、pages
ディレクトリで静的エクスポートを使用するにはnext export
を実行する必要がありました。しかし、next.config.js
オプションを使用すると、output: 'export'
が設定されている場合にnext build
がout
ディレクトリを出力します。app
ルーターとpages
ディレクトリに同じ設定を使用できます。これによりnext export
は不要になりました。
高度な静的エクスポートサポートにより、cookies()
やheaders()
などのサーバーを必要とする動的関数を使用しようとした場合など、開発プロセス(next dev
)の早い段階でエラーが表示されます。
並列ルートとインターセプション
Next.js 13.3では、高度なルーティングケースを実装できる新しい動的規約が導入されました:並列ルートとインターセプティングルート。これらの機能により、複雑なダッシュボードやモーダルのように、同じビューで複数のページを表示できます。
並列ルートを使用すると、独立してナビゲート可能な1つ以上のページを_同じビュー_で同時にレンダリングできます。また、条件付きでページをレンダリングするためにも使用できます。
並列ルートは**「スロット」**という名前で作成されます。スロットは@folder
規約で定義されます:
dashboard
├── @user
│ └── page.js
├── @team
│ └── page.js
├── layout.js
└── page.js
同じルートセグメント内のレイアウトは、スロットをプロップとして受け入れます:
export default async function Layout({ children, user, team }) {
const userType = getCurrentUserType();
return (
<>
{userType === 'user' ? user : team}
{children}
</>
);
}
上記の例では、@user
と@team
の並列ルートスロット(明示的)がロジックに基づいて条件付きでレンダリングされます。children
は@folder
にマップする必要のない暗黙的なルートスロットです。例えば、dashboard/page.js
はdashboard/@children/page.js
と同等です。
インターセプティングルートを使用すると、現在のレイアウト内で新しいルートを読み込みながら、ブラウザのURLを「マスク」できます。これは、フィード内の写真をモーダルで拡大表示する場合など、現在のページのコンテキストを保持することが重要な場合に便利です。
インターセプティングルートは、相対パス../
と同様の(..)
規約で定義できます。また、app
ディレクトリからの相対パスを作成するために(...)
規約も使用できます。
feed
├── @modal
│ └── (..)photo
│ └── [id]
│ └── page.tsx
├── page.tsx
└── layout.tsx
photo
└── [id]
└── page.tsx
上記の例では、ユーザーのプロフィールから写真をクリックすると、クライアントサイドナビゲーション中にモーダルで写真が開きます。しかし、ページを更新したり共有したりすると、デフォルトのレイアウトで写真が読み込まれます。
並列ルートとインターセプションにより、Instagramのようなモーダルルーティングが可能になります。
これにより、モーダルコンテンツをURLで共有可能にすること、ページが更新されたときにコンテキストが失われるのを防ぐこと、後方および前方ナビゲーションでモーダルを閉じて再度開くことなど、モーダル作成時の課題が解決されます。
その他の例や動作については、並列ルートとインターセプティングルートのドキュメントを参照してください。
その他の改善点
- デザインの更新: Next.jsのホームページとショーケースが新しいデザインでリフレッシュされました。
- Turbopack: ミドルウェアのサポート、すべての
next/font
オプション、ベータ版に近づくサーバーコンポーネントのストリーミングが追加されました(デモを参照)。また、vercel.comやnextjs.orgなどの成熟したNext.jsアプリで使用しながら発見された追加のバグも修正しました。詳細を学ぶ。 next.config.js
のFast Refresh:next.config.js
への変更がローカル開発サーバーを自動的に再起動するようになりました。これにより、.env
、.env.*
、jsconfig.json
、tsconfig.json
設定ファイルの自動リロードが拡張されます。- アクセシビリティ: App Routerに
pages
からのルートアナウンスが含まれるようになりました。この機能は、クライアントサイドのルート遷移をスクリーンリーダーやその他の支援技術に通知します。詳細を学ぶ。 - 静的に型付けされたリンク:
next.config.js
で設定されたredirects
とrewrites
が型チェック時に考慮されるようになりました。詳細を学ぶ。 create-next-app
のTailwind CSS:npx create-next-app@latest
で新しいプロジェクトを開始する際、Tailwind CSSをオプションで選択するか、--tailwind
フラグを使用して、このスタイリングソリューションでアプリケーションを事前設定できるようになりました。- Route Handlers: サポートされているHTTP動詞の代わりに
export default
を使用すると、route.ts
で役立つエラーがスローされるようになりました。Route Handlersについて詳しく学ぶ。 - 画像:
next/image
がfetchPriority="high"
属性をサポートするようになりました。 - メタデータ: 13.2で非推奨となった以前のメタデータAPI(
head.js
)が削除されました。代わりに、Metadata APIを通じたSEOの組み込みサポートを使用してください。 - ルーティングからフォルダを除外: フォルダ名の前に_を付けることで、そのフォルダと子セグメントをルーティングから除外できます。例えば、
app/_dashboard/page.tsx
はルーティング可能ではありません。 - App Router: 与えられたルートセグメントの動的パラメータを読み取るための新しい
useParams
クライアントコンポーネントフックが追加されました。詳細を学ぶ。 - スタイルシートの読み込みの改善: Next.jsはReactのSuspensey CSSを実装し、特にナビゲーション中のCSSの読み込みやスタイル未適用コンテンツのちらつきに関する多くの問題を修正しました。
- Not Found処理の改善: 予期される
notFound()
エラーをキャッチするだけでなく、ルートのapp/not-found.js
ファイルはアプリケーション全体でマッチしないURLも処理します。つまり、アプリで処理されないURLにアクセスしたユーザーには、app/not-found.js
ファイルからエクスポートされたUIが表示されます。詳細を学ぶ。 - クライアントサイドルーターキャッシュの改善:
router.refresh()
はキャッシュ全体を無効化し、検索パラメータがキャッシュキーの一部になりました。これにより、2つの検索パラメータ間(例:/?search=leerob
と/?search=tim
)をナビゲートすると、パラメータに依存するコンテンツが正しく復元されます。
コミュニティ
Next.jsは、2,600人以上の個人開発者、GoogleやMetaなどの業界パートナー、そしてVercelのコアチームの共同作業の結果です。週に420万回以上のnpmダウンロードと10万4千以上のGitHubスターを獲得しており、Next.jsはWebを構築する最も人気のある方法の1つです。
GitHub Discussions、Reddit、Discordでコミュニティに参加してください。
このリリースは以下の方々によってもたらされました:
- Next.jsチーム: Andrew, Balazs, Hannes, Jan, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, Wyatt.
- Turbopackチーム: Alex, Donny, Justin, Leah, LongYinan, Maia, OJ, Tobias, Will.
そして以下の方々の貢献: @shuding, @huozhi, @sokra, @hanneslund, @JesseKoldewijn, @kaguya3222, @yangshun, @ijjk, @konomae, @Brooooooklyn, @jridgewell, @zlrlyy, @JohnDaly, @abhiyandhakal, @benjie, @johnnyomair, @nk980113, @dirheimerb, @DerTimonius, @DuCanhGH, @padmaia, @stafyniaksacha, @Gladowar, @zek, @jankaifer, @styfle, @balazsorban44, @wbinnssmith, @chibicode, @ForsakenHarmony, @franktronics, @FSaldanha, @Schniz, @raisedadead, @AdamKatzDev, @wyattjoh, @leerob, @meesvandongen, @vladikoff, @feedthejim, @tka5, @pyjun01, @gdborton, @M3kH, @aretrace, @shivanshubisht, @alexkirsz, @agrattan0820, @vinaykulk621, @heyitsuzair, @mrkldshv, @timneutkens, @furkanmavili, @swaminator, @EndangeredMassa, @DevEsteves, @rishabhpoddar, @schehata, @molebox, @dlehmhus, @akshaynox, @sp00ls, @janicklas-ralph, @tomryanx, @kwonoj, @karlhorky, @kdy1, @dante-robinson, @lachlanjc, @ianmacartney, @hotters, @isaackatayev, @insik-han, @jayair, @ivanhofer, @javivelasco, @SukkaW, @visshaljagtap, @imranbarbhuiya, @nivak-monarch, @HarshaVardhanReddyDuvvuru, @ianldgs, @ricardofiorani, @swarnava, @gustavostz.