【AMP】記事系コンテンツで使いそうなAMP対応のメモ

  • 19
    Like
  • 0
    Comment

本当はお遊びで「ゴジラがどのゴジラか分類してみた」「ゴジラの出没地を予測してみた」というネタを書こうとしていました。@s-moriです。
ミレニアムシリーズが好きです。

今年から本格稼働していたAMPですが、徐々にAMP化されたページの露出が増えてきています。
そんな中、AMPの仕様を理解していなかったためにバリデーションエラーが発生しまくっていたという現実にぶつかり大ダメージを受けたので、自戒の念を込めて簡単にまとめておこうかと思います。
AMPのタグ等、対応全部まとめると超大作になってしまうので、AMP対応の基本+記事系コンテンツで使いそうなSNSボタン、埋め込みwidget系、GA系に絞っています。

そもそもの「AMPとは」という部分は公式より引用。

AMP HTML は、パフォーマンスを保証するための制約が設けられた HTML で、 通常の HTML より優れたリッチ コンテンツを作成できる拡張機能が備わっています。 そして AMP HTML ページのレンダリングを高速化するのが、AMP JS ライブラリです。 Google AMP Cache は(必要に応じて)AMP HTML ページを配信します。
AMPとは

HTMLをAMP化する

AMP HTMLページの作成

AMP > Tutorials > Create Your AMP HTML Pageにサンプルがあります。ので、まるっと拝借。

<!-- DOCTYPE宣言 -->
<!doctype html>
<!-- <html amp>でAMPページということを示す -->
<html amp lang="en">
  <head>
    <!-- headタグの最初の子要素で文字コードを指定 -->
    <meta charset="utf-8">
    <title>Hello, AMPs</title>
    <!-- canonicalで表示しているAMPページの元となるHTMLページのURLを指定。なければ自身のURLを指定 -->
    <link rel="canonical" href="http://example.ampproject.org/article-metadata.html" />
    <!-- 表示領域の設定 -->
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <!-- schema.orgの構造化マークアップ -->
    <script type="application/ld+json">
      {
        "@context": "http://schema.org",
        "@type": "NewsArticle",
        "headline": "Open-source framework for publishing content",
        "datePublished": "2015-10-07T12:02:41Z",
        "image": [
          "logo.jpg"
        ]
      }
    </script>
    <!-- ampのstyle -->
    <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
    <!-- headタグの最後の要素に設定。AMP JSライブラリの読み込み -->
    <script async src="https://cdn.ampproject.org/v0.js"></script>
  </head>
  <body>
    <h1>Welcome to the mobile web</h1>
  </body>
</html>

下記項目は必須のようです。

  • DOCTYPE宣言の<!doctype html>
  • AMP記事と示す<html amp>
  • 文字コードの<meta charset="utf-8">
  • 何もしないと重複コンテンツと見なされる場合もあるので、元記事を示すcanonical設定の<link rel="canonical">
  • レスポンシブにするために表示領域を設定する<meta name="viewport">
  • AMPで指定されているstyleの<style amp-boilerplate>
  • AMP JSライブラリの<script async src="https://cdn.ampproject.org/v0.js"></script>

構造化マークアップについては、スマホのGoogle検索結果に表示されるトップニュースへ配信する場合などは必要になります。

また、AMP記事でコメントアウトは利用できないので、上記コードをそのままコピペするとエラーになります :frowning:

validationチェック

AMPのバリデーションチェック方法は4つあります。

開発環境で確認できる&手軽な、開発者コンソールでの確認or拡張機能が良さそうな気がしています。
上記以外にも、Google Search Consoleを利用する方法もあるようです。

参考:使いやすく新登場、Web版「AMPテストツール」活用法
ドキュメント:AMP > Guides > validate AMP Pages

また、(手遅れ感がありますが)AMPのエラーページに表示される「Debug original page.」からデバッグすることもできます。
amp_valid_error.png
(エラーページはこんな悲しい画面が…)

CSS

CSSは通常の<style>でなく<style amp-custom>の中に記述します。
<style amp-custom>が使えるのはファイル内に1回のみ。

<!-- ex. <style amp-custom> -->
<head>
  <meta charset="utf-8">
  ...省略...
  <style amp-custom>
    a {
      color: #333;
      font-size: 14px;
    }
    a:hover {
      opacity: .8;
    }
  </style>
  ...省略...
</head>

また、<link rel="stylesheet">は特定のフォントを利用するとき以外は使えないので、基本的には外部のCSSファイルを読み込めません。
sassなど、プリプロセッサを利用する場合は下記のように<style amp-custom>内にincludeすることで利用できるようです。

<style amp-custom>
  {% include "/assets/css/main.min.css" %}
</style>

Railsだとこのような方法も:RailsアプリのAMP対応をSassで快適に

そのほかCSSの制約(よく使いそうなところ)

要素 制約 ex
!important 使えない :heavy_multiplication_x: img{ width: 100% !important; }
擬似クラス amp-から始まらないタグには使える :heavy_multiplication_x: amp-img:hover{ opacity: .8; }
:o: img:hover{ opacity: .8; }
behavior, -moz-binding セキュリティ的な理由で使えない
-amp-i-ampから始まるクラス/ID AMPの予約語等として使われているので設定できない

など。ほかにもあります。
ドキュメント:AMP > Guides > Styling&Layout > Supported CSS

フォント

外部のフォントを利用する方法は2つあります。
1. <link>タグを利用する
2. @font-faceを利用する

1.linkタグ

<link>タグを利用する場合は普段Webフォントを利用するときと同じイメージ。

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">

ただし、利用できるフォントに制限があり、現時点では下記のみ対応しています(この制限があるので外部CSSが利用できない)

2.font-face

@font-faceを利用する場合は制限はないようです。

<style amp-custom>
  @font-face {
    font-family: "Bitstream Vera Serif Bold";
    src: url("https://somedomain.org/VeraSeBd.ttf");
  }

  body {
    font-family: "Bitstream Vera Serif Bold", serif;
  }
</style>

ドキュメント:AMP > Guides > Styling&Layout > Custom fonts

HTMLタグ

pタグやaタグなど、HTMLタグそのまま利用できるものもありますが、いくつかのHTMLタグはAMP用のタグに変換する必要があります。

imgタグ

<img><amp-img>へ変換します。

  • 変換
    width,height(,layout)を指定する
<img src="hoge.jpg"><amp-img src="hoge.jpg" width="264" height="96"></amp-img>

amp-imgタグでは画像サイズの指定が必須になります。
「いい感じ」に表示させようとするとちょっと考えてしまうところですが、下記記事が参考になりました。
参考:サイズのわからない画像のAMP対応
ドキュメント:AMP > Guides > Include images & Video

iframe

GoogleMapの埋め込みなど、<iframe><amp-iframe>へ変換します。

  • <head>内で読み込むライブラリ
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
  • 変換
    sandboxlayout を追加
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3159.4501403248655!2d140.36441641531366!3d37.63861997978452!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x5f8a9ef672ca6aa3%3A0xc13457f76f17515b!2z5p2x5YyX44K144OV44Kh44Oq44OR44O844Kv!5e0!3m2!1sja!2sjp!4v1481616609367" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe><!-- srcが長いので改行 -->
<amp-iframe
  src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3159.4501403248655!2d140.36441641531366!3d37.63861997978452!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x5f8a9ef672ca6aa3%3A0xc13457f76f17515b!2z5p2x5YyX44K144OV44Kh44Oq44OR44O844Kv!5e0!3m2!1sja!2sjp!4v1481616609367"
  width="600"
  height="450"
  sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
  layout="responsive"
  frameborder="0"
></amp-iframe>

ドキュメント:AMP > Guides > Include Iframes

iframe(case. YouTube)

YouTubeの埋め込みiframeの場合は、<amp-youtube>があるのでそちらに変換

  • <head>内で読み込むライブラリ
<script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
  • 変換
    iframeのsrcに 動画のリンク があるので、そこから動画IDを取得して amp-youtubeタグ の data-videoid属性 に設定する layoutを追加
    frameborderallowfullscreenは使えないので削除(もしくはdata-param-frameborderなどにする)
<iframe width="560" height="315" src="https://www.youtube.com/embed/YOUTUBE_VIDEO_ID" frameborder="0" allowfullscreen></iframe><amp-youtube data-videoid="YOUTUBE_VIDEO_ID" layout="responsive" width="560" height="315"></amp-youtube>

ドキュメント:AMP > Reference > Components/Tags > amp-youtube

属性

  • onclickonmouseoverなど、on〜系の属性は利用できない
  • (タグによって)name属性、style属性は利用できない

などなど

SNSボタン

SNSボタンはすべてamp-social-shareタグになります。
AMP側であらかじめ設定されているサービスは、type属性でサービス(twitterやfacebookなど)を指定するだけで利用できます。
type属性で指定できないものは、data-share-endpoint属性にURLを設定することで利用できるようになるようです。

Twitterのdata-viaなど、シェア時に渡す属性があればdata-param-viaなど、data-param-xxxの形で記述することができます。

  • <head>内で読み込むライブラリ
<script async custom-element="amp-social-share" src="https://cdn.ampproject.org/v0/amp-social-share-0.1.js"></script>
  • 設定
<!-- 一番シンプルな形 -->
<amp-social-share type="twitter"></amp-social-share>
<!-- ツイートフォームに「@hogeさんから」をつける場合 -->
<amp-social-share type="twitter" data-param-via="hoge"></amp-social-share>
<!-- タイトルを指定する場合(デフォルトはページタイトル -->
<amp-social-share type="twitter" data-param-text="title sample"></amp-social-share>

<!-- facbeookシェアの場合はapp_idが必要 -->
<amp-social-share type="facebook" data-param-app_id="xxxxx">

<!-- LINEなどtypeに用意されていないもの -->
<amp-social-share type="line" data-share-endpoint="https://line.me/ti/p/xxxxx'>LINE</amp-social-share>

今のところ

  • twitter
  • facebook
  • pinterest
  • linkedin
  • gplus
  • tumblr
  • email

のみtype属性の指定で設置できます。

ドキュメント:AMP > Reference > Components/Tags > amp-social-share

埋め込みタグ

Twitter

Twitterの埋め込みツイートは<amp-twitter>に変換

  • <head>内で読み込むライブラリ
<script async custom-element="amp-twitter" src="https://cdn.ampproject.org/v0/amp-twitter-0.1.js"></script>
  • 変換
    埋め込みタグの中にあるツイート日に ツイート詳細のリンク があるので、そこからツイートIDを取得して amp-twitterタグ の data-tweetid属性 に設定する
    scriptタグは利用できないので、削除する
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">月日は百代の過客にして、行かふ年も又旅人也。</p>松尾芭蕉 (@matshuo_basho) <a href="https://twitter.com/matshuo_basho/status/TWEET_ID">2016年12月13日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><amp-twitter data-tweetid="TWEET_ID" width="100" height="100" layout="responsive"></amp-twitter>

ドキュメント:AMP > Referernce > Components/Tags > amp-twitter

Instagram

Instagramの埋め込みは<amp-instagram>に変換

  • <head>内で読み込むライブラリ
<script async custom-element="amp-instagram" src="https://cdn.ampproject.org/v0/amp-instagram-0.1.js"></script>
  • 変換
    埋め込みHTMLの中にある「hogeが投稿した写真」というテキストにポストURLのリンクがあるので、そこからポストIDを取得して amp-instagramタグ の data-shortcode属性 に設定
    scriptタグは利用できないので、削除する
<blockquote class="instagram-media" data-instgrm-version="7" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px;"><a href="https://www.instagram.com/p/POST_ID/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal;" target="_blank">@hogeが投稿した写真</a> - <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-09-20T01:40:12+00:00">2015 9月 19 6:40午後 PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script><amp-instagram data-shortcode='POST_ID' width='1' height='1' layout='responsive'></amp-instagram>

ドキュメント:AMP > Reference > Components/Tags > amp-instagram

Facebook

facebookの埋め込み投稿は<amp-facebook>に変換

  • <head>内で読み込むライブラリ
<script async custom-element="amp-facebook" src="https://cdn.ampproject.org/v0/amp-facebook-0.1.js"></script>
  • 変換
    埋め込みのiframeに 動画のリンク があるので、そこからURLを取得して amp-facebookタグ の data-href属性 に設定する
<iframe src="https://www.facebook.com/plugins/post.php?href=https%3A%2F%2Fwww.facebook.com%matsuo_basho%2Fposts%xxxxxxx&width=500&show_text=true&appId=xxxxxxxxxxx&height=553" width="500" height="553" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe><amp-facebook width=486 height=657 layout="responsive" data-href="https://www.facebook.com/matsuo_basho/posts/xxxxxxx"></amp-facebook>

ドキュメント:AMP > Reference > Components/Tags > amp-facebook

GA計測

GAの場合

GAタグを直接埋めて、トリガーを記述していきます。

  • <head>内で読み込むライブラリ
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>

ページの本文にGAのトラッキング設定を追加するので、<body>の下あたりに<amp-analytics>を追加します。
type属性はgoogleanalyticsで、

  • pageview: ページ トラッキング用
  • event: イベント トラッキング用
  • social: ソーシャル トラッキング用

ex. pageview+ソーシャルイベント+クリックイベントを計測する場合

<!-- pageviewを計測する場合 -->
<amp-analytics type="googleanalytics" id="analytics1">
  <script type="application/json">
    {
      // 計測するGAアカウントID
      "vars": {
        "account": "UA-XXXXX-X"
      },
      // 計測するもののトリガーの設定
      "triggers": {
        // pageviewの計測
        "trackPageview": {
          "on": "visible",
          "request": "pageview",
          "vars": {
            "title": "奥の細道"
          }
        },
        // ソーシャルイベントの計測
        "trackClickOnTwitterLink": {
          "on": "click",
          "selector": "#twitter",
          "request": "social",
          "vars": {
            "socialNetwork": "twitter",
            "socialAction": "ツイート",
            "socialTarget": "/hosomichi.html"
          }
        },
        // クリックイベントの計測
        "trackClickToSaruminoLink" : {
        "on": "click",
        "selector": "#to_sarumino",
        "request": "event",
        "vars": {
          "eventCategory": "序文",
          "eventAction": "リンククリック"
        }
      }
    }
  </script>
</amp-analytics>

参考:Googleアナリティクス > AMP ページにアナリティクスを追加する

GTMを利用する場合

おなじみGoogleタグマネージャ
GTMでコンテナを作成する際に、「コンテナの使用場所」でAMPを選択することで、AMPでもGTMを利用できるようになります。
スクリーンショット_2016-12-17_2_09_07.png

AMP用のコンテナを作成したら、「Googleタグマネージャのインストール」に記述されている指示に従ってamp-analyticsタグを設定します。

<head>
  ...省略...
  <!-- AMP Analytics -->
  <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
</head>
<body>
  <!-- Google Tag Manager -->
  <amp-analytics config="https://www.googletagmanager.com/amp.json?id=GTM-XXXXXXX&gtm.url=SOURCE_URL" data-credentials="include"></amp-analytics>
</body>

うっかりコンテナの種類がウェブのタグを使うとエラーでやられます。

以降は普通にGTMを使う感覚でページビューやイベント送信、ソーシャル等のトラッキング設定を行えます。
ex. ページビュートラッキング
スクリーンショット 2016-12-17 11.43.17.png

まとめ

AMPページでエラーが大量発生していたときは「これは…アカン…:scream:」となっていましたが、無事エラー解消ができて一安心しています。今年も年を越せそうです。
ただ、タグの変換が発生するので、上がってくる記事に予期せぬタグがあったとしてもうまくエラー回避&柔軟に対応できるようにしておきたいなぁと、こっそり思いました。

補足:
AMP BY EXAMPLEという、実装例が掲載されているところもあるので、困ったときにチラッと覗くと幸せになれました。