検索エンジン最適化のために metadata をどう入れるか調べていたところ、velog でDoeunnkimmさんの記事を見て、メタデータを静的に注入していた。
投稿を始めてみると、動的ルーティングで各ポストごとに異なる metadata を入れたくなった。
そこで復習も兼ねて一度書いてみる。
1. コード
まず、上の velog で見つけたコードは以下のとおり。
// まず基本的に必要なメタデータを設定する。
const META = {
title: "ブログタイトル",
siteName: "サイト名",
description: "ブログに関する大まかな説明",
keyword: ["配列", "形式の", "キーワード"],
url: "https://sample.kr",
googleVerification: "xxx", // Google サーチコンソール
naverVerification: "xxx", // Naver サーチアドバイザー
ogImage: "https://sample.kr/assets/thumbnail.png", // サムネイル,
} as const;
// getMetadata 関数を利用して metadata を設定する。
// 下の関数 1 つで、ほとんどのサイトで必要な metadata は事足りる。
export const getMetadata = (metadataProps?: generateMetadataProps) => {
const { title, description, asPath, ogImage } = metadataProps || {};
const TITLE = title ? `${title} | ブログタイトル` : META.title;
const DESCRIPTION = description || META.description;
const PAGE_URL = asPath ? asPath : "";
const OG_IMAGE = ogImage || META.ogImage;
const metadata: Metadata = {
metadataBase: new URL(META.url),
alternates: {
canonical: PAGE_URL,
},
title: TITLE,
description: DESCRIPTION,
keywords: [...META.keyword],
openGraph: {
title: TITLE,
description: DESCRIPTION,
siteName: TITLE,
locale: "ko_KR",
type: "website",
url: PAGE_URL,
images: {
url: OG_IMAGE,
},
},
verification: {
google: META.googleVerification,
other: {
"naver-site-verification": META.naverVerification,
},
},
twitter: {
title: TITLE,
description: DESCRIPTION,
images: {
url: OG_IMAGE,
},
},
icons: {
icon: "/favicon/favicon.ico",
},
};
return metadata;
};
そしてこのコードを layout.tsx で呼び出して使用する。
metadata を生成してこれを export すると、ホームページに関するメタデータが生成される。
import "./globals.css";
import { Metadata } from "next";
import { getMetadata } from "@/utils/getMetadata";
// メタデータオブジェクトをエクスポート
export const metadata: Metadata = {
// スプレッド構文 .. を利用してオブジェクトを取り込む。
...getMetadata(),
// もし別のタイトルを使いたいなら、以下のようにすればよい。
...getMetadata({ title: "別のタイトル" }),
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body className="h-svh">
<div>
<div className="mx-auto max-w-7xl p-6 lg:px-8">{children}</div>
</div>
</body>
</html>
);
}
自分のホームページにアクセスして F12 キーを押し、<head> タグを確認すると、metadata を確認できる。

2. 動的ルーティングと metadata
動的ルーティングでは generateMetadata 関数を利用した。
これに関する説明は上記ブログやNextjs 公式ドキュメントにある。

この記事のポイントは、metadata を作るときに動的ルーティングで使われるオブジェクトを利用できるということだ。
自分は slug と記事一覧が入った Json を使ってメタデータを作成した。
export async function generateMetadata({
params,
}: {
params: { slug: string };
}) {
const { slug } = await params;
// カテゴリー一覧 json を読み込む
const categoryData = fs.readFileSync(categoryJsonPath, "utf-8");
const categorys: postCardFrontMatter[] = JSON.parse(categoryData);
// 現在の slug と url が同じものを 1 件探して返す。
const baseMetaData = categorys.find(
(category) => category.postUrlPath === slug
);
// これを利用してメタデータを設定
const metadata: Metadata = {
...getMetadata({
title: baseMetaData?.data.title,
description: baseMetaData?.data.description,
asPath: `https://earthscience.kr/posts/${slug}`,
ogImage:
baseMetaData?.data.thumbnail &&
`https://earthscience.kr/posts/${slug}/${baseMetaData.data.thumbnail}`,
}),
};
return metadata;
}
3. 感想
普通は Facebook の共有デバッガーをよく使う。
しかし自分は Facebook アカウントがないので、単純にカカオトークでテストしてみた。
短所は、画像が表示されるまで少し時間がかかること。

最初は画像が表示されなかったが、翌日もう一度見てみるとちゃんと表示されていた。
一つずつ作り上げていくのが楽しいと感じる。
댓글을 불러오는 중...