メタデータの追加とOG画像の作成方法

メタデータAPIを使用すると、SEOとウェブ共有性を向上させるためにアプリケーションのメタデータを定義できます。これには以下が含まれます:

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

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

デフォルトフィールド

ルートがメタデータを定義していなくても、常に追加される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オブジェクトをエクスポートします。例えば、ブログルートにタイトルと説明を追加するには:

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'My Blog',
  description: '...',
}

export default function Page() {}
export const metadata = {
  title: 'My Blog',
  description: '...',
}

export default function Page() {}

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

生成メタデータ

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

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

  // 投稿情報を取得
  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はメタデータをUIとは別にストリーミングし、解決され次第HTMLにメタデータを注入します。

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

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

import { cache } from 'react'
import { db } from '@/app/lib/db'

// getPostは2回使用されますが、1回だけ実行されます
export const getPost = cache(async (slug: string) => {
  const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) })
  return res
})

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

以下の特別なファイルがメタデータ用に利用可能です:

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

ファビコン

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

アプリフォルダ内のファビコン特別ファイル(レイアウトとページファイルと並列)

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

静的OG画像

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

アプリフォルダ内のOG画像特別ファイル(レイアウトとページファイルと並列)

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

ブログフォルダ内のOG画像特別ファイル

より具体的な画像は、フォルダ構造の上位にあるOG画像よりも優先されます。

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

生成OG画像

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

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

import { ImageResponse } from 'next/og'
import { getPost } from '@/app/lib/data'

// 画像メタデータ
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// 画像生成
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)

  return new ImageResponse(
    (
      // ImageResponse JSX要素
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    )
  )
}

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

知っておくと便利

  • 例はVercel OG Playgroundで利用可能です。
  • ImageResponseは、HTMLとCSSをPNGに変換するために@vercel/ogsatoriresvgを使用します。
  • フレックスボックスとCSSプロパティのサブセットのみがサポートされています。高度なレイアウト(例:display: grid)は機能しません。

On this page