エリアページを作って検索導線を増やす【Art Navi開発記録 #10】
はじめに
こんにちは。
なかのひとカンパニーの archer です。
美術展検索サービス Art Navi の開発内容を、備忘録も兼ねて記事にしています。
- サービスURL: https://art-weekend.jp/
前回は、Next.jsで構造化データを入れる内容について書きました。
今回は、Art Naviで作成している エリアページ についてまとめます。
今回やりたいこと
Art Naviでは、美術館や展覧会を探しやすくするために、エリアごとのページを用意しています。
初期対象エリアは以下です。
- 上野
- 六本木
- 銀座
今回やりたいことは以下です。
- エリアごとのページを作る
- エリア内の展覧会を一覧表示する
- エリア内の施設へ移動できるようにする
- 検索流入の受け皿を増やす
- サイト内の回遊導線を増やす
展覧会詳細ページだけでなく、エリアページも作ることで、検索導線を増やす狙いがあります。
なぜエリアページを作るか
美術展を探すとき、必ずしも展覧会名で検索するとは限りません。
たとえば、以下のように探すことがあります。
上野 美術館
上野 展覧会
六本木 アート
銀座 ギャラリー
週末 美術館 東京
このような検索に対応するには、展覧会単体のページだけでなく、エリアごとのページがあると便利です。
エリアページがあると、ユーザーは以下のように探せます。
エリアページ
↓
そのエリアの施設一覧
↓
開催中の展覧会
↓
展覧会詳細
また、サイト内のページ同士をつなげることで、検索エンジンにもサイト構造を伝えやすくなります。
URL設計
エリアページのURLは、以下のような形にします。
/areas/[slug]
例です。
/areas/ueno
/areas/roppongi
/areas/ginza
Next.js App Routerでは、以下のようなディレクトリ構成になります。
app/
areas/
[slug]/
page.tsx
[slug] を使うことで、エリアごとの動的ページを作れます。
エリアデータの持ち方
エリア情報は、まずはシンプルなデータとして持ちます。
const areas = [
{
slug: "ueno",
name: "上野",
description:
"上野は、美術館や博物館が集まる東京有数の文化エリアです。",
},
{
slug: "roppongi",
name: "六本木",
description:
"六本木は、現代アートやデザイン系の展示に触れやすいエリアです。",
},
{
slug: "ginza",
name: "銀座",
description:
"銀座は、ギャラリーや商業施設内の展示を楽しみやすいエリアです。",
},
];
最初は固定データでも問題ありません。
MVP段階では、まずページとして成立させることを優先し、あとからDB管理に移すこともできます。
表示する情報
エリアページでは、以下の情報を表示する方針にしました。
- エリア名
- エリアの説明文
- そのエリアの展覧会一覧
- そのエリアの施設一覧
- 展覧会詳細ページへのリンク
- 施設詳細ページへのリンク
イメージとしては以下です。
上野の展覧会・美術館
上野エリアの説明文
開催中・開催予定の展覧会
- 展覧会A
- 展覧会B
上野の美術館・ギャラリー
- 施設A
- 施設B
エリアページ単体で完結させるのではなく、展覧会ページや施設ページへの入口として使います。
実装イメージ
エリアのslugをもとに、対象エリアの情報を取得します。
type Area = {
slug: string;
name: string;
description: string;
};
type Exhibition = {
id: number;
title: string;
areaSlug: string;
period: string;
};
type Venue = {
id: number;
name: string;
areaSlug: string;
};
const areas: Area[] = [
{
slug: "ueno",
name: "上野",
description:
"上野は、美術館や博物館が集まる東京有数の文化エリアです。",
},
];
const exhibitions: Exhibition[] = [
{
id: 1,
title: "印象派と光の表現",
areaSlug: "ueno",
period: "2026年6月1日〜2026年8月31日",
},
];
const venues: Venue[] = [
{
id: 1,
name: "上野の美術館",
areaSlug: "ueno",
},
];
export default function AreaPage({
params,
}: {
params: { slug: string };
}) {
const area = areas.find((item) => item.slug === params.slug);
if (!area) {
return <main>エリアが見つかりませんでした。</main>;
}
const areaExhibitions = exhibitions.filter(
(exhibition) => exhibition.areaSlug === area.slug
);
const areaVenues = venues.filter((venue) => venue.areaSlug === area.slug);
return (
<main>
<h1>{area.name}の展覧会・美術館</h1>
<p>{area.description}</p>
<section>
<h2>{area.name}の展覧会</h2>
{areaExhibitions.map((exhibition) => (
<article key={exhibition.id}>
<h3>{exhibition.title}</h3>
<p>{exhibition.period}</p>
<a href={`/exhibitions/${exhibition.id}`}>展覧会を見る</a>
</article>
))}
</section>
<section>
<h2>{area.name}の美術館・ギャラリー</h2>
{areaVenues.map((venue) => (
<article key={venue.id}>
<h3>{venue.name}</h3>
<a href={`/venues/${venue.id}`}>施設を見る</a>
</article>
))}
</section>
</main>
);
}
実際には、DBやデータファイルから取得する形にしてもよいです。
存在しないエリアへの対応
動的ページでは、存在しないslugにアクセスされた場合の対応も必要です。
Next.jsでは notFound() を使えます。
import { notFound } from "next/navigation";
export default function AreaPage({
params,
}: {
params: { slug: string };
}) {
const area = areas.find((item) => item.slug === params.slug);
if (!area) {
notFound();
}
return (
<main>
<h1>{area.name}の展覧会・美術館</h1>
</main>
);
}
存在しないURLをそのまま表示しないようにすることで、不要なページが増えるのを防げます。
generateStaticParamsを使う
エリアが固定で決まっている場合は、generateStaticParams を使って事前にページを生成できます。
export function generateStaticParams() {
return areas.map((area) => ({
slug: area.slug,
}));
}
これにより、以下のページを生成対象にできます。
/areas/ueno
/areas/roppongi
/areas/ginza
MVP段階では対象エリアが少ないため、固定のslugから生成する形でも十分だと考えています。
metadataを設定する
エリアページごとに、title と description も変えます。
export async function generateMetadata({
params,
}: {
params: { slug: string };
}) {
const area = areas.find((item) => item.slug === params.slug);
if (!area) {
return {
title: "エリアが見つかりません | Art Navi",
};
}
return {
title: `${area.name}の展覧会・美術館情報 | Art Navi`,
description: `${area.name}エリアで開催中・開催予定の展覧会や美術館情報を紹介します。`,
};
}
すべてのエリアページで同じtitleにするのではなく、エリア名を含めるようにしました。
上野の展覧会・美術館情報 | Art Navi
六本木の展覧会・美術館情報 | Art Navi
銀座の展覧会・美術館情報 | Art Navi
ページごとの内容が分かりやすくなります。
内部リンクを増やす
エリアページでは、内部リンクも意識しています。
たとえば、以下のようなリンクです。
トップページ
↓
エリアページ
エリアページ
↓
施設詳細ページ
エリアページ
↓
展覧会詳細ページ
施設詳細ページ
↓
エリアページ
ページ同士をつなげることで、ユーザーがサイト内を回遊しやすくなります。
また、検索エンジンにもページの関係性を伝えやすくなります。
サイトマップにも含める
エリアページを作ったら、sitemap.xml にも含めます。
const areaPages = areas.map((area) => ({
url: `${baseUrl}/areas/${area.slug}`,
lastModified: new Date(),
}));
サイトマップに含めることで、検索エンジンにエリアページの存在を伝えやすくなります。
Art Naviでは、展覧会詳細ページ・施設詳細ページ・エリアページをサイトマップに含める方針にしています。
構造化データも入れる
エリアページにも、パンくずの構造化データを入れます。
const breadcrumbJsonLd = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "ホーム",
item: "https://art-weekend.jp/",
},
{
"@type": "ListItem",
position: 2,
name: "エリア",
item: "https://art-weekend.jp/areas",
},
{
"@type": "ListItem",
position: 3,
name: area.name,
item: `https://art-weekend.jp/areas/${area.slug}`,
},
],
};
パンくずを入れることで、ページの階層を検索エンジンに伝えやすくなります。
気をつけたこと
エリアページを作るときに気をつけたことは以下です。
- エリア名だけの薄いページにしない
- 展覧会や施設へのリンクを入れる
- titleとdescriptionをエリアごとに変える
- 存在しないslugは404にする
- sitemap.xmlに含める
- パンくずの構造化データを入れる
特に、本文が少ないページを大量に作ると、検索流入向けのページとしては弱くなります。
そのため、エリア説明文や施設・展覧会への導線を用意するようにしました。
今後やりたいこと
エリアページについては、今後以下を改善したいです。
- エリア紹介文の充実
- 近隣エリアへのリンク
- 開催中・開催予定の表示切り替え
- ジャンルごとの絞り込み
- エリアごとのOGP画像
- エリアごとのおすすめ施設表示
- Google Search Consoleでの検索状況確認
まずは上野・六本木・銀座の3エリアから始めて、必要に応じて対象エリアを増やしていく予定です。
まとめ
今回は、Art Naviで作成しているエリアページについてまとめました。
今回のポイントは以下です。
- エリアごとのページを作る
- エリア内の展覧会や施設を表示する
- エリア名検索の受け皿を用意する
- 展覧会ページや施設ページへ内部リンクする
- metadata、サイトマップ、構造化データも合わせて整備する
エリアページを作ることで、展覧会詳細ページだけでは拾いにくい検索導線を増やしやすくなりました。
次回は、施設詳細ページを作ってSEO導線を増やす内容について書く予定です。