これはなに
Hugoで作ったサイトをJSON-LD方式の構造化データに対応するためしたことのまとめ。
構造化データとは
構造化データとは、簡単に言うとウェブページの詳細をGoogleなどの検索エンジンに教えるためのデータである。 データには、たとえばタイトル、日付、記事の種類などが含まれる。
Google検索セントラルの「構造化データのマークアップの仕組み概要」 によると、構造化データの追加はGoogleに対するSEOの1つでもあるようだ。 少なくともGoogleでは、Google検索でリッチリザルトとして表示されるために、構造化データが必要である。
構造化データの形式
構造化データには複数の形式がある。 Google検索セントラル によると、Googleでは下記3種類の形式がサポートされている。
- JSON-LD(Google推奨)
- microdata
- RDFa
また、構造化データの中にも種類がある。 Google 検索セントラルの「Google 検索がサポートする構造化データ マークアップ」 あたりが参考になるだろう。 今回は 「Article 」 「パンくずリスト(BreadcrumbList) 」 「WebSite 」 の3つを利用する。
HugoのサイトをJSON-LD方式の構造化データに対応させる方法
本記事では、Googleが推奨しているJSON-LDの形式で、Hugoのサイトを構造化データに対応させる。 流れは下記のとおりである。
- schema.htmlを作成する
- schema.htmlをサイトに埋め込む
- 構造化データが正常に作成されているか確認する
schema.htmlを作成する
layouts/partials/
下にschema.html
を作成する。
このschema.html
に、<script type="application/ld+json">
で始まる構造化データスクリプト記述を記述する。
たとえば、Google検索セントラル
によると、
サイトの記事(Article)には下記の構造化データが推奨されている。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "NewsArticle",
"headline": "Title of a News Article",
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"datePublished": "2015-02-05T08:00:00+08:00",
"dateModified": "2015-02-05T09:20:00+08:00",
"author": [{
"@type": "Person",
"name": "Jane Doe",
"url": "https://example.com/profile/janedoe123"
},{
"@type": "Person",
"name": "John Doe",
"url": "https://example.com/profile/johndoe123"
}]
}
</script>
これをHugoの変数 を用いて 各記事に適応できるように変更すると、次のようになる。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": {{ .Title }},
"image": {{ .Page.Params.image | absURL }},
"datePublished": {{ .PublishDate }},
"dateModified": {{ .Lastmod }},
"author": {
"@type": "Person",
"name": {{ .Site.Author.name }},
"url": {{ .Site.Author.url }}
}
}
</script>
ただし、下記のように記事のfront matterにtitle
、date
、image
が定義されているものとする1。
---
title: Example
date: 2022-12-28T09:58:07+09:00
image: test/sample.webp
---
## タイトル
記事の内容
また、config.yamlに、次のようにauthor
が定義されているものとする2。
author:
name: NakuRei
url: https://twitter.com/nakurei7901
ここでさらに、記事のページにパンくずリスト(BreadcrumbList) の構造化データを加える。 Google検索セントラル によると、 パンくずリストで推奨されている構造化データは次のとおりである。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": "Books",
"item": "https://example.com/books"
},{
"@type": "ListItem",
"position": 2,
"name": "Science Fiction",
"item": "https://example.com/books/sciencefiction"
},{
"@type": "ListItem",
"position": 3,
"name": "Award Winners"
}]
}
</script>
これをHugoの変数 を用いて 各記事に適応できるように変更すると、次のようになる。
<script type="application/ld+json">
{{ if .Page.Params.categories }}
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": {{ index .Page.Params.categories 0 }},
"item": {{ path.Join (.Site.BaseURL) ("/categories/" | relLangURL) (index .Page.Params.categories 0 | urlize) }}
}]
}
{{ end }}
</script>
{{ if .Page.Params.categories }}
で囲むことで、このパンくずリストの記述は、記事のfront matterにcategories
が定義されているときだけ反映される。
また、下記のように複数カテゴリが記述されている場合、最初の1つだけが利用されるようにしている。
---
categories: [Example1, Example2]
---
これら2つの構造化データ記述をまとめると下記のようになる。
<script type="application/ld+json">
[
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": {{ .Title }},
"image": {{ .Page.Params.image | absURL }},
"datePublished": {{ .PublishDate }},
"dateModified": {{ .Lastmod }},
"author": {
"@type": "Person",
"name": {{ .Site.Author.name }},
"url": {{ .Site.Author.url }}
},
},
{{ if .Page.Params.categories }}
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": {{ index .Page.Params.categories 0 }},
"item": {{ path.Join (.Site.BaseURL) ("/categories/" | relLangURL) (index .Page.Params.categories 0 | urlize) }}
}]
}
{{ end }}
]
</script>
ところで、上記<script>
タグのままだと、記事以外のページもBlogPosting扱いになってしまう。
そのため、記事にだけBlogPostingの構造化データが適用されるように、Hugoの変数IsPage
を利用する。
<script type="application/ld+json">
[
+ {{ if .IsPage }}
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": {{ .Title }},
"image": {{ .Page.Params.image | absURL }},
"datePublished": {{ .PublishDate }},
"dateModified": {{ .Lastmod }},
"author": {
"@type": "Person",
"name": {{ .Site.Author.name }},
"url": {{ .Site.Author.url }}
},
},
{{ if .Page.Params.categories }}
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": {{ index .Page.Params.categories 0 }},
"item": {{ path.Join (.Site.BaseURL) ("/categories/" | relLangURL) (index .Page.Params.categories 0 | urlize) }}
}]
}
{{ end }}
+ {{ end }}
]
</script>
記事以外のページには、WebSite の構造化データを適用する。 Google検索セントラル によると、 WebSiteで推奨されている構造化データは下記のとおりである。
<script type="application/ld+json">
{
"@context" : "https://schema.org",
"@type" : "WebSite",
"name" : "Example",
"url" : "https://example.com/"
}
</script>
これをHugoの変数 を用いて 各記事に適応できるように変更すると、次のようになる。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": {{ .Site.Title }},
"url": {{ .Site.BaseURL }},
}
</script>
ただし、config.yamlに、次のようにtitle
とbaseurl
が定義されているものとする3。
title: Examole Site Title
baseurl: https://example.com
以上すべての構造化データをまとめると、layouts/partials/schema.html
には下記を記述することになる。
<script type="application/ld+json">
[
{{ if .IsPage }}
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": {{ .Title }},
"image": {{ .Page.Params.image | absURL }},
"datePublished": {{ .PublishDate }},
"dateModified": {{ .Lastmod }},
"author": {
"@type": "Person",
"name": {{ .Site.Author.name }},
"url": {{ .Site.Author.url }}
}
},
{{ if .Page.Params.categories }}
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": {{ index .Page.Params.categories 0 }},
"item": {{ path.Join (.Site.BaseURL) ("/categories/" | relLangURL) (index .Page.Params.categories 0 | urlize) }}
}]
},
{{ end }}
{{ else }}
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": {{ .Site.Title }},
"url": {{ .Site.BaseURL }}
}
{{ end }}
]
</script>
schema.htmlをサイトに埋め込む
つくったschema.htmlをサイトに埋め込む。
<head>
タグ内か、<body>
タグの下部に埋め込めばよい。
<head>
...
...
<!-- json-ld -->
{{- partial "schema.html" . -}}
<!-- json-ld -->
</head>
筆者の使っているHugoのテーマStack
では、layouts/partials/head/custom.html
に追加したい内容を記述すれば、
<head>
タグ内に自動で追記してくれる。
よって、layouts/partials/head/custom.html
にschema.htmlを読み込む記述を書く。
{{- partial "schema.html" . -}}
構造化データが正常に作成されているか確認する
構造化データが作成されているかは、 Google 検索セントラルの構造化データ マークアップテストサイト で確認できる。
- リッチリザルト テスト : Googleのリッチリザルトに対応している構造化データを確認できる
- スキーマ マークアップ検証ツール : すべての構造化データを確認できる