LoginSignup
0
0

Next.jsで動的にメタ情報設定

Posted at

はじめに

ブログサイトを作る過程で学んだことを、備忘録目的で投稿しています。
自身は駆け出しエンジニアであり、React自体がほぼ初学者のため、誤った認識・理解をしている可能性があります。
万が一参考にする場合は、上記の点を考慮した上でご一読ください。
また、スタイリングについては割愛しています。

この記事は、過去に投稿したNext.js × microCMSでブログサイト作成した際に学んだことを書き留めるのプロジェクトを元に説明しています。

目的

各ページにメタ情報を追加する、記事詳細ページなど動的ページにも対応する。

作業環境

Windows10 Pro x64
Node.js: 20.14.0
npm: 10.3.0
Next.js: 14.2.3(App Router使用)

手順

静的なメタ情報を設定

layout.jsxで基本形を設定します。

静的なメタ情報にはexport const metadataを使用します。
まずは結論から。

/src/app/layout.jsx
import "./globals.scss";

// metadataオブジェクトの基本形を設定
export const metadata = {
  // Vercel以外のホスティングサービスを利用する場合はmetadataBaseを設定する必要がある
  metadataBase: new URL("https://example-domain.com"),

  title: {
    default: "サイトタイトル",
    template: `%s | サイトタイトル`,
  },
  description: "一覧ページのディスクリプション",
  alternates: {
    canonical: "/",
  },
  openGraph: {
    title: {
      default: "サイトタイトル",
      template: `%s | サイトタイトル`,
    },
    description: "一覧ページのディスクリプション",
    url: `https://example-domain.com`,
    siteName: "サイトタイトル",
    locale: "ja_JP",
    type: "website",
    images: "/opengraph-image.png",
  },
  twitter: {
    card: "summary_large_image",
    images: "/twitter-image.png",
  },
};

export default function RootLayout({ children }) {
  return (
    <html lang="ja">
      <body>{children}</body>
    </html>
  );
}

image.png
image.png

templateを使用することで、トップページでは「サイトタイトル」のみ、仮想ページでは「ページタイトル | サイトタイトル」のようにすることが可能です。

title: {
  default: "サイトタイトル",
  template: `%s | サイトタイトル`,
},

opengraph-image.pngtwitter-image.pngはappディレクトリ直下に配置しています。
twitterの設定を行わなかった場合は、openGraphと同じ画像設定になります。

metadataBaseは、Vercel以外のホスティングサービスを利用する場合に必要とのことです。
設定しなかった場合、localhostになってしまうらしいです。(未検証)

動的なメタ情報を設定

記事詳細ページのメタ情報を設定します。
まずは結論から。

/src/app/articles/[slug]/page.jsx
export async function generateMetadata({ params }) {
  const pageUrl = `articles/${params.slug}/`;

  // 記事詳細を取得
  const queries = { fields: "title" };
  const article = await getArticlesDetail(params.slug, queries);

  const metadata = {
    title: article.title,
    description: "詳細ページのディスクリプション",
    alternates: {
      canonical: `${pageUrl}`,
    },
    openGraph: {
      title: article.title,
      description: "詳細ページのディスクリプション",
      url: `https://example-domain.com/${pageUrl}`,
      siteName: "サイトタイトル",
      locale: "ja_JP",
      type: "website",
      images: "/opengraph-image.png",
    },
    twitter: {
      card: "summary_large_image",
      images: "/twitter-image.png",
    },
  };

  return metadata;
}

image.png
image.png

異なる箇所を解説します。
まずはURLが異なるので、paramsから現在のコンテンツIDを取得し、そこからpageUrlを設定します。
次に、titleにページタイトルを表示させたいので、記事タイトルをAPIから取得し、titleで使用します。
後は、descriptionに好きな内容を入力します。
残りの箇所は全て同じになります。

さいごに

今回はわかりやすいように重複する内容も毎回記述していますが、実際には保守性を高めるために一括管理するファイルを準備し、そこからimportして使用するのがよいと思います。

参考

0
0
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
0
0