コンテンツにスキップ
App RouterはじめにメタデータとOG画像

メタデータとOG画像

メタデータAPIは、SEOとWeb共有可能性を向上させるためにアプリケーションのメタデータを定義するために使用でき、以下を含みます。

  1. 静的なmetadataオブジェクト
  2. 動的なgenerateMetadata関数
  3. 静的または動的に生成されたファビコンOG画像を追加するために使用できる特別なファイル規約

上記のすべてのオプションにより、Next.jsはページの関連する<head>タグを自動的に生成します。これはブラウザの開発者ツールで確認できます。

metadataオブジェクトとgenerateMetadata関数のエクスポートは、Server Componentsでのみサポートされています。

デフォルトフィールド

ルートがメタデータを定義していない場合でも、常に2つのデフォルトmetaタグが追加されます。

  • ウェブサイトの文字コードを指定するmeta charsetタグ
  • ウェブサイトのビューポート幅とスケールを設定して、さまざまなデバイスに対応させるmeta viewportタグ
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

その他のメタデータフィールドは、Metadataオブジェクト(静的メタデータ用)またはgenerateMetadata関数(生成されたメタデータ用)で定義できます。

静的なメタデータ

静的なメタデータを定義するには、静的なlayout.jsまたはpage.jsファイルからMetadataオブジェクトをエクスポートします。たとえば、ブログルートにタイトルと説明を追加するには

app/blog/layout.tsx
import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'My Blog',
  description: '...',
}
 
export default function Layout() {}

利用可能なオプションの完全なリストは、generateMetadataドキュメントで確認できます。

生成されたメタデータ

generateMetadata関数を使用して、データに依存するメタデータをfetchできます。たとえば、特定のブログ記事のタイトルと説明を取得するには

app/blog/[slug]/page.tsx
import type { Metadata, ResolvingMetadata } from 'next'
 
type Props = {
  params: Promise<{ slug: string }>
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}
 
export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  const slug = (await params).slug
 
  // fetch post information
  const post = await fetch(`https://api.vercel.app/blog/${slug}`).then((res) =>
    res.json()
  )
 
  return {
    title: post.title,
    description: post.description,
  }
}
 
export default function Page({ params, searchParams }: Props) {}

ストリーミングメタデータ

動的にレンダリングされるページの場合、Next.jsはメタデータを個別にストリーミングし、generateMetadataが解決されると、UIレンダリングをブロックせずにHTMLに注入します。

ストリーミングメタデータは、視覚的なコンテンツが先にストリーミングされるようにすることで、体感パフォーマンスを向上させます。

ストリーミングメタデータは、メタデータが<head>タグに存在することを期待するボットやクローラー(例:TwitterbotSlackbotBingbot)では**無効**になっています。これらは、受信リクエストのUser Agentヘッダーを使用して検出されます。

Next.js設定ファイルでhtmlLimitedBotsオプションを使用して、ストリーミングメタデータをカスタマイズしたり、完全に**無効**にしたりできます。

静的にレンダリングされるページは、ビルド時にメタデータが解決されるため、ストリーミングを使用しません。

ストリーミングメタデータの詳細はこちらをご覧ください。

データリクエストのメモ化

メタデータとページ自体のために**同じ**データを取得する必要がある場合があります。重複リクエストを回避するために、Reactのcache関数を使用して戻り値をメモ化し、データを一度だけ取得できます。たとえば、メタデータとページの両方のブログ記事情報を取得するには

app/lib/data.ts
import { cache } from 'react'
import { db } from '@/app/lib/db'
 
// getPost will be used twice, but execute only once
export const getPost = cache(async (slug: string) => {
  const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) })
  return res
})
app/blog/[slug]/page.tsx
import { getPost } from '@/app/lib/data'
 
export async function generateMetadata({
  params,
}: {
  params: { slug: string }
}) {
  const post = await getPost(params.slug)
  return {
    title: post.title,
    description: post.description,
  }
}
 
export default async function Page({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)
  return <div>{post.title}</div>
}

ファイルベースのメタデータ

メタデータには以下の特殊ファイルが利用可能です。

これらを静的メタデータに使用することも、コードでこれらのファイルをプログラム的に生成することもできます。

ファビコン

ファビコンは、ブックマークや検索結果でサイトを表す小さなアイコンです。アプリケーションにファビコンを追加するには、favicon.icoを作成し、appフォルダのルートに追加します。

Favicon Special File inside the App Folder with sibling layout and page files

コードを使用してファビコンをプログラム的に生成することもできます。詳細については、ファビコンのドキュメントを参照してください。

静的なOpen Graph画像

Open Graph (OG) 画像は、ソーシャルメディアでサイトを表す画像です。アプリケーションに静的なOG画像を追加するには、appフォルダのルートにopengraph-image.pngファイルを作成します。

OG image special file inside the App folder with sibling layout and page files

フォルダ構造の奥にopengraph-image.pngを作成することで、特定のルートのOG画像を追加することもできます。たとえば、/blogルート固有のOG画像を作成するには、blogフォルダ内にopengraph-image.jpgファイルを追加します。

OG image special file inside the blog folder

より具体的な画像が、フォルダ構造上のそれより上のOG画像よりも優先されます。

jpegpnggifなどの他の画像形式もサポートされています。詳細については、Open Graph Imageドキュメントを参照してください。

生成されたOpen Graph画像

ImageResponseコンストラクタを使用すると、JSXとCSSを使用して動的な画像を生成できます。これは、データに依存するOG画像に便利です。

たとえば、各ブログ記事に固有のOG画像を生成するには、blogフォルダ内にopengraph-image.tsxファイルを追加し、next/ogからImageResponseコンストラクタをインポートします。

app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'
import { getPost } from '@/app/lib/data'
 
// Image metadata
export const size = {
  width: 1200,
  height: 630,
}
 
export const contentType = 'image/png'
 
// Image generation
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)
 
  return new ImageResponse(
    (
      // ImageResponse JSX element
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    )
  )
}

ImageResponseは、flexboxや絶対配置、カスタムフォント、テキスト折り返し、中央揃え、ネストされた画像など、一般的なCSSプロパティをサポートしています。サポートされているCSSプロパティの全リストを参照してください。

知っておくと良いこと:

  • 例は、Vercel OG Playgroundで入手できます。
  • ImageResponseは、@vercel/ogsatori、およびresvgを使用してHTMLとCSSをPNGに変換します。
  • flexboxとCSSプロパティのサブセットのみがサポートされています。高度なレイアウト(例:display: grid)は機能しません。