初のアドベントカレンダー参加。こんな内容でいいのかなと思いつつ…nuxt.jsにSEOに必要なmeta(OGP)タグを入れていきます。
SEOに必要なmeta(OGP)タグを入れたい
nuxt.jsでは、metaタグのコントロールにvue-metaが使われている。これ、ページ数が増えるとめんどくさい記入漏れなどのミスが起こる。なので、最低限必要なmeta(OGP)をフォーマット化しておく。あとから仕様を変更できればなおよし。
今回の目標
The Open Graph protocolを参考にしつつ、meta(OGP)を以下のようにしたい。(icon関連はPWAの設定と一緒にやるので今回は保留。)
<html prefix="og: http://ogp.me/ns#">
<head>
<!-- title/description -->
<title>タイトル</title>
<meta name="description" content="ディスクリプション">
<!-- OGP -->
<meta property="og:site_name" content="サイト名" >
<meta property="og:type" content="タイプ" >
<meta property="og:url" content="ページURL" >
<meta property="og:title" content="ページタイトル" >
<meta property="og:description" content="ディスクリプション" >
<meta property="og:image" content="OGP画像URL" />
<!-- FB/twitter ※必要ならば以下追加-->
<!-- meta property="article:publisher" content="FacebookURL" -->
<!-- meta property="fb:app_id" content="FacebookAppID" -->
<!-- meta name="twitter:card" content="summary_large_image" -->
<!-- meta name="twitter:site" content="@Twitter" -->
...
</head>
meta(OGP)の仕様
当たり前のことを、一度書き出す。
タイトル
- トップページ -> サイト名
- 下層ページ -> ページタイトル - サイト名
ディスクリプション
- トップページ -> 共通ディスクリプション
- 下層ページ -> ページ個別のディスクリプション
ページタイプ
- トップページ -> website
- 下層ページ -> artice
サイトのURLとページURL
- 絶対パスで入力
OGP画像URL
- トップページ -> 共通画像への絶対パス
- 下層ページ -> ページ個別画像への絶対パス
ということで、試していく。
universal(SSR)モードにする!
まずは、universal(SSR)モードにする。generate
する場合でもuniversal(SSR)モードにする。(大事なことなので2回言う。)
SPAモードは(たとえgenerate
したとしても)ページ毎のmeta(OGP)が反映されない。
module.exports = {
mode: 'universal',
...
}
公式ドキュメントを参考にベースを作成
nuxt.jsの公式ドキュメントと、vue-metaの公式ドキュメントを参考にベース部分を作成。小規模のサイトならこれだけでもOK。
nuxt.config.js
nuxt.config.jsにheadを追加。本来は、CDNの読み込みやicon関連なども入ってくるが、今回はSEOに関連するmeta(OGP)のみ記載。
module.exports = {
head: {
htmlAttrs: {
prefix: 'og: http://ogp.me/ns#'
},
titleTemplate: '%s - サイト名',
meta: [
{ hid: 'description', name: 'description', content: '共通ディスクリプション' },
{ hid: 'og:site_name', property: 'og:site_name', content: 'サイト名' },
{ hid: 'og:type', property: 'og:type', content: 'website' },
{ hid: 'og:url', property: 'og:url', content: 'https://example.com' },
{ hid: 'og:title', property: 'og:title', content: 'サイト名' },
{ hid: 'og:description', property: 'og:description', content: '共通ディスクリプション' },
{ hid: 'og:image', property: 'og:image', content: 'https://example.com/img/ogp/common.jpg' },
// { property: 'article:publisher', content: 'FacebookURL' },
// { property: 'fb:app_id', content: 'FacebookAppID' },
// { name: 'twitter:card', content: 'summary' },
// { name: 'twitter:site', content: '@Twitter' },
...
],
},
}
pagesファイル(トップページ)
トップページでは、titleTemplate
の機能をnull
にしつつ、サイト名のみ表示されるようにする。
<template lang="pug">
.main
h1 サイト名
nuxt-link(to="/test") go to Test-Page
</template>
<script>
export default {
head () {
return {
titleTemplate: null,
title: 'サイト名',
}
},
}
</script>
pagesファイル(トップページ以外)
下層ページでは、titleTemplate
の機能を使いタイトルを表示。また、各種metaタグの内容を変える。
<template lang="pug">
.main
h1 {{ meta.title }}
nuxt-link(to="/") go to HOME
</template>
<script>
export default {
data () {
return {
meta: {
title: 'Test-Page!',
description: 'ページ個別のディスクリプション',
type: 'article',
url: 'https://example.com/test',
image: 'https://example.com/img/ogp/test.jpg',
},
}
},
head () {
return {
title: this.meta.title,
meta: [
{ hid: 'description', name: 'description', content: this.meta.description },
{ hid: 'og:type', property: 'og:type', content: this.meta.type },
{ hid: 'og:title', property: 'og:title', content: this.meta.title },
{ hid: 'og:description', property: 'og:description', content: this.meta.description },
{ hid: 'og:url', property: 'og:url', content: this.meta.url },
{ hid: 'og:image', property: 'og:image', content: this.meta.image },
],
}
}
}
</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-hid="description" name="description" content="共通ディスクリプション" data-n-head="true">
<meta data-hid="og:type" property="og:type" content="website" data-n-head="true">
<meta data-hid="og:url" property="og:url" content="https://example.com" data-n-head="true">
<meta data-hid="og:title" property="og:title" content="サイト名" data-n-head="true">
<meta data-hid="og:description" property="og:description" content="共通ディスクリプション" data-n-head="true">
<meta data-hid="og:image" property="og:image" content="https://example.com/img/ogp/common.jpg" data-n-head="true">
</head>
<html prefix="og: http://ogp.me/ns#" data-n-head="prefix">
<head>
<title data-n-head="true">Test-Page! - サイト名</title>
<meta data-n-head="true" data-hid="og:site_name" property="og:site_name" content="サイト名">
...
<meta data-hid="description" name="description" content="ページ個別のディスクリプション" data-n-head="true">
<meta data-hid="og:type" property="og:type" content="article" data-n-head="true">
<meta data-hid="og:title" property="og:title" content="Test-Page!" 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="https://example.com/test" data-n-head="true">
<meta data-hid="og:image" property="og:image" content="https://example.com/img/ogp/test.jpg" data-n-head="true">
</head>
いい感じ。generate
で生成されたhtmlファイルにも反映されている。
何度も書く場所をmixin化
test.vueへ書いたhead () {...}
の部分。めんどくさいのでミス軽減のためmixinで共通化する。
mixinファイル作成
mixinファイルを作成して、head () {...}
をごそっと移植。
export default {
head () {
return {
title: this.meta.title,
meta: [
{ hid: 'description', name: 'description', content: this.meta.description },
{ hid: 'og:type', property: 'og:type', content: this.meta.type },
{ hid: 'og:title', property: 'og:title', content: this.meta.title },
{ hid: 'og:description', property: 'og:description', content: this.meta.description },
{ hid: 'og:url', property: 'og:url', content: this.meta.url },
{ hid: 'og:image', property: 'og:image', content: this.meta.image },
],
}
}
}
pagesファイル(トップページ)
トップページとなるindex.vueはそのままで問題ない。
pagesファイル(トップページ以外)
下層ページに、mixins: [Head]
を追加していく。mixinファイルをimport
するのを忘れずに。
<template lang="pug">
...
</template>
<script>
import Meta from '~/assets/mixins/meta' // ←追加
export default {
mixins: [Meta], // ←追加
data () {
return {
meta: {
title: 'Test-Page!',
description: 'ページ個別のディスクリプション',
type: 'article',
url: 'https://example.com/test',
image: 'https://example.com/img/ogp/test.jpg',
},
}
},
// ←`head ()`は削除。
}
</script>
GOOD!generate
で生成されたhtmlも大丈夫。
mixin化が出来たので、あとは好みで使いやすいようにカスタマイズすればいい。
第2段、nuxt.js(v2)でSEOに必要なmeta(OGP)で入力漏れの事故をなくす。書きました。
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!