Menu

メタデータの追加と 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 オブジェクトをエクスポートします。例えば、ブログルートにタイトルと説明を追加するには:

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

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

生成されたメタデータ

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

app/blog/[slug]/page.tsx
TypeScript
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 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 はメタデータを UI とは別にストリーミングし、メタデータが解決されるとすぐに HTML にメタデータを挿入します。

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

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

app/lib/data.ts
TypeScript
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
TypeScript
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

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

OG image special file inside the blog folder

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

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

生成された Open Graph 画像

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

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

app/blog/[slug]/opengraph-image.ts
TypeScript
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)は機能しません。