17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsでmetaタグをカスタマイズ!OpenGraphのみを出力しtwitter:~を出力しない方法

Last updated at Posted at 2025-03-11

やりたいこと・前提条件

  • 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

twitter:~のmetaタグも出力されていますね。
image.png

Other

twitter:~のmetaタグは出力されなくなりました。
image.png

おわりに

今回の課題について調査を進める中で、あまり参考になる技術記事がすぐには見つけられなかったため、Qiitaに投稿することを決めました。
私たちのサービスではtwitter:~タグも出力した方が良いという結論に至ったため、今回紹介した方法は最終的に採用しませんでしたが、同じ課題で困っている方には参考になるかもしれませんので、少しでもお役に立てれば幸いです。

KIYOラーニング株式会社について

当社のビジョンは『世界一「学びやすく、分かりやすく、続けやすい」学習手段を提供する』ことです。革新的な教育サービスを作り成長させていく事で、オンライン教育分野でナンバーワンの存在となり、世界に展開していくことを目指しています。

プロダクト

  • スタディング:「学びやすく・わかりやすく・続けやすい」オンライン資格対策講座
  • スタディングキャリア:資格取得者の仕事探しやキャリア形成を支援する転職サービス
  • AirCourse:受け放題の動画研修がついたeラーニングシステム(LMS)

KIYOラーニング株式会社では一緒に働く仲間を募集しています

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?