nuxt.js(v2)でSEOに必要なmeta(OGP)を入れたいで、最低限必要なmeta(OGP)をmixinにまとめた。このままでも使えるけど、共通化できるものを整理してつつ入力漏れの事故をなくしたい。
今回の目標
基本情報はnuxt.config.jsで管理する
以下をnuxt.config.jsで管理しつつ、環境変数でいつでも変更できるようにしておく。
- サイト名
- 共通のディスクリプション
- ドメイン
- ベースディレクトリ
- OGP画像置き場
下層ページのmeta(OGP)情報未入力時の対応をする
下層ページでmeta(OGP)情報の書き忘れが発生してもいいようにする。全ページ内容を変えるのはSEOにっとて大事。入力しなくても、全ページ違っていてほしい。そもそも、ページURLとか、毎回書かなくてよくない?
ということで、こんな感じを目標に…
タイトル
titleTemplate機能は使わない。
- トップページ&未入力 -> サイト名
- 下層ページ -> ページタイトル - サイト名
ディスクリプション
- トップページ&未入力 -> 共通ディスクリプション
- 下層ページ -> ページ個別のディスクリプション
- 未入力&ページタイトルあり -> {サイト名}サイトの{ページタイトル}ページです。{共通ディスクリプション}
ページタイプ
- トップページ -> website
- 下層ページ -> artice
- 未入力 -> artice
サイトのURLとページURL
- 絶対パスで入力(自動)
OGP画像URL
OGP置き場のURLは毎回書かなくていいようにしておいた上で、
- トップページ -> 共通画像への絶対パス
- 下層ページ -> ページ個別画像への絶対パス
- 未入力 -> 表示なし
やってきます。
universal(SSR)モードにする!
まずは、universal(SSR)モードにする。generate
する場合でもuniversal(SSR)モードにする。(大事なことなので2回言う。)
SPAモードは(たとえgenerate
したとしても)ページ毎のmeta(OGP)が反映されない。
module.exports = {
mode: 'universal',
...
}
環境変数を設定する
環境変数とディフォルト値を設定する。
const baseName = process.env.BASE_NAME || '株式会社アミテン'
const baseDesc = process.env.BASE_DISC || '共通のディスクリプション。得意分野で「ヒトの自立」「ヒトのつながり」を促進する。そんな会社にしたいです。'
const baseUrl = process.env.BASE_URL || 'http://localhost:3000'
const baseOgp = process.env.BASE_OGP || '/lib/img/ogp'
const baseDir = process.env.BASE_DIR || '/'
使い方
MAC
BASE_URL=https://example.com BASE_DIR=/yourDir/ npm run dev
WIN
※windowsは環境変数の扱い方が違うのでcross-env
経由で行う。nuxt.js(v2)系からは、cross-envがはじめから入っている。
npx cross-env BASE_URL=https://example.com BASE_DIR=/yourDir/ nuxt
よくつかう場合はpackage.jsonに書いておく。
{
"scripts": {
"generate": "nuxt generate",
"generate:production": "cross-env BASE_URL=https://example.com BASE_DIR=/yourDir/ nuxt generate",
...
},
}
npm run generate:production
OK。
どこでも使えるようにする
nuxt.config.jsのrouterプロパティのbaseにbaesDir
を登録する。あとの項目は、envプロパティに登録。これで、バックエンド・フロントエンドともにどこからでも使えるようになる。
const baseName = process.env.BASE_NAME || '株式会社アミテン'
const baseDesc = process.env.BASE_DISC || '共通のディスクリプション。共通のディスクリプション。得意分野で「ヒトの自立」「ヒトのつながり」を促進する。そんな会社にしたいです。'
const baseUrl = process.env.BASE_URL || 'http://localhost:3000'
const baseOgp = process.env.BASE_OGP || '/lib/img/ogp'
const baseDir = process.env.BASE_DIR || '/'
module.exports = {
mode: 'universal',
env: {
baseName: baseName,
baseDesc: baseDesc,
baseUrl: baseUrl,
baseOgp: baseOgp,
},
router: {
base: baseDir,
},
...
}
contextかprocessを経由してどこからでも使えるようになった。試しに使ってみる。
<template lang="pug">
.main
p context経由でアクセス:{{test1}}
p process経由でアクセス:{{test2}}
p おまけ(router.base取得):{{test3}}
</template>
<script>
export default {
asyncData (context) {
console.log(context)
return {
test1: context.env.baseName,
test2: process.env.baseDesc,
test3: context.base,
}
},
}
</script>
Good!基本情報をnuxt.config.jsで管理できるようになりました。
nuxt.config.jsにheadを追加
nuxt.config.jsにhead情報を追加していく。早速、さっき設定したbaseセットを利用する。
本来は、CDNの読み込みやicon関連なども入ってくるが、今回はSEOに関連するmeta(OGP)のみ記載。
const baseName = process.env.BASE_NAME || '株式会社アミテン'
const baseDesc = process.env.BASE_DISC || '共通のディスクリプション。共通のディスクリプション。得意分野で「ヒトの自立」「ヒトのつながり」を促進する。そんな会社にしたいです。'
const baseUrl = process.env.BASE_URL || 'http://localhost:3000'
const baseOgp = process.env.BASE_OGP || '/lib/img/ogp'
const baseDir = process.env.BASE_DIR || '/'
module.exports = {
mode: 'universal',
env: {
baseName: baseName,
baseDesc: baseDesc,
baseUrl: baseUrl,
baseOgp: baseOgp,
},
router: {
base: baseDir,
},
...
head: { // 以下を追加
htmlAttrs: {
prefix: 'og: http://ogp.me/ns#'
},
title: baseName,
meta: [
{ hid: 'description', name: 'description', content: baseDesc },
{ hid: 'og:site_name', property: 'og:site_name', content: baseName },
{ hid: 'og:type', property: 'og:type', content: 'article' },
{ hid: 'og:url', property: 'og:url', content: baseUrl },
{ hid: 'og:title', property: 'og:title', content: baseName },
{ hid: 'og:description', property: 'og:description', content: baseDesc },
{ hid: 'og:image', property: 'og:image', content: `${baseOgp}/common.jpg` },
// { property: 'article:publisher', content: 'FacebookURL' },
// { property: 'fb:app_id', content: 'FacebookAppID' },
// { name: 'twitter:card', content: 'summary' },
// { name: 'twitter:site', content: '@Twitter' },
],
...
},
}
OK。環境変数で指定した内容もバッチリ反映される。
本題
下層ページのmeta(OGP)情報未入力時の対応をしていく。
まずは、mixinファイルをカスタマイズ。
export default {
asyncData (context) {
return {
baseName: context.env.baseName,
baseDesc: context.env.baseDesc,
baseUrl: context.env.baseUrl,
baseOgp: context.env.baseOgp,
}
},
head () {
const head = { meta: [] }
// タイトル
if (this.meta.title) {
const title = `${this.meta.title} - ${this.baseName}`
head.title = title
head.meta.push({ hid: 'og:title', property: 'og:title', content: title })
}
// ディスクリプション
if (this.meta.description) {
head.meta.push({ hid: 'description', name: 'description', content: this.meta.description })
head.meta.push({ hid: 'og:description', property: 'og:description', content: this.meta.description })
} else if (!this.meta.description && this.meta.title) {
const disc = `${this.baseName}サイトの${this.meta.title}ページです。${this.baseDesc}`
head.meta.push({ hid: 'description', name: 'description', content: disc })
head.meta.push({ hid: 'og:description', property: 'og:description', content: disc })
}
// ページタイプ
if (this.meta.type) {
head.meta.push({ hid: 'og:type', property: 'og:type', content: this.meta.type })
} else if (this.$route.path === '/') {
head.meta.push({ hid: 'og:type', property: 'og:type', content: 'website' })
}
// ページURL
const url = `${this.baseUrl}${this.$router.history.base}${this.$route.path}`
head.meta.push({ hid: 'og:url', property: 'og:url', content: url })
// OGP画像URL
if (this.meta.image) {
const imageUrl = `${this.baseUrl}${this.$router.history.base}${this.baseOgp}${this.meta.image}`
head.meta.push({ hid: 'og:image', property: 'og:image', content: imageUrl })
}
return head
}
}
これで、index.vueでは何も設定しなくて良くなった。
変更したかったら、head()
を使って修正すればよい。
<template lang="pug">
.main
nuxt-link(to="/test") goto testPage
</template>
<script>
export default {
// head () {
// return {
// titleTemplate: null.
// title: 'すごくかっこいいサイト名をつかったタイトル'
// }
// }
}
</script>
からの、下層ページでは、mixinを利用する。
<template lang="pug">
.main
nuxt-link(to="/") goto top
</template>
<script>
import Meta from '~/assets/mixins/meta' // ←追加
export default {
mixins: [Meta], // ←追加
data () {
return {
meta: {
title: 'Test-Page!', // ←未入力も対応
description: 'ページ個別のディスクリプション', // ←未入力も対応
type: 'article', // ←未入力も対応
image: '/test.jpg', // ←OGP画像置き場からのURLだけでOK、未入力も対応
},
}
},
}
</script>
極端な話、titleだけでも大丈夫。
<template lang="pug">
.main
nuxt-link(to="/") goto top
</template>
<script>
import Meta from '~/assets/mixins/meta'
export default {
mixins: [Meta],
data () {
return {
meta: {
title: 'サンプルページ', // ←これだけでもなんとかなる。
},
}
},
}
</script>
出力結果
<html prefix="og: http://ogp.me/ns#" data-n-head="prefix">
<head>
<title data-n-head="true">サンプルページ - 株式会社アミテン</title>
<meta data-n-head="true" data-hid="og:site_name" property="og:site_name" content="株式会社アミテン">
<meta data-n-head="true" data-hid="og:type" property="og:type" content="artice">
<meta data-n-head="true" data-hid="og:image" property="og:image" content="/lib/img/ogp/common.jpg">
<meta data-hid="og:title" property="og:title" content="サンプルページ - 株式会社アミテン" data-n-head="true">
<meta data-hid="description" name="description" content="株式会社アミテンサイトのサンプルページページです。共通のディスクリプション。得意分野で「ヒトの自立」「ヒトのつながり」を促進する。そんな会社にしたいです。" data-n-head="true">
<meta data-hid="og:description" property="og:description" content="株式会社アミテンサイトのサンプルページページです。共通のディスクリプション。得意分野で「ヒトの自立」「ヒトのつながり」を促進する。そんな会社にしたいです。" data-n-head="true">
<meta data-hid="og:url" property="og:url" content="http://localhost:3000/ex" data-n-head="true">
</head>
入力漏れの事故がなくなりました。\(^o^)/
Link
以下、公開中のnuxt.js(v2)関連の記事一覧
技術よりの記事
- nuxt.js(v2)のインストール〜ESLint設定まで
- nuxt.js(v2)の作業ディレクトリを整理
- nuxt.js(v2)のベースURLをターミナルからコントロール
- nuxt.js(v2)でpug/stylusを利用する
- nuxt.js(v2)でIE11対応をする(CSS編)
- nuxt.js(v2)でIE11対応をする(JS編)
- nuxt.js(v2)で絶対パス(https~)を取得する方法
- nuxt.js(v2)でSEOに必要なmeta(OGP)を入れたい
- nuxt.js(v2)でSEOに必要なmeta(OGP)で入力漏れの事故をなくす
よく使うプラグインのお話
- nuxt.js(v2)で便利なvue-mqを使ってみるがSSRモードでコンソールエラーがでるので確認してみた。
- nuxt-linkでスムーズスクロールするならvue-scrolltoが便利で気が利いている…と思う。
- nuxt.jsでパララックスをするならvue-parallax-jsがお手軽。Cool!