Next.jsでOGP画像+ALTを動的に生成する
TL;DR
❌ opengraph-image.tsxだけでは動的なALT設定は不可能
⭕️ opengraph-image.tsxでOGP画像作成 + generatemetadata()でALT生成 の合わせ技でALTも動的に設定可能!
背景
Next.jsではv13.3.0からOGP画像をコードで動的に生成できるようになりました。
opengraph-image.tsx(もしくはtwitter-image.tsx)をpage.tsxと同じ階層に置くだけでOGP画像を作成してくれるという優れものです。
具体的なコードを見てみましょう。
import { ImageResponse } from 'next/og'
export const alt = 'Image Description'; // 静的 ALT
export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';
export default async function Image({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params;
const post = await fetch(`https://.../posts/${slug}`).then(res => res.json());
return new ImageResponse(
<div style={{ display: "flex" }}>{post.title}</div>,
{ ...size }
)
}
paramsを用いて引っ張ってきたデータで画像を生成し、altに"Image Description"を設定しているのが何となくわかりますね。
しかし、この方法ではparamsを用いたイメージ生成はできても、ALTの設定はできません。
altはImage()の外側で定義しなければならないからです。
見た目は動的に変わるのにALTは全部同じ、これではアクセシビリティ的に良くありませんよね。。
今回はその解決方法を考えてみました。
解決方法
以下のステップを踏むことでOGP画像に動的にALTを設定することができました。
1.opengraph-image.tsxでOGP作成
前述した方法でOGP画像を生成します。
この時点で設定したALTは次のステップで上書きされるため適当なものにしておきましょう。
import { ImageResponse } from 'next/og'
export const alt = 'tmp ALT'; // 上書きされる
(前述と同じ)
2.generatemetadata()でALT設定
続いて、page.tsxでgenerateMetadata()を使ってALTを設定します。
この時、image.urlには表示させたい画像の絶対パスを指定する必要がありますが、opengraph-image.tsxで作成されたOGP画像はapp/posts/[slug]/opengraph-imageに作成されるため、それを指定すればOKです。
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
// opengraph-image.tsxで作成されたOGP画像の絶対パス
const ogImageUrl = `https:/posts/${slug}/opengraph-image`;
// 上書きするALT
const description = `${data.slug} の説明`;
return {
metadataBase: new URL(baseUrl),
title: title,
description: description,
openGraph: {
title: title,
description: description,
images: [
{
url: ogImageUrl,
width: 1200,
height: 630,
alt: description, // ここでALTを上書きする
},
],
},
};
}
参考
Discussion