メタデータ
Next.jsには、SEOとWeb共有性を向上させるために、アプリケーションのメタデータ(HTMLの`head`要素内の`meta`タグや`link`タグなど)を定義するために使用できるメタデータAPIがあります。
アプリケーションにメタデータを追加するには、2つの方法があります。
- **設定ベースのメタデータ**:`layout.js`または`page.js`ファイルに、静的な`metadata`オブジェクト、または動的な`generateMetadata`関数をエクスポートします。
- **ファイルベースのメタデータ**:静的または動的に生成された特別なファイルをルートセグメントに追加します。
これらのどちらのオプションでも、Next.jsはページに関連する`<head>`要素を自動的に生成します。また、`ImageResponse`コンストラクタを使用して、動的なOG画像を作成することもできます。
静的メタデータ
静的メタデータを定義するには、`layout.js`または静的な`page.js`ファイルから`Metadata`オブジェクトをエクスポートします。
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}
使用可能なすべてのオプションについては、APIリファレンスを参照してください。
動的メタデータ
動的な値を必要とするメタデータを`fetch`するために、`generateMetadata`関数を使用できます。
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> {
// read route params
const id = (await params).id
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// optionally access and extend (rather than replace) parent metadata
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) {}
使用可能なすべてのパラメータについては、APIリファレンスを参照してください。
知っておくべきこと:
- `generateMetadata`を介した静的および動的メタデータはどちらも、**サーバーコンポーネントでのみサポートされています**。
- `fetch`リクエストは、`generateMetadata`、`generateStaticParams`、レイアウト、ページ、およびサーバーコンポーネント全体で同じデータに対して自動的にメモ化されます。`fetch`が使用できない場合は、Reactの`cache`を使用できます。
- Next.jsは、クライアントにUIをストリーミングする前に、`generateMetadata`内のデータフェッチが完了するまで待機します。これにより、ストリーミングレスポンスの最初の部分に`<head>`タグが含まれていることが保証されます。
ファイルベースのメタデータ
メタデータに使用できる特別なファイルは次のとおりです。
これらは静的メタデータに使用できます。また、コードを使用してこれらのファイルをプログラムで生成することもできます。
実装と例については、メタデータファイルAPIリファレンスと動的画像生成を参照してください。
挙動
ファイルベースのメタデータは優先度が高く、設定ベースのメタデータよりも優先されます。
デフォルトフィールドは、ウェブサイトの文字エンコーディングを設定します。
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
知っておくと良いこと:デフォルトの
viewport
メタタグは上書きできます。
順序付け
メタデータは、ルートセグメントから最終的な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 is a...',
},
}
export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Output:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />
上記の例では
app/layout.js
のtitle
は、app/blog/page.js
のtitle
に**置き換え**られます。app/blog/page.js
がopenGraph
メタデータを設定しているため、app/layout.js
のすべてのopenGraph
フィールドはapp/blog/page.js
で**置き換え**られます。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 is a...',
},
}
export const metadata = {
title: 'About',
}
// Output:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme is a..." />
注記
app/layout.js
の`title`は、`app/about/page.js`の`title`に**置き換え**られます。- `app/about/page.js`は`openGraph`メタデータを設定していないため、`app/layout.js`のすべての`openGraph`フィールドは`app/about/page.js`で**継承**されます。
動的画像生成
ImageResponse
コンストラクタを使用すると、JSXとCSSを使用して動的画像を生成できます。これは、Open Graph画像、Twitterカードなどのソーシャルメディア画像を作成するのに役立ちます。
これを使用するには、`next/og`から`ImageResponse`をインポートします。
import { ImageResponse } from 'next/og'
export async function GET() {
return new ImageResponse(
(
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}
>
Hello world!
</div>
),
{
width: 1200,
height: 600,
}
)
}
ImageResponse
は、ルートハンドラやファイルベースのメタデータなど、他のNext.js APIと適切に統合されています。たとえば、`opengraph-image.tsx`ファイルで`ImageResponse`を使用して、ビルド時またはリクエスト時に動的にOpen Graph画像を生成できます。
ImageResponse
は、フレックスボックスと絶対配置、カスタムフォント、テキストの折り返し、センタリング、ネストされた画像など、一般的なCSSプロパティをサポートしています。 サポートされているCSSプロパティの完全なリストをご覧ください。
知っておくべきこと:
- Vercel OG Playground
で例を確認できます。 ImageResponse
は、@vercel/og、Satori 、およびResvgを使用して、HTMLとCSSをPNGに変換します。 - Edgeランタイムのみがサポートされています。デフォルトのNode.jsランタイムは機能しません。
- フレックスボックスとCSSプロパティのサブセットのみがサポートされています。高度なレイアウト(例:`display:grid`)は機能しません。
- 最大バンドルサイズは`500KB`です。バンドルサイズには、JSX、CSS、フォント、画像、その他のすべてのアセットが含まれます。制限を超えた場合は、アセットのサイズを削減するか、実行時にフェッチすることを検討してください。
- `ttf`、`otf`、`woff`フォント形式のみがサポートされています。フォントの解析速度を最大化するには、`woff`よりも`ttf`または`otf`が推奨されます。
JSON-LD
JSON-LD
JSON-LDに関する現在の推奨事項は、`layout.js`または`page.js`コンポーネントで構造化データを`<script>`タグとしてレンダリングすることです。例えば
export default async function Page({ params }) {
const product = await getProduct(params.id)
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
}
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
)
}
Googleのリッチリザルトテスト
schema-dts
import { Product, WithContext } from 'schema-dts'
const jsonLd: WithContext<Product> = {
'@context': 'https://schema.org',
'@type': 'Product',
name: 'Next.js Sticker',
image: 'https://nextjs.dokyumento.jp/imgs/sticker.png',
description: 'Dynamic at the speed of static.',
}
次のステップ
これは役に立ちましたか?