generateMetadata
metadataオブジェクトまたはgenerateMetadata関数を使用して、メタデータを定義できます。
metadataオブジェクト
静的メタデータを定義するには、layout.jsまたはpage.jsファイルからMetadataオブジェクトをエクスポートします。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}サポートされているすべてのオプションの完全なリストについては、メタデータフィールドを参照してください。
generateMetadata関数
動的メタデータは、現在のルートパラメータ、外部データ、または親セグメントのmetadataなどの動的情報に依存し、Metadataオブジェクトを返すgenerateMetadata関数をエクスポートして設定できます。
generateMetadataの解決はページのレンダリングの一部です。ページが事前レンダリングでき、generateMetadataが動的動作を導入しない場合、結果のメタデータはページの初期HTMLに含まれます。
それ以外の場合、generateMetadataから解決されたメタデータは、初期UIを送信した後にストリーミングできます。
import type { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: Promise<{ id: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// ルートパラメータを読み込む
const { id } = await params
// データをフェッチする
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// オプションで親メタデータにアクセスして拡張する(置き換えるのではなく)
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }: Props) {}paramsとsearchParamsの型補完については、ページとレイアウトの場合はそれぞれPageProps<'/route'>またはLayoutProps<'/route'>で最初の引数を型指定できます。
補足:
- メタデータは
layout.jsおよびpage.jsファイルに追加できます。- Next.jsはメタデータを自動的に解決し、ページに関連する
<head>タグを作成します。metadataオブジェクトとgenerateMetadata関数のエクスポートは、サーバーコンポーネントのみでサポートされています。- 同じルートセグメントから
metadataオブジェクトとgenerateMetadata関数の両方をエクスポートすることはできません。generateMetadata内のfetchリクエストは、generateMetadata、generateStaticParams、レイアウト、ページ、およびサーバーコンポーネント間の同じデータに対して自動的にメモ化されます。fetchが利用できない場合、Reactcacheを使用できます。- ファイルベースのメタデータは優先度が高く、
metadataオブジェクトとgenerateMetadata関数をオーバーライドします。
リファレンス
パラメータ
generateMetadata関数は以下のパラメータを受け入れます:
-
props- 現在のルートのパラメータを含むオブジェクト:-
params- ルートセグメントからgenerateMetadataが呼び出されるセグメントまでの動的ルートパラメータオブジェクトを含むオブジェクト。例:ルート URL paramsapp/shop/[slug]/page.js/shop/1{ slug: '1' }app/shop/[tag]/[item]/page.js/shop/1/2{ tag: '1', item: '2' }app/shop/[...slug]/page.js/shop/1/2{ slug: ['1', '2'] } -
searchParams- 現在のURLの検索パラメータを含むオブジェクト。例:URL searchParams/shop?a=1{ a: '1' }/shop?a=1&b=2{ a: '1', b: '2' }/shop?a=1&a=2{ a: ['1', '2'] }
-
-
parent- 親ルートセグメントから解決されたメタデータの約束。
戻り値
generateMetadataは、1つ以上のメタデータフィールドを含むMetadataオブジェクトを返す必要があります。
補足:
- メタデータがランタイム情報に依存しない場合、
generateMetadataではなく、静的なmetadataオブジェクトを使用して定義する必要があります。fetchリクエストは、generateMetadata、generateStaticParams、レイアウト、ページ、およびサーバーコンポーネント間の同じデータに対して自動的にメモ化されます。fetchが利用できない場合、Reactcacheを使用できます。searchParamsはpage.jsセグメントでのみ利用可能です。redirect()およびnotFound()Next.jsメソッドもgenerateMetadata内で使用できます。
メタデータフィールド
以下のフィールドがサポートされています:
title
title属性はドキュメントのタイトルを設定するのに使用されます。単純な文字列またはオプションのテンプレートオブジェクトとして定義できます。
文字列
export const metadata = {
title: 'Next.js',
}<title>Next.js</title>default
title.defaultを使用して、titleを定義しない子ルートセグメントにフォールバックタイトルを提供できます。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Acme',
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {}
// 出力:<title>Acme</title>template
title.templateを使用して、子ルートセグメントで定義されたtitlesにプレフィックスまたはサフィックスを追加できます。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // テンプレートを作成する場合、デフォルトは必須です
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About',
}
// 出力:<title>About | Acme</title>補足:
title.templateは子ルートセグメントに適用され、**定義されているセグメントには適用されません。つまり:
title.templateを追加する場合、title.defaultは必須です。layout.jsで定義されたtitle.templateは、同じルートセグメントのpage.jsで定義されたtitleには適用されません。page.jsで定義されたtitle.templateは、ページが常に終了セグメント(子ルートセグメントがない)であるため、効果がありません。- ルートが
titleまたはtitle.defaultを定義していない場合、title.templateは効果がありません。
absolute
title.absoluteを使用して、親セグメントで設定されたtitle.templateを無視するタイトルを提供できます。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
absolute: 'About',
},
}
// 出力:<title>About</title>補足:
layout.js
title(文字列)およびtitle.defaultは、子セグメントのデフォルトタイトルを定義します(独自のtitleを定義していません)。親セグメントにtitle.templateが存在する場合、それに拡張されます。title.absoluteは、子セグメントのデフォルトタイトルを定義します。親セグメントからのtitle.templateを無視します。title.templateは子セグメントの新しいタイトルテンプレートを定義します。page.js
- ページが独自のタイトルを定義していない場合、最も近い親の解決されたタイトルが使用されます。
title(文字列)はルートのタイトルを定義します。親セグメントにtitle.templateが存在する場合、それに拡張されます。title.absoluteはルートタイトルを定義します。親セグメントからのtitle.templateを無視します。- ページが常にルートの終了セグメントであるため、
page.jsではtitle.templateは効果がありません。
description
export const metadata = {
description: 'Webの代替えReactフレームワーク',
}<meta name="description" content="Webの代替えReactフレームワーク" />その他のフィールド
export const metadata = {
generator: 'Next.js',
applicationName: 'Next.js',
referrer: 'origin-when-cross-origin',
keywords: ['Next.js', 'React', 'JavaScript'],
authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
creator: 'Jiachi Liu',
publisher: 'Sebastian Markbåge',
formatDetection: {
email: false,
address: false,
telephone: false,
},
}<meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />metadataBase
metadataBaseは、完全修飾URLが必要なメタデータフィールドのベースURLプレフィックスを設定するための便利なオプションです。
metadataBaseにより、現在のルートセグメント以下で定義されたURLベースのmetadataフィールドは、それ以外は必須の絶対URLではなく相対パスを使用できます。- フィールドの相対パスは
metadataBaseと組み合わされて、完全修飾URLを形成します。
export const metadata = {
metadataBase: new URL('https://acme.com'),
alternates: {
canonical: '/',
languages: {
'en-US': '/en-US',
'de-DE': '/de-DE',
},
},
openGraph: {
images: '/og-image.png',
},
}<link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />補足:
metadataBaseは通常、ルートapp/layout.jsで設定され、すべてのルート全体でURLベースのmetadataフィールドに適用されます。- 絶対URLが必要なすべてのURLベースの
metadataフィールドは、metadataBaseオプションで構成できます。metadataBaseには、サブドメイン(例:https://app.acme.com)またはベースパス(例:https://acme.com/start/from/here)を含めることができます。metadataフィールドが絶対URLを提供する場合、metadataBaseは無視されます。metadataBaseを構成しないでURLベースのmetadataフィールドで相対パスを使用すると、ビルドエラーが発生します。- Next.jsは
metadataBase(例:https://acme.com/)と相対フィールド(例:/path)の間の重複するスラッシュを単一のスラッシュ(例:https://acme.com/path)に正規化します。
URLの構成
URL構成は、デフォルトのディレクトリトラバーサルセマンティクスよりも開発者の意図を優先します。
metadataBaseとmetadataフィールド間の末尾のスラッシュが正規化されます。metadataフィールドの「絶対」パス(通常はURL全体パスを置き換えます)は「相対」パス(metadataBaseの終わりから始まる)として扱われます。
例えば、次のmetadataBaseの場合:
import type { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https://acme.com'),
}上記のmetadataBaseを継承し、独自の値を設定したmetadataフィールドは、次のように解決されます:
metadataフィールド | 解決されたURL |
|---|---|
/ | https://acme.com |
./ | https://acme.com |
payments | https://acme.com/payments |
/payments | https://acme.com/payments |
./payments | https://acme.com/payments |
../payments | https://acme.com/payments |
https://beta.acme.com/payments | https://beta.acme.com/payments |
openGraph
export const metadata = {
openGraph: {
title: 'Next.js',
description: 'Webの代替えReactフレームワーク',
url: 'https://nextjs.org',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.org/og.png', // 絶対URLである必要があります
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png', // 絶対URLである必要があります
width: 1800,
height: 1600,
alt: 'カスタム代替テキスト',
},
],
videos: [
{
url: 'https://nextjs.org/video.mp4', // 絶対URLである必要があります
width: 800,
height: 600,
},
],
audio: [
{
url: 'https://nextjs.org/audio.mp3', // 絶対URLである必要があります
},
],
locale: 'en_US',
type: 'website',
},
}<meta property="og:title" content="Next.js" />
<meta property="og:description" content="Webの代替えReactフレームワーク" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="カスタム代替テキスト" />
<meta property="og:video" content="https://nextjs.org/video.mp4" />
<meta property="og:video:width" content="800" />
<meta property="og:video:height" content="600" />
<meta property="og:audio" content="https://nextjs.org/audio.mp3" />
<meta property="og:type" content="website" />export const metadata = {
openGraph: {
title: 'Next.js',
description: 'Webの代替えReactフレームワーク',
type: 'article',
publishedTime: '2023-01-01T00:00:00.000Z',
authors: ['Seb', 'Josh'],
},
}<meta property="og:title" content="Next.js" />
<meta property="og:description" content="Webの代替えReactフレームワーク" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />補足:
- Open Graph画像にはファイルベースのメタデータAPIを使用する方が便利な場合があります。設定エクスポートを実際のファイルと同期する必要がなく、ファイルベースのAPIは自動的に正しいメタデータを生成します。
robots
import type { Metadata } from 'next'
export const metadata: Metadata = {
robots: {
index: true,
follow: true,
nocache: false,
googleBot: {
index: true,
follow: true,
noimageindex: false,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
}<meta name="robots" content="index, follow" />
<meta
name="googlebot"
content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>icons
補足:可能な場合は、ファイルベースのメタデータAPIを使用することをお勧めします。設定エクスポートを実際のファイルと同期する必要がなく、ファイルベースのAPIは自動的に正しいメタデータを生成します。
export const metadata = {
icons: {
icon: '/icon.png',
shortcut: '/shortcut-icon.png',
apple: '/apple-icon.png',
other: {
rel: 'apple-touch-icon-precomposed',
url: '/apple-touch-icon-precomposed.png',
},
},
}<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
rel="apple-touch-icon-precomposed"
href="/apple-touch-icon-precomposed.png"
/>export const metadata = {
icons: {
icon: [
{ url: '/icon.png' },
new URL('/icon.png', 'https://example.com'),
{ url: '/icon-dark.png', media: '(prefers-color-scheme: dark)' },
],
shortcut: ['/shortcut-icon.png'],
apple: [
{ url: '/apple-icon.png' },
{ url: '/apple-icon-x3.png', sizes: '180x180', type: 'image/png' },
],
other: [
{
rel: 'apple-touch-icon-precomposed',
url: '/apple-touch-icon-precomposed.png',
},
],
},
}<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="icon" href="https://example.com/icon.png" />
<link rel="icon" href="/icon-dark.png" media="(prefers-color-scheme: dark)" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
rel="apple-touch-icon-precomposed"
href="/apple-touch-icon-precomposed.png"
/>
<link
rel="apple-touch-icon"
href="/apple-icon-x3.png"
sizes="180x180"
type="image/png"
/>補足:
msapplication-*メタタグはChromiumビルドのMicrosoft Edgeではサポートされなくなり、したがって不要になりました。
themeColor
非推奨:Next.js 14の時点で、
metadataのthemeColorオプションは非推奨です。代わりにviewport構成を使用してください。
colorScheme
非推奨:Next.js 14の時点で、
metadataのcolorSchemeオプションは非推奨です。代わりにviewport構成を使用してください。
manifest
ウェブアプリケーションマニフェスト仕様で定義されているウェブアプリケーションマニフェスト。
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}<link rel="manifest" href="https://nextjs.org/manifest.json" />twitter
Twitter仕様は(驚くべきことに)X(以前はTwitterとして知られていた)以上の用途に使用されています。
Twitterカードマークアップリファレンスの詳細を参照してください。
export const metadata = {
twitter: {
card: 'summary_large_image',
title: 'Next.js',
description: 'Webの代替えReactフレームワーク',
siteId: '1467726470533754880',
creator: '@nextjs',
creatorId: '1467726470533754880',
images: ['https://nextjs.org/og.png'], // 絶対URLである必要があります
},
}<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="Webの代替えReactフレームワーク" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />export const metadata = {
twitter: {
card: 'app',
title: 'Next.js',
description: 'Webの代替えReactフレームワーク',
siteId: '1467726470533754880',
creator: '@nextjs',
creatorId: '1467726470533754880',
images: {
url: 'https://nextjs.org/og.png',
alt: 'Next.jsロゴ',
},
app: {
name: 'twitter_app',
id: {
iphone: 'twitter_app://iphone',
ipad: 'twitter_app://ipad',
googleplay: 'twitter_app://googleplay',
},
url: {
iphone: 'https://iphone_url',
ipad: 'https://ipad_url',
},
},
},
}<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="Webの代替えReactフレームワーク" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.jsロゴ" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />viewport
非推奨:Next.js 14の時点で、
metadataのviewportオプションは非推奨です。代わりにviewport構成を使用してください。
verification
export const metadata = {
verification: {
google: 'google',
yandex: 'yandex',
yahoo: 'yahoo',
other: {
me: ['my-email', 'my-link'],
},
},
}<meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />appleWebApp
export const metadata = {
itunes: {
appId: 'myAppStoreID',
appArgument: 'myAppArgument',
},
appleWebApp: {
title: 'Apple Web App',
statusBarStyle: 'black-translucent',
startupImage: [
'/assets/startup/apple-touch-startup-image-768x1004.png',
{
url: '/assets/startup/apple-touch-startup-image-1536x2008.png',
media: '(device-width: 768px) and (device-height: 1024px)',
},
],
},
}<meta
name="apple-itunes-app"
content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Apple Web App" />
<link
href="/assets/startup/apple-touch-startup-image-768x1004.png"
rel="apple-touch-startup-image"
/>
<link
href="/assets/startup/apple-touch-startup-image-1536x2008.png"
media="(device-width: 768px) and (device-height: 1024px)"
rel="apple-touch-startup-image"
/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>alternates
export const metadata = {
alternates: {
canonical: 'https://nextjs.org',
languages: {
'en-US': 'https://nextjs.org/en-US',
'de-DE': 'https://nextjs.org/de-DE',
},
media: {
'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
},
types: {
'application/rss+xml': 'https://nextjs.org/rss',
},
},
}<link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
rel="alternate"
media="only screen and (max-width: 600px)"
href="https://nextjs.org/mobile"
/>
<link
rel="alternate"
type="application/rss+xml"
href="https://nextjs.org/rss"
/>appLinks
export const metadata = {
appLinks: {
ios: {
url: 'https://nextjs.org/ios',
app_store_id: 'app_store_id',
},
android: {
package: 'com.example.android/package',
app_name: 'app_name_android',
},
web: {
url: 'https://nextjs.org/web',
should_fallback: true,
},
},
}<meta property="al:ios:url" content="https://nextjs.org/ios" />
<meta property="al:ios:app_store_id" content="app_store_id" />
<meta property="al:android:package" content="com.example.android/package" />
<meta property="al:android:app_name" content="app_name_android" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:should_fallback" content="true" />archives
歴史的な関心のある記録、ドキュメント、またはその他の資料のコレクションを説明します(出典)。
export const metadata = {
archives: ['https://nextjs.org/13'],
}<link rel="archives" href="https://nextjs.org/13" />assets
export const metadata = {
assets: ['https://nextjs.org/assets'],
}<link rel="assets" href="https://nextjs.org/assets" />bookmarks
export const metadata = {
bookmarks: ['https://nextjs.org/13'],
}<link rel="bookmarks" href="https://nextjs.org/13" />category
export const metadata = {
category: 'technology',
}<meta name="category" content="technology" />facebook
Facebookアプリまたはメインのユーザーのアカウントをウェブページに接続して、特定のFacebook Social Pluginを使用できます。Facebookドキュメント
補足:appIdまたはadminsのいずれかを指定できますが、両方は指定できません。
export const metadata = {
facebook: {
appId: '12345678',
},
}<meta property="fb:app_id" content="12345678" />export const metadata = {
facebook: {
admins: '12345678',
},
}<meta property="fb:admins" content="12345678" />複数のfb:adminsメタタグを生成する場合は、配列値を使用できます。
export const metadata = {
facebook: {
admins: ['12345678', '87654321'],
},
}<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />pinterest
ウェブページでPinterest Rich Pinsを有効または無効にできます。
export const metadata = {
pinterest: {
richPin: true,
},
}<meta name="pinterest-rich-pin" content="true" />other
すべてのメタデータオプションは、組み込みサポートを使用してカバーする必要があります。ただし、サイトまたはブランド固有のカスタムメタデータタグ、または最近リリースされた新しいメタデータタグがある場合があります。otherオプションを使用して、カスタムメタデータタグをレンダリングできます。
export const metadata = {
other: {
custom: 'meta',
},
}<meta name="custom" content="meta" />複数の同じキーメタタグを生成する場合は、配列値を使用できます。
export const metadata = {
other: {
custom: ['meta1', 'meta2'],
},
}<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />タイプ
Metadata型を使用してメタデータに型安全性を追加できます。IDEで組み込みTypeScriptプラグインを使用している場合、手動で型を追加する必要はありませんが、必要に応じて明示的に追加することもできます。
metadataオブジェクト
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}generateMetadata関数
通常の関数
import type { Metadata } from 'next'
export function generateMetadata(): Metadata {
return {
title: 'Next.js',
}
}非同期関数
import type { Metadata } from 'next'
export async function generateMetadata(): Promise<Metadata> {
return {
title: 'Next.js',
}
}セグメントプロップを含む
import type { Metadata } from 'next'
type Props = {
params: Promise<{ id: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
export function generateMetadata({ params, searchParams }: Props): Metadata {
return {
title: 'Next.js',
}
}
export default function Page({ params, searchParams }: Props) {}親メタデータを含む
import type { Metadata, ResolvingMetadata } from 'next'
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: 'Next.js',
}
}JavaScriptプロジェクト
JavaScriptプロジェクトの場合、JSDocを使用して型安全性を追加できます。
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}サポートされていないメタデータ
以下のメタデータタイプは現在、組み込みサポートがありません。ただし、レイアウトまたはページ自体でレンダリングできます。
| メタデータ | 推奨事項 |
|---|---|
<meta http-equiv="..."> | redirect()、プロキシ、セキュリティヘッダーを使用して適切なHTTPヘッダーを使用します。 |
<base> | レイアウトまたはページ自体にタグをレンダリングします。 |
<noscript> | レイアウトまたはページ自体にタグをレンダリングします。 |
<style> | Next.jsでのスタイリングの詳細を参照してください。 |
<script> | スクリプトの使用の詳細を参照してください。 |
<link rel="stylesheet" /> | スタイルシートをレイアウトまたはページに直接importします。 |
<link rel="preload /> | ReactDOM preloadメソッドを使用します。 |
<link rel="preconnect" /> | ReactDOM preconnectメソッドを使用します。 |
<link rel="dns-prefetch" /> | ReactDOM prefetchDNSメソッドを使用します。 |
リソースヒント
<link>要素には、ブラウザに外部リソースが必要であることをヒントするために使用できる多くのrelキーワードがあります。ブラウザはこの情報を使用して、キーワードに応じてプリロード最適化を適用します。
メタデータAPIはこれらのヒントを直接サポートしていませんが、新しいReactDOMメソッドを使用して、ドキュメントの<head>に安全に挿入できます。
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}<link rel="preload">
ページレンダリング(ブラウザ)のライフサイクルの早期にリソースの読み込みを開始します。MDNドキュメント。
ReactDOM.preload(href: string, options: { as: string })<link rel="preload" href="..." as="..." /><link rel="preconnect">
オリジンへの接続を事前に開始します。MDNドキュメント。
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })<link rel="preconnect" href="..." crossorigin /><link rel="dns-prefetch">
リソースがリクエストされる前に、ドメイン名の解決を試みます。MDNドキュメント。
ReactDOM.prefetchDNS(href: string)<link rel="dns-prefetch" href="..." />補足:
- これらのメソッドは現在、クライアントコンポーネントでのみサポートされており、初期ページ読み込み時にはサーバーサイドレンダリングされます。
next/font、next/image、next/scriptなどのNext.jsの組み込み機能は、関連するリソースヒントを自動的に処理します。
動作
デフォルトフィールド
ルートがメタデータを定義していない場合でも、常に追加される2つのデフォルトmetaタグがあります:
- メタcharsetタグは、ウェブサイトの文字エンコーディングを設定します。
- メタviewportタグは、別のデバイスに合わせるためのビューポート幅とスケールを設定します。
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />補足:デフォルトの
viewportメタタグをオーバーライドできます。
ストリーミングメタデータ
ストリーミングメタデータにより、Next.jsはgenerateMetadataが完了するのを待たずに、初期UIをレンダリングしてブラウザに送信できます。
generateMetadataが解決されると、結果のメタデータタグが<body>タグに追加されます。JavaScriptを実行して完全なDOMを検査するボット(例:Googlebot)によってメタデータが正しく解釈されることを確認しました。
JavaScriptを実行できないHTMLに限定されたボット(例:facebookexternalhit)の場合、メタデータはページレンダリングを引き続きブロックします。結果のメタデータは<head>タグで利用可能になります。
Next.jsは、User Agentヘッダーを見ることによってHTMLに限定されたボットを自動的に検出します。Next.jsの構成ファイルでhtmlLimitedBotsオプションを使用して、デフォルトのUser Agentリストをオーバーライドできます。
ストリーミングメタデータを完全に無効にするには:
import type { NextConfig } from 'next'
const config: NextConfig = {
htmlLimitedBots: /.*/,
}
export default configストリーミングメタデータは、TTFBを削減することで認識されるパフォーマンスを向上させ、LCP時間を低下させるのに役立ちます。
htmlLimitedBotsをオーバーライドすると、応答時間が長くなる可能性があります。ストリーミングメタデータは高度な機能であり、ほとんどの場合、デフォルトで十分です。
順序
メタデータはルートセグメントから最終的なpage.jsセグメントに最も近いセグメントまで、順序に従って評価されます。例えば:
app/layout.tsx(ルートレイアウト)app/blog/layout.tsx(ネストされたブログレイアウト)app/blog/[slug]/page.tsx(ブログページ)
マージ
評価順に従って、同じルート内の複数のセグメントからエクスポートされたメタデータオブジェクトは浅くマージされてルートの最終メタデータ出力を形成します。重複キーは、その順序に基づいて置き換えられます。
これは、openGraphとrobotsなどの早期セグメントで定義されたネストされたフィールドを持つメタデータが、それらを定義する最後のセグメントによって上書きされることを意味します。
フィールドの上書き
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acmeは...',
},
}export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// 出力:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />上記の例では:
app/layout.jsのtitleはapp/blog/page.jsのtitleによって置き換えられます。app/layout.jsのすべてのopenGraphフィールドはapp/blog/page.jsで置き換えられます。app/blog/page.jsはopenGraphメタデータを設定するため。openGraph.descriptionがないことに注意してください。
セグメント間でネストされたフィールドのいくつかを共有しながら他の部分をオーバーライドしたい場合は、それらを別の変数に引き出すことができます:
export const openGraphImage = { images: ['http://...'] }import { openGraphImage } from './shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'Home',
},
}import { openGraphImage } from '../shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'About',
},
}上記の例では、OG画像はapp/layout.jsとapp/about/page.jsの間で共有されていますが、タイトルは異なります。
フィールドの継承
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acmeは...',
},
}export const metadata = {
title: 'About',
}
// 出力:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acmeは..." />注釈
app/layout.jsのtitleはapp/about/page.jsのtitleによって置き換えられます。app/layout.jsのすべてのopenGraphフィールドはapp/about/page.jsで継承されます。app/about/page.jsはopenGraphメタデータを設定しないため。
バージョン履歴
| バージョン | 変更内容 |
|---|---|
v15.2.0 | generateMetadataへのストリーミングサポートを導入しました。 |
v13.2.0 | viewport構成に有利にviewport、themeColor、colorSchemeを廃止しました。 |
v13.2.0 | metadataとgenerateMetadataを導入しました。 |