
Next.jsでのMeta設定について
今回は、Next.jsでも欠かせないMetaの設定方法を紹介していきます。
下記のような点を着目して、ご紹介していきたいと思います。
基本的な設定値と解説
Next.jsにおける静的ページと動的ページでのMeta設定方法
汎用性を考えた設定方法(個人的に設定している最適解)
下記、公式サイトのリンクになりますので、詳細が気になる方は、ご確認ください。
基本的な設定値と解説
通常のサイトと同じように、Next.js でもメタデータの設定を行います。以下のコードを例に、それぞれの設定値の意味を解説していきます。
import type { Metadata } from "next";
import { SITE_URL, SITE_TITLE, SITE_DESCRIPTION } from "@/config";
export const meta: Metadata = {
title: {
template: `%s | ${SITE_TITLE}`,
default: SITE_TITLE,
},
description: SITE_DESCRIPTION,
icons: {
icon: [
{
rel: "favicon",
url: "/favicon.ico",
},
{
rel: "icon",
url: "/icon.svg", // モダンブラウザ用
},
{
rel: "icon",
url: "/icon-192x192.png", //Android 用
},
{
rel: "icon",
url: "/icon-512x512.png", //Android 用
},
{
rel: "apple-touch-icon",
url: "/icon-180x180.png", //Apple デバイス用
},
],
},
openGraph: {
title: {
template: `%s`,
default: SITE_TITLE,
},
description: SITE_DESCRIPTION,
url: SITE_URL,
siteName: SITE_TITLE,
images: [
{
url: `${SITE_URL}/assets/ogp.jpg`,
width: 1200,
height: 630,
},
],
locale: "ja_JP",
type: "website",
},
};
※ここでは、SITE_SITE_TITLEとSITE_DESCRIPTION、SITE_URLは、configファイルで、共通設定しています。
import { SITE_URL, SITE_TITLE, SITE_DESCRIPTION } from "@/config";
configファイル
export const SITE_URL =
process.env.NODE_ENV === "production"
? process.env.NEXT_PUBLIC_SITE_URL ?? ""
: "http://localhost:3000";
export const SITE_TITLE = "サイト名が入ります";
export const SITE_DESCRIPTION = "デフォルトのディスクリプションが入ります";
では、一つ一つ解説していきたいと思います。
import type { Metadata } from "next";
まず、Next.js の Metadata 型をインポートし、型安全なメタデータの定義を行います。
title
title: {
template: `%s | ${SITE_TITLE}`,
default: SITE_TITLE,
},
「 template: `%s | ${SITE_TITLE}`」
templateで設定している「%s」は、下層ページ(ABOUTページ)では、「私たちについて | サイト名」という形で、ページごとにtitle情報を書き換えつつ、SITE_TITLEを継承することができます。
import type { Metadata } from "next";
import { metadata as defaultMetadata } from "@/app/layout";
const title = `私たちについて`;
const description =
"私たちについてのdescriptionです";
export const metadata: Metadata = {
title,
description,
openGraph: {
...defaultMetadata.openGraph,
title,
description,
},
};

icons
ブラウザやデバイスで使用するアイコンを設定します。
個人的は、下記5つの設定を推奨しています。
favicon.ico → 一般的なファビコン
icon.svg → モダンブラウザ用のアイコン
icon-192x192.png、icon-512x512.png → Android や PWA 用のアイコン
apple-touch-icon → iOS 用のホーム画面アイコン
<余談>
アイコン関連は public/配下に配置しても表示されません。
appディレクトリの直下に置くようにしてください。
apple-touch-iconでは、icon-180x180.pngを設定しています。
180x180サイズにしているのは、Configuring Web ApplicationsでRetinaのiPadで推奨されているサイズとなっており、最大で使用されるアイコンサイズで、設定しています。
openGraph
SNS でのシェア時に使用されるメタデータを設定します。
title, description → OGP 用のタイトルと説明
url → シェア時の URL
siteName → サイト名
images → OGP 画像の URL とサイズ
locale → 言語設定(ja_JP は日本語)
type → Web サイトの種類(通常 website)
Next.jsにおける静的ページと動的ページでのMeta設定方法
Next.jsでは、静的ページと動的にデータ取得をするページで、設定方法が違いますので、見ていきましょう。
静的ページでのMeta設定
静的なページでは、export const metadata を利用してMeta情報を設定できます。
下記が静的ページでの簡単な設定例になります。
※SITE_URLは適宜詳細設定してください。
export const metadata: Metadata = {
title: 'ページ名が入ります | サイト名が入ります',
description:
'ディスクリプションが入ります',
openGraph: {
title: 'ページ名が入ります | サイト名が入ります',
description:
'ディスクリプションが入ります',
url: "https://example.com/about/",
},
};
動的なページ(詳細ページなど)
ニュースの詳細ページなどCMS管理しているページでは、ページごとに異なるタイトルや説明を設定する必要があります。その場合、generateMetadata を使い、下記のように設定します。
import type { Metadata } from "next";
import { getPostBySlug } from "@/libs/api";
export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> {
const post = await getPostBySlug(params.slug);
return {
title: `${post.title} | ニュース`,
description: post.description,
openGraph: {
title: `${post.title} | ニュース`,
description: post.description,
url: "https://example.com/news/${params.slug}`,
images: [{
url: post.ogImage,
width: 1200,
height: 630,
}],
locale: "ja_JP",
type: "article",
},
};
}
汎用性を考えたMetaの設定方法
(個人的に設定している設定)
Meta設定は、ページごとに変更する部分、共通したい部分があると思います。その中で、共通設定した値を引き継ぎつつ、タイトルやディスクリプションなど、ページ固有の部分だけ変更するための設定方法の一例は、こちらになります。
libs/metadata/index.tsx
(共通で設定しておくファイル)
「基本的な設定値と解説」で解説していたコードになりますが、libs/metadata/index.tsxに共通の設定を記述しておきます。
import type { Metadata } from "next";
import { SITE_URL, SITE_TITLE, SITE_DESCRIPTION } from "@/config";
export const meta: Metadata = {
title: {
template: `%s | ${SITE_TITLE}`,
default: SITE_TITLE,
},
description: SITE_DESCRIPTION,
icons: {
icon: [
{
rel: "favicon",
url: "/favicon.ico",
},
{
rel: "icon",
url: "/icon.svg", // モダンブラウザ用
},
{
rel: "icon",
url: "/icon-192x192.png", //Android 用
},
{
rel: "icon",
url: "/icon-512x512.png", //Android 用
},
{
rel: "apple-touch-icon",
url: "/icon-180x180.png", //Apple デバイス用
},
],
},
openGraph: {
title: {
template: `%s`,
default: SITE_TITLE,
},
description: SITE_DESCRIPTION,
url: SITE_URL,
siteName: SITE_TITLE,
images: [
{
url: `${SITE_URL}/assets/ogp.jpg`,
width: 1200,
height: 630,
},
],
locale: "ja_JP",
type: "website",
},
};
app/layout.tsx
まずlayout.tsxで、libs/metadata/index.tsxで設定したmetadataをimportして、ページ側でMeta設定が無い場合、共通の設定値が反映されるようにしておきます。
import { meta } from "@/libs/metadata";
import Header from "@/components/ui/Header";
import Footer from "@/components/ui/Footer";
export const metadata = meta;
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ja">
<head></head>
<body>
<Header />
{children}
<Footer />
</body>
</html>
);
}

次に下層ページでの設定を見ていきます。
app/about/page.tsx
※ABOUTページの場合
layout.tsxのMeta設定を継承しつつ、About固有のtitle、descriptionを設定していきます。
import Heading from "@/components/ui/Heading";
import type { Metadata } from "next";
import { metadata as defaultMetadata } from "@/app/layout";
const title = `私たちについて`;
const description = "私たちについてのdescriptionです";
export const metadata: Metadata = {
title,
description,
openGraph: {
...defaultMetadata.openGraph,
title,
description,
},
};
export default function AboutPage() {
return (
<main className="main">
<div className="l-pagetitle">
<div className="l-pagetitle__inner">
<Heading hLevel={1} titleEn="ABOUT" titleJa="私たちについて" />
</div>
</div>
<section className="l-content">
<div className="l-content__inner">
ABOUT内容が入りますABOUT内容が入りますABOUT内容が入りますABOUT内容が入りますABOUT内容が入りますABOUT内容が入りますABOUT内容が入りますABOUT内容が入ります
</div>
</section>
</main>
);
}
OGP(Open Graph Protocol)や favicon などの設定は、共通の設定を継承するため、...defaultMetadata.openGraphで設定して、title、descriptionは、固有の値が反映されるようにしています。
const title = `私たちについて`;
const description = "私たちについてのdescriptionです";
export const metadata: Metadata = {
title,
description,
openGraph: {
...defaultMetadata.openGraph,
title,
description,
},
};
問題なく、設定が継承されていることが確認できます。

まとめ
いかがだったでしょうか?
何気なく静的構築や、Wordpressなどで設定していた方法とは違い、Next.jsでの独自の設定方法がありました。
今回紹介した方法は、一例になるため、構成によって、今回紹介した方法以外で設定する必要が出てくるかもしれませんが、抑えておくポイントは、同じになるため、ぜひみなさんに合った方法を見つけていただけると幸いです。
では良きNext.jsライフを!!