amp-list に構造化データのマークアップはできない
amp-list とは?
amp-list は、CORS JSON のエンドポイントから動的にデータを取得しリスト表示するための AMP コンポーネントです。
この amp-list は、amp-mustache を使いテンプレートを作成します。amp-mustache は、JavaScript テンプレートエンジンの mustache.js を AMP で使うためのコンポーネントです。
例えば、WordPress の WP REST API の場合、このような URL でアイキャッチ画像付きの最新記事データ 10 件を JSON 形式で取得できます。
https://firstlayout.net/wp-json/wp/v2/posts?_embed
この JSON のデータを取得するために、amp-mustache を使い amp-list をこのように書いてみます。
<amp-list
height="400"
layout="fixed-height"
src="https://firstlayout.net/wp-json/wp/v2/posts?_embed"
items=".">
<template type="amp-mustache">
<a href="{{link}}">
<h2>{{title.rendered}}</h2>
</a>
</template>
</amp-list>
すると、最新 10 件のリンク付き記事タイトルのリストができあがります。
amp-list には refresh
というアクションが用意されており、JSON から取得したデータの初期化と再表示が可能です。データは動的に取得するため、データの再表示の際にブラウザの再読み込みがありません。
また、amp-bind と組み合わせれば、別の JSON からデータを取得し直して再表示ができます。
使いどころは、このような場面です。
- ログインユーザーに対し、パーソナライズされた関連記事やおすすめ商品の表示。
- ページにアクセスする度、またはボタンをクリックする度に、関連記事やおすすめ商品をランダムに表示。
- 頻繁にコンテンツを公開するサイトで、常に最新のリストを表示。
- ユーザーが条件を指定し、表示中のコンテンツを絞り込む。
アイデア次第で、他にも使う場面は多くあると思います。
Microdata や meta タグが出力されない
そして、ここからが本題です。
この amp-list に、schema.org での構造化データのマークアップができない問題にぶつかりました。少なくとも私には、マークアップする方法が分かりません。
例えば、amp-list で出力するのは、記事のリストだとします。その出力される各記事に、schema.org で構造化データをマークアップしたいとします。
そこで、このように Microdata で書いたとします。画像のマークアップには、<meta>
タグを使います。
<amp-list
height="400"
layout="fixed-height"
src="https://firstlayout.net/wp-json/wp/v2/posts?_embed"
items=".">
<template type="amp-mustache">
<a href="{{link}}">
<article itemscope itemtype="https://schema.org/CreativeWork">
<div
itemprop="image"
itemscope
itemtype="https://schema.org/ImageObject">
<amp-img
alt="{{_embedded.wp:featuredmedia.0.alt_text}}"
src="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.source_url}}"
width="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.width}}"
height="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.height}}"
layout="responsive"></amp-img>
<meta
itemprop="url"
content="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.source_url}}" />
<meta
itemprop="width"
content="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.width}}" />
<meta
itemprop="height"
content="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.height}}" />
</div>
<h2 itemprop="headline">{{title.rendered}}</h2>
</article>
</a>
</template>
</amp-list>
各記事の HTML は、当然このようなものを期待します(<a>
タグに target 属性や role 属性があるのは、amp-list が自動的につけるためです)。
<a href="記事のURL" target="_top" role="listitem">
<article itemscope itemtype="https://schema.org/CreativeWork">
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<amp-img
alt="画像のalt"
src="画像のURL"
width="画像の幅"
height="画像の高さ"
layout="responsive"></amp-img>
<meta itemprop="url" content="画像のURL" />
<meta itemprop="width" content="画像の幅" />
<meta itemprop="height" content="画像の高さ" />
</div>
<h2 itemprop="headline">記事タイトル</h2>
</article>
</a>
しかし、実際に出力される HTML をデベロッパーツールで見るとこうなります。
<a href="記事のURL" target="_top" role="listitem">
<article>
<div>
<amp-img
alt="画像のalt"
src="画像のURL"
width="画像の幅"
height="画像の高さ"
layout="responsive"></amp-img>
</div>
<h2>記事タイトル</h2>
</article>
</a>
Microdata や <meta>
タグが出力されません。
調べてみると、Microdata や <meta>
タグが出力されないのは、2018 年夏にバージョンアップされた amp-mustache が原因のようです(2018 年夏以前までは出力できた)。
JSON-LD が認識されない
であれば、「JSON-LD だとどうかな?」と試してみました。
<amp-list
height="400"
layout="fixed-height"
src="https://firstlayout.net/wp-json/wp/v2/posts?_embed"
items=".">
<template type="amp-mustache">
<a href="{{link}}">
<article>
<amp-img
alt="{{_embedded.wp:featuredmedia.0.alt_text}}"
src="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.source_url}}"
width="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.width}}"
height="{{_embedded.wp:featuredmedia.0.media_details.sizes.full.height}}"
layout="responsive"></amp-img>
<h2>{{title.rendered}}</h2>
</article>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "CreativeWork",
"headline": "{{title.rendered}}",
"image": {
"@type": "ImageObject",
"url": "{{{_embedded.wp:featuredmedia.0.media_details.sizes.full.source_url}}}",
"width": "{{_embedded.wp:featuredmedia.0.media_details.sizes.full.width}}",
"height": "{{_embedded.wp:featuredmedia.0.media_details.sizes.full.height}}"
}
}
</script>
</a>
</template>
</amp-list>
すると、デベロッパーツールで見る限り、JSON-LD が出力されました。
ただ、スキーマ マークアップ検証ツール で検証すると、実際のデータが認識されません。
Stack Overflow の Q&A
スキーマ マークアップ検証ツールに実際のデータを認識させるには、<head>
内などに JSON-LD を書けばいいはずです。
しかし、どうやったら amp-list の中にある {{title.rendered}}
などを取得し、amp-list の外にある JSON-LD に反映できるのか?
方法が分からないため Google で調べると、Stack Overflow の AMP JSON-LD dynamic content を見つけました。
この Q&A の回答者は、AMP プロジェクトに携わっている Google のエンジニアさん。最高の回答者です。
以下は、Q&A の意訳です。
質問:<head>
内で amp-list の JSON-LD を書きたい。どうすれば <head>
内で {{title.rendered}}
などを取得できますか?
回答:Microdata が使えます。(※訳注:この時点では amp-mustache で Microdata を出力できたみたい)
質問:JSON-LD で書きたい場合は、どうすればいいですか?
回答:JSON-LD では無理です。
無理でした。この Q&A から 1 年以上が経ちますが、まだできる方法はないはずです。amp-list で出力するコンテンツに対し、マークアップするのは諦めました。
おわりに
amp-list で出力するデータへの構造化データのマークアップ方法がお分かりになる方は、是非やり方を教えて下さい。
いくら考えても、表示するデータがランダムの時や amp-list の無限スクロールを使う時のマークアップ方法が分かりません。
尚、WordPress に amp-list の無限スクロールを実装する方法は、WordPress の AMP ページに amp-list の無限スクロールを実装する方法 にて解説しています。