Nuxtでメタデータをいい感じに一元管理する方法forAMP

エンジニア向けの記事です。Nuxt.jsでメタデータを一元管理して保守性を上げるための内容です。

結論

mixin使って呼び出すコードをまとめます。
基本参考サイトまんまの処理で、AMP用に必要なものをちょっと書き加えています。

注意

・AMP HTMLを作るためのコードです。AMPいらないぞって人は素直に参考ページの方を見ておきましょう。
・単一ファイルコンポーネントを使ってます。「よく見る記事と記述方法違くね?」と思っても諦めましょう。

コード

nuxt.config.js
indexページ用の設定とサイト全般に必要な設定を記述

export default {
 mode: 'universal',
 router: {
   base: hoge
 },
 head: {
   base: {
     href: 'router.base'
   },
   htmlAttrs: {
     lang: 'ja'
   },
   titleTemplate: '%s サイト名',
   meta: [
     { charset: 'utf-8' },
     { name: 'viewport', content: 'width=device-width, initial-scale=1.0, minimum-scale=1.0' },
     { hid: 'description', name: 'description', content: site.description }
   ],
   link: [
     { hid: 'canonical', rel: 'canonical', href: '/' },
     { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
   ],
   script: []
 },
 ...
}

/assets/mixins/meta.js
ぶっちゃけパスはなんでもいい。今回は簡略化のためパス周りは直接記述だが、実際は環境変数で出し分けるのがオススメ

export default {
 head() {
   // 画像は必須
   const src = this.meta.image
   
   // 他に欲しいメタデータがあるなら要素を追加する
   const meta = [
     {
       hid: 'description',
       name: 'description',
       content: this.meta.description
     }
   ]
   // 特定ページでだけ使うメタ情報を引き取れるようにしとく
   if (this.meta.args) {
     for (let i = 0; i < this.meta.args.length; i++) {
       if (this.meta.args[i].name) {
         meta.push({
           name: this.meta.args[i].name,
           content: this.meta.args[i].content
         })
       }
     }
   }
   
   // AMPで必要なcanonicalを生成(今回は通常htmlは生成しない想定なので自身の絶対パスを指定)
   const link = [
     {
       hid: 'canonical',
       rel: 'canonical',
       href: `https://hoge.com${this.$router.history.base}${this.$route.path}`
     }
   ]
   // linkも独自設定を受け入れるようにいておく
   if (this.link) {
     for (let i = 1; i <= this.link.length; i++) {
       link.push({})
       for (const j of Object.keys(this.link[i])) {
         link[i].j = this.link[i][j]
       }
     }
   }
   
   // メタデータをページに返却
   if (this.meta.titleTemplate) {
     return {
       title: this.meta.title,
       titleTemplate: this.meta.titleTemplate || false,
       meta: meta,
       link: link
     }
   } else {
     return {
       title: this.meta.title,
       meta: meta,
       link: link
     }
   }
 }
}

/pages/index.vue
indexページは「サイト名」だけタイトルにしたいので、mixinsは読み込まず直接頑張る

<template>
  hoge
</template>

<script>
export default {
  ...
  head() {
    return {
     titleTemplate: null,
     title: 'サイト名'
    }
  }
}
</script>

/pages/*.vue
メタ情報として引き渡したいデータをthisで使えるように定義します。APIから取得する場合はdataじゃなくてasyncDataがオススメです。

<template>
  hoge
</template>

<script>
import Meta from '~/assets/mixins/meta'

export default {
  mixins: [Meta],
  ...
  data () {
    return {
      meta: {
       title: 'ページタイトル',
       description: 'ページ説明',
       args: [{ name: 'robots', content: 'noindex,nofollow' }]// 必要に応じて
      },
      // 以下必要に応じて
      link: [
       {
         hid: 'hoge',
         rel: 'huga',
         href: 'https://hogehuga.com'
       }
      ],
      script: [
        {
          hid: 'amp-carousel',
          src: 'https://cdn.ampproject.org/v0/amp-carousel-0.2.js',
          'custom-element': 'amp-carousel',
          async: true
        }
      ]
    }
  }
}
</script>

解説

基本は↓の参考をご参照。
AMPに必須なのはbaseタグとcanonicalです。
baseタグは位置調整しないとgoogle先生に怒られるので、この記事を参考にしてください。

参考


この記事が気に入ったらサポートをしてみませんか?