amp-list に構造化データのマークアップはできない

amp-listにschema.orgでの構造化データマークアップは不可能

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を「見やすさ」と「使いやすさ」にこだわり紹介しています。

カノニカル AMP( AMP ページしかないサイト)を作っている過程で、amp-list を使いました。

この amp-list に、schema.org での構造化データのマークアップができない問題にぶつかりました。

少なくとも私には、マークアップする方法がまったく分かりません。

そのことについて、書いてみたいと思います。

amp-list って何?

amp-list は、CORS JSON のエンドポイントから動的にデータを取得し表示するための拡張コンポーネントです。

この amp-list は、amp-mustache を使いテンプレートを作成します。

amp-mustache は、JavaScript テンプレートエンジンの mustache.js を AMP で使うためのもの。

例えば、このブログは WordPress を使っているので、こんな URL でアイキャッチ画像付きの最新記事データ 10 件を JSON 形式( WP REST API )で取得できます。

https://firstlayout.net/wp-json/wp/v2/posts?_embed

で、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 件のリンク付き記事タイトルのリストができあがります。

WP REST APIから取得したデータをamp-listで表示した例

amp-list には refresh というアクションが用意されていて、JSON から取得したデータの初期化と再表示が可能。

また、amp-bind と組み合わせると、別の JSON からデータを取得し直して再表示ができます。

amp-list は動的にデータを取得するので、データの再表示の際にブラウザの再読み込みがありません。

これがすごくいい!

使いどころは、こんな場面です。

  • ログインユーザーに対し、パーソナライズされた関連記事やおすすめ商品の表示
  • ページにアクセスする度、またはボタンをクリックする度に、関連記事やおすすめ商品をランダムに表示
  • 頻繁にコンテンツを公開するサイトで、常に最新のリストを表示
  • ユーザーが条件を指定し、表示中のコンテンツを絞り込む

アイデア次第で、他にもまだまだ使う場面はあります。

Microdata や meta タグが出力されない

で、ここからが本題。

amp-list で出力するのは、記事のリスト。

出力される各記事に、schema.org で構造化データをマークアップしたい。

そこで、こんな感じに Microdata で書いたとします。画像のマークアップには、<meta> タグを使います。

WP REST API は、画像データの階層が深い…。

<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 が原因のようです。

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 が出力されました。

デベロッパーツールで確認できるJSON-LD

ただ、構造化データテストツールで検証すると、実際のデータが認識されません。

構造化データテストツールで認識されないJSON-LD

問題を解決できず

構造化データテストツールに実際のデータを認識させるには、<head> 内などに JSON-LD を書けばいいはずです。

しかし、どうやったら amp-list の中にある {{title.rendered}} などを取得し、amp-list の外にある JSON-LD に反映できるのか?

方法が分からないので Google で調べると、Stack Overflow の Q&A を教えてくれました。

AMP JSON-LD dynamic content – Stack Overflow

この Q&A の回答者は、AMP プロジェクトに携わっている Google のエンジニアさん。最高の回答者!

以下、博多弁での Q&A の意訳。

質問:<head> 内で amp-list の JSON-LD を書きたいっちゃんね。どうすれば <head> 内で {{title.rendered}} とか取得できると?

回答:Microdata でマークアップするといいっちゃない?(※訳注:この時点では amp-mustache で Microdata を出力できたみたい)

質問:そうっちゃけど JSON-LD で書きたいと。

回答:JSON-LD では無理とです…。

OK Google!無理ね!

だって、Google のエンジニアさんが方法はないって言ってるんだもん。

この Q&A から 1 年以上が経ちますが、まだできる方法はないはず。

amp-list で出力するコンテンツに、マークアップするのは諦めました。

バージョンアップに期待

ただ、希望はあります。

それは、amp-list のバージョンアップが予定されていること。

参考amp-list v2

バージョンアップの内容の 1 つに、Support refresh/push と書いてあります。

refresh は今でもできます。ただ、push はできません。

この push が何を指しているのか不明ですが、JSON から取得したデータを push できるようになれば、amp-list の外からでもデータにアクセスできるはず。

そうなれば、<head> 内で amp-list の JSON-LD を書ける。

単なる期待に過ぎませんが、バージョンアップを気長に待ってみたいと思います。