mintsu's blog

nuxt.jsでtitle/meta/ogpのhead情報をmixinにまとめて共通化

2020-05-20 14:00:00
フロントエンド

nuxt.jsでtitle/meta/ogpのhead情報をmixinにまとめて共通化

Nuxt.jsでページごとにtitle,descriptionやogpの情報を変更したい場合があると思います。
その際header情報を共通化して、デフォルト値の設定と簡単に上書きできるようにする方法を記載します。

目次

head情報のmixinの作成

ページごとのheader情報の上書きについて

nuxt.jsではpageコンポーネントのheader情報はheadメソッドを使うことでページごとに書き換えが可能です。
参考: API: head メソッド - NuxtJS

例)

<template>
  <h1>{{ title }}</h1>
</template>

<script>
export default {
  data () {
    return {
      title: 'Hello World!'
    }
  },
  head () {
    return {
      title: this.title,
      meta: [
        // `hid` は一意の識別子として使用されます。 `vmid` は動作しないので使わないでください。
        { hid: 'description', name: 'description', content: 'My custom description' }
      ]
    }
  }
}
</script>

今回は複数ページを扱うときに毎回headメソッドを記載するのは漏れの原因となるため、mixinを使って共通化することを考えます。

mixinの作成

headerと最低限必要なOGPタグを記載したmixinを書きのように記載します。

mixins/header.js

export default {
  head() {
    return {
      htmlAttrs: {
        lang: 'ja'
      },
      title: (this.meta && this.meta.title) || 'デフォルトのタイトル',
      meta: [
        {
          hid: 'description',
          name: 'description',
          content:
            (this.meta && this.meta.description) || 'デフォルトのdescription'
        },
        {
          hid: 'og:description',
          property: 'og:description',
          content:
            (this.meta && this.meta.description) || 'デフォルトのog:description'
        },
        {
          hid: 'og:site_name',
          property: 'og:site_name',
          content: (this.meta && this.meta.title) || 'デフォルトのog:site_name'
        },
        {
          hid: 'og:type',
          propery: 'og:type',
          content: (this.meta && this.meta.type) || 'website'
        },
        {
          hid: 'og:image',
          property: 'og:image',
          content: (this.meta && this.meta.image) || 'https//example.com/ogImagePath.png'
        }
      ]
    }
  }
}

ここで書いた this.meta以下のそれぞれの変数が設定されていればそれが使われ、設定されていない場合は直接文字列で指定している部分がデフォルト値として使われます。

this.megaの値はどこで設定すればいいのかというと、各ページのdataまたはasyncDataで設定すれば良いです。
例を後述します。

ページコンポーネント側の設定

mixinを読み込む

ページコンポーネント側でmixinを読み込む設定を書きます。

pages/page1.vue

<template>
  <p>page1</p>
</template>

<script>
import Header from '~/mixins/header'

export default {
  mixins: [Header]
}
</script>

単純にimport文でmixinを読んで、mixinsに入れるだけです。

これでこのページを開くと、mixinに設定した内容でtitle/description/ogpの情報が設定されます。

ページコンポーネント側で情報を上書きする

mixinsに追加するだけでは、各ページで同じ情報になってしまうので、ページコンポーネント側で値を設定してページごとに値を書き換えてみます。

pages/page2.vue

<template>
  <p>page2</p>
</template>

<script>
import Header from '~/mixins/header'

export default {
  mixins: [Header],
  asyncData() {
    const title = 'page2'
    const description = 'page2 description'
    const ogDescription = 'page2 ogDescription'
    const image = 'htts://example.com/images/page2.png'
    return {
      meta: {
        title,
        description,
        ogDescription,
        image
      }
    }
  }
}
</script>

asyndDataで返す値にmetaオブジェクトを追加しています。
ここの値がmixinであるheader.js内のthisの値と対応しており、この値でheader情報が上書きされます。

各ページコンポーネントで必要な情報のみ上書きができます。

まとめ

  • mixinを使ってheader情報を共通化できる
  • ページごとに値を設定してページごとの設定が可能

さいごにこちらにサンプルのリポジトリをおいておきます
mintsu/header-mixin-sample: header-mixin-sample