0
0

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で構造化データを入れる【Art Navi開発記録 #9】

0
Posted at

Next.jsで構造化データを入れる【Art Navi開発記録 #9】

はじめに

こんにちは。
なかのひとカンパニーの archer です。

美術展検索サービス Art Navi の開発内容を、備忘録も兼ねて記事にしています。

前回は、sitemap.xmlrobots.txt を整備した内容について書きました。

今回は、Art Naviで対応した 構造化データ についてまとめます。

今回やりたいこと

Art Naviでは、展覧会ページや施設ページを検索エンジンに正しく伝えるために、構造化データを入れる方針にしました。

今回やりたいことは以下です。

  • JSON-LDで構造化データを出力する
  • WebSite情報を伝える
  • パンくず情報を伝える
  • 展覧会ページや施設ページに応用できる形にする

構造化データを入れることで、検索エンジンにページの意味を伝えやすくなります。

構造化データとは

構造化データは、ページ内の情報を検索エンジンが理解しやすい形で伝えるためのデータです。

通常のHTMLだけでもページ内容は伝わりますが、構造化データを使うことで、以下のような情報をより明確に伝えられます。

  • このサイトは何のサイトか
  • このページは何のページか
  • パンくずの階層はどうなっているか
  • 展覧会名や会場名は何か
  • 施設名や住所は何か

Art Naviでは、まずSEOの基本対応として、JSON-LD形式で構造化データを出力することにしました。

JSON-LDで出力する

構造化データはいくつか書き方がありますが、今回はJSON-LDを使います。

Next.jsでは、script タグで以下のように出力できます。

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
    __html: JSON.stringify(jsonLd),
  }}
/>

dangerouslySetInnerHTML という名前は少し怖いですが、JSON-LDを出力するときによく使う形です。

外部入力をそのまま埋め込む場合は注意が必要ですが、自分で生成したJSONを出す用途で使っています。

WebSiteの構造化データ

まずは、サイト全体を表す WebSite の構造化データを入れます。

const websiteJsonLd = {
  "@context": "https://schema.org",
  "@type": "WebSite",
  name: "Art Navi",
  url: "https://art-weekend.jp/",
  description: "美術館や展覧会をエリア・ジャンルから探せるWebサービスです。",
};

ページ内では以下のように出力します。

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
    __html: JSON.stringify(websiteJsonLd),
  }}
/>

これで、検索エンジンに対してArt NaviがWebサイトであることを伝えられます。

パンくずの構造化データ

次に、パンくずリストを表す BreadcrumbList を入れます。

たとえば、展覧会詳細ページでは以下のような階層を想定しています。

ホーム
  ↓
展覧会一覧
  ↓
展覧会詳細

JSON-LDでは以下のように書きます。

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/exhibitions",
    },
    {
      "@type": "ListItem",
      position: 3,
      name: "展覧会詳細",
      item: "https://art-weekend.jp/exhibitions/1",
    },
  ],
};

パンくずは、ページの階層構造を検索エンジンに伝えるために使います。

Art Naviでは、展覧会詳細ページや施設詳細ページで特に重要だと考えています。

コンポーネント化する

毎回 script タグを書くと重複するため、JSON-LD出力用のコンポーネントを用意しました。

type JsonLdProps = {
  data: Record<string, unknown>;
};

export function JsonLd({ data }: JsonLdProps) {
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{
        __html: JSON.stringify(data),
      }}
    />
  );
}

使う側では、以下のように書けます。

<JsonLd data={breadcrumbJsonLd} />

共通コンポーネントにしておくと、ページごとに構造化データを追加しやすくなります。

展覧会詳細ページで使う

展覧会詳細ページでは、パンくずの構造化データを動的に生成します。

const exhibition = {
  id: 1,
  title: "印象派と光の表現",
};

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/exhibitions",
    },
    {
      "@type": "ListItem",
      position: 3,
      name: exhibition.title,
      item: `https://art-weekend.jp/exhibitions/${exhibition.id}`,
    },
  ],
};

ページ内では以下のように出力します。

<JsonLd data={breadcrumbJsonLd} />

展覧会名をパンくずの最後に入れることで、ページごとの内容に合わせた構造化データになります。

施設詳細ページで使う

施設詳細ページでも同じようにパンくずを生成できます。

const venue = {
  id: 1,
  name: "上野の美術館",
};

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/venues",
    },
    {
      "@type": "ListItem",
      position: 3,
      name: venue.name,
      item: `https://art-weekend.jp/venues/${venue.id}`,
    },
  ],
};

Art Naviでは、展覧会ページだけでなく、施設ページも検索流入の入口にしたいと考えています。

そのため、施設詳細ページにも構造化データを入れていく方針です。

URLは絶対URLにする

構造化データ内のURLは、相対URLではなく絶対URLで書くようにしました。

OK:
https://art-weekend.jp/exhibitions/1

NG:
/exhibitions/1

サイト全体で使うため、ベースURLは定数化しておくと便利です。

const BASE_URL = "https://art-weekend.jp";

本番URLを複数箇所に直接書くと変更に弱くなるため、最終的には環境変数や共通設定に寄せたいです。

確認方法

構造化データを入れたら、ページのHTMLにJSON-LDが出力されているか確認します。

ブラウザの開発者ツールで、以下のようなタグが出ていればOKです。

<script type="application/ld+json">
  ...
</script>

また、構造化データの形式に問題がないか確認するために、Googleのリッチリザルトテストなどでチェックします。

確認するときは、公開URLを入力します。

https://art-weekend.jp/
https://art-weekend.jp/exhibitions/1

エラーが出た場合は、JSON-LDの構造や必須項目を見直します。

気をつけたこと

構造化データを入れるときに気をつけたことは以下です。

  • JSONとして壊れていないこと
  • URLは絶対URLにすること
  • 存在しないURLを入れないこと
  • ページ内容と違う情報を入れないこと
  • パンくずの順番を正しくすること
  • 動的ページではページごとの値を使うこと

特に、ページに表示していない情報や、実態と違う情報を構造化データに入れないように注意しました。

SEO目的でも、ページ内容と一致していることが大事だと考えています。

今後やりたいこと

今後は、以下の構造化データも検討したいです。

  • 展覧会ページ用の構造化データ
  • 美術館・ギャラリーなど施設ページ用の構造化データ
  • エリアページ用の構造化データ
  • OGP画像との整合性確認
  • Search Consoleでの検出状況確認

まずは、WebSiteBreadcrumbList を入れて、土台を作るところから進めています。

まとめ

今回は、Art Naviで対応した構造化データについてまとめました。

今回のポイントは以下です。

  • 構造化データはJSON-LDで出力する
  • Next.jsでは script type="application/ld+json" を使う
  • 共通の JsonLd コンポーネントを作ると使いやすい
  • WebSite でサイト全体の情報を伝える
  • BreadcrumbList でページ階層を伝える
  • URLは絶対URLで書く
  • ページ内容と一致した情報を入れる

SEOはすぐに効果が出るものではありませんが、サイト構造を検索エンジンに伝えるための土台として、早めに整備しておきたい部分だと感じました。

次回は、エリアページを作って検索導線を増やす内容について書く予定です。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?