Vue.jsでSPAサイトを作成するチュートリアル【7. メタ編】 

Vue.jsを使い始めていろいろできることが多くなってきたので、整理する意味も兼ねてチュートリアルにまとめます。
今回はコーポレートサイトを想定して作成していきます。
※記事が長くなったのでチュートリアルを分割しました。


## 目次

* [表示編](https://qiita.com/buchiya4th/items/cff0b2ab9ebd550c4e0f)
* [ルーター編](https://qiita.com/buchiya4th/items/f154191c8157bbd2239a)
* [コンポーネント編](https://qiita.com/buchiya4th/items/d5a62722f1fc26230df0)
* [CSS編](https://qiita.com/buchiya4th/items/6f5db9f58ee66982438e)
* [JS編](https://qiita.com/buchiya4th/items/3f3b9c6e48866e6d9d27)
* [ライブラリ編](https://qiita.com/buchiya4th/items/b4814c0018f9311af461)
* メタ編 ←イマココ
* [ビルド編](https://qiita.com/buchiya4th/items/71649f8fbd2f72b9e6e7)


## 前提

* タスクは`npm scripts`で一限管理
* コマンドは`yarn`を使用
* `vue-cli`の`webpack-simple`を使用


## バージョン

* "vue": "^2.5.11"
* "webpack": "^3.6.0"

## はじめに

メタは画面には表示されないので、うっかり忘れがちです。
SEO対策をしたいのであれば、しっかりと記述しましょう。

head内に記述するメタはいろいろありますが、全ページ共通と個別で扱うものに分かれます。
以下にまとめられているので参考にしながら、全ページ共通はindex.htmlへ、個別で扱うものはVue.js側に記述していきましょう。

参考：[サイトに埋め込まれたHTMLのmetaタグ(メタタグ)のまとめ](https://qiita.com/imotoy/items/c805f3cbc2d09f396cb4)
参考：[もうmeta要素を迷わない！最低限入れるべきmeta要素のまとめ](https://qiita.com/pompom0c0/items/5c00a188aab744cfc918)

## 全ページ共通

* charset
* viewport
* format-detection
* robots

全ページ共通は上記を設定しておくと良いと思います。
index.htmlに記述しましょう。

```html:/src/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="format-detection" content="telephone=no">
    <title>vue-skeleton</title>
    <meta name="robots" content="noindex,nofollow">
    <link rel="stylesheet" href="/css/style.css">
  </head>
  <body>
    <div id="app"></div>
    <script src="/js/bundle.js"></script>
  </body>
</html>

```

## ページ固有

* title
* description
* og:title
* og:description
* og:type
* og:url
* og:image
* twitter:card

上記をページごとに設定するためにvue-headを使います。
vue-headを追加します。

```bash
$ yarn add vue-head
```

続いてmain.jsに追記します。

```js:/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './router.js'
import VueHead from 'vue-head' // ← 追記
import BodyClass from 'vue-body-class'
import VueMatchHeights from 'vue-match-heights'
import VueSmoothscroll from 'vue-smoothscroll'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: Routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { x: 0, y: 0 }
    }
  }
})

// ↓ 追記
Vue.use(VueHead, {
  separator: ' | '
})
// ↑ 追記
Vue.use(BodyClass, router)

Vue.use(VueMatchHeights)
Vue.use(VueSmoothscroll)

const app = new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
console.log(app)

```

separatorで区切り文字を設定できます。

indexに設定しましょう。

```js:/src/pages/Index/Index.js
import IndexSwiper from '../../components/IndexSwiper/IndexSwiper.vue'

export default {
  components: {
    IndexSwiper
  },
  data: function () {
    return {
      text: 'index'
    }
  },
  head: {
    meta: [
      { name: 'description', content: 'ここにトップページの説明文が入ります。' },
      { property: 'og:title', content: 'トップページ' },
      { property: 'og:description', content: 'ここにトップページの説明文が入ります。' },
      { property: 'og:type', content: 'website' },
      { property: 'og:url', content: 'https://example.com' },
      { property: 'og:image', content: 'https://example.com/img/og.png' },
      { name: 'twitter:card', content: 'summary' }
    ]
  }
}

```

indexはindex.htmlのtitleに記述しているものをそのまま出すようにしています。
その他のページは区切り文字を出したいので以下のように記述します。
２つの違いは、indexにはtitleの記述をせず、その他のページはtitleを記述してそのページタイトルを追加するようになっています。

```js:/src/pages/About/About.js
export default {
  data: function () {
    return {
      title: '会社概要',
      text: 'about'
    }
  },
  head: {
    title: function () {
      return {
        inner: this.title
      }
    },
    meta: [
      { name: 'description', content: 'ここに会社概要の説明文が入ります。' },
      { property: 'og:title', content: '会社概要' },
      { property: 'og:description', content: 'ここに会社概要の説明文が入ります。' },
      { property: 'og:type', content: 'website' },
      { property: 'og:url', content: 'https://example.com/about/' },
      { property: 'og:image', content: 'https://example.com/img/og.png' },
      { name: 'twitter:card', content: 'summary' }
    ]
  }
}

```

indexが「vue-skeleton」
aboutが「会社概要  |  vue-skeleton」
になっていれば成功です。
他のページもaboutと同じように記述しましょう。


## Google Analytics

Google Analyticsは以下で動作するようです。

**※最終確認していないので自己責任で導入してください。**

```bash
$ yarn add vue-analytics
```

```js:main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './router.js'
import VueHead from 'vue-head'
import VueAnalytics from 'vue-analytics' // ← 追加
import BodyClass from 'vue-body-class'
import VueMatchHeights from 'vue-match-heights'
import VueSmoothscroll from 'vue-smoothscroll'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: Routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { x: 0, y: 0 }
    }
  }
})

Vue.use(VueHead, {
  separator: ' | '
})
// ↓ 追加
Vue.use(VueAnalytics, {
  id: 'UA-70413829-1',
  router
})
// ↑ 追加
Vue.use(BodyClass, router)

// 省略
```

参考：[Vue-SPAでもGoogle Analyticsしたい！](https://qiita.com/hirohero/items/0f29a89cd08b421ccfe1)
参考：[vue-analytics](https://www.npmjs.com/package/vue-analytics)
参考：[Page tracking](https://github.com/MatteoGabriele/vue-analytics/blob/HEAD/docs/page-tracking.md)

## まとめ

以上で設定は終わりですが、忘れてはいけないのは今回はVue.js（JavaScript）で設定しています。
GoogleはJavaScriptの中も読んでいると宣言していますが、どこまで正確に読まれているかの判断は難しいところです。
きちんと読み込まれている事例もいくつか見かけましたが、不安な方はご自身でいろいろ調べてみると良いでしょう。