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

Akira

福岡在住の Web デザイナー。Web サイト制作に役立つ情報を紹介しています。AMP が大好き。

FacebookTwitter で記事の更新をお知らせしています。

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

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

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

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

amp-list って何?

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

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

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 が原因のようです(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 が出力されました。

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

問題を解決できず

構造化データテストツールに実際のデータを認識させるには、<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 のバージョンアップが予定されていること。

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

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

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

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

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

おわりに

amp-list で出力するデータへの構造化データのマークアップ方法がお分かりになる方は、是非やり方を教えて下さい。

いくら考えても、表示するデータがランダムの時や amp-list の無限スクロールを使う時のマークアップ方法が分からない…。

ちなみに、WordPress に amp-list の無限スクロールを実装する方法は、WordPress の AMP ページに amp-list の無限スクロールを実装する方法にて解説しています。

送信に失敗しました

ボットと判定された可能性があります。

大変お手数をおかけしますが、以下の内容をご確認の上、再度のコメントの送信をお願い申し上げます。