やりたいこと・前提条件
- Next.jsのバージョンは15.2.1
- ルーティングシステムはApp Routerを採用
- metaタグのog:~は出力するが、twitter:~は出力しない
課題
Next.jsでmetaタグを出力する方法については、以下の公式ドキュメントに記載されている通り、generateMetadata関数を利用します。
https://nextjs.org/docs/app/building-your-application/optimizing/metadata
サンプルコード
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
// 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) {}
MetadataにはopenGraphというプロパティがあり、そこに必要な情報を設定します。
しかし、このままだとtwitter:~タグもog:~と同じ設定値で出力されてしまう仕様になっています。
SEO的にはtwitter:~のmetaタグも出力した方が良いとされていることから、このような配慮がされているのかもしれません。
解決策
Metadataにはtwitterというプロパティも存在しますが、nullやundefined、空のオブジェクトを設定しても、どれもうまくいかず困っていました。
その後、下記のGitHubのページでtwitter:~を出力させない方法が紹介されていたので、試してみました。
https://github.com/vercel/next.js/discussions/75319
解決方法としては、MetadataのopenGraphには何も設定せず、代わりにotherプロパティを使用してOpenGraph情報を設定する方法です。
具体的には以下のように設定します。
other: {
'og:title': meta.title,
'og:type': meta.type,
'og:image': `${APP_BASE_URL}/og-image?fbgBCzjj`,
'og:url': APP_BASE_URL,
},
// openGraphには何も設定しない
// openGraph: {
// title: meta.title,
// type: meta.type,
// image: `${APP_BASE_URL}/og-image?fbgBCzjj`,
// url: APP_BASE_URL,
// },
この方法であれば、twitter:~のmetaタグは出力せず、og:~のmetaタグのみを出力できます。
実際に試してみる
まずは適当なNext.jsプロジェクトをApp Routerで作成しておきます。
※この記事作成時点におけるNext.jsの最新バージョンは15.2.1です。
npx create-next-app@latest
次にsrc > appの配下に(pages) > metaディレクトリを作成し、ogとotherページを作成します。
src
└── app
├── (pages)
│ └── meta
│ ├── og
│ │ └── page.tsx
│ └── other
│ └── page.tsx
├── favicon.ico
├── globals.css
├── layout.tsx
└── page.tsx
src/app/(pages)/meta/og/page.tsx
import { Metadata } from "next";
export const generateMetadata = (): Metadata => {
return {
title: "Meta Tags Test Page OpenGraph",
description: "Meta Tags Test Page OpenGraph Description",
keywords: ["Meta Tags", "Test", "Page", "OpenGraph"],
openGraph: {
"siteName": "Meta Tags Test Page OpenGraph",
"type": "article",
"title": "Meta Tags Test Page OpenGraph",
"description": "Meta Tags Test Page OpenGraph Description",
"locale": "ja_JP",
},
};
};
export default function Page() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
Meta Tags Test Page OpenGraph
</main>
</div>
);
}
src/app/(pages)/meta/other/page.tsx
import { Metadata } from "next";
export const generateMetadata = (): Metadata => {
return {
title: "Meta Tags Test Page Other",
description: "Meta Tags Test Page Other Description",
keywords: ["Meta Tags", "Test", "Page"],
other: {
"og:siteName": "Meta Tags Test Page Other",
"og:type": "article",
"og:title": "Meta Tags Test Page Other",
"og:description": "Meta Tags Test Page Other Description",
"og:locale": "ja_JP",
},
};
};
export default function Page() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
Meta Tags Test Page Other
</main>
</div>
);
}
画面表示
OpenGraph
Other
おわりに
今回の課題について調査を進める中で、あまり参考になる技術記事がすぐには見つけられなかったため、Qiitaに投稿することを決めました。
私たちのサービスではtwitter:~タグも出力した方が良いという結論に至ったため、今回紹介した方法は最終的に採用しませんでしたが、同じ課題で困っている方には参考になるかもしれませんので、少しでもお役に立てれば幸いです。
KIYOラーニング株式会社について
当社のビジョンは『世界一「学びやすく、分かりやすく、続けやすい」学習手段を提供する』ことです。革新的な教育サービスを作り成長させていく事で、オンライン教育分野でナンバーワンの存在となり、世界に展開していくことを目指しています。
プロダクト
- スタディング:「学びやすく・わかりやすく・続けやすい」オンライン資格対策講座
- スタディングキャリア:資格取得者の仕事探しやキャリア形成を支援する転職サービス
- AirCourse:受け放題の動画研修がついたeラーニングシステム(LMS)
KIYOラーニング株式会社では一緒に働く仲間を募集しています