Nuxt.js初心者がhead内にOGPの設定を追加してみる

シェアする:

この記事をおすすめしたい人

  • WordPressしか知らないのにNuxt.jsを始めようとしてる人
  • Nuxt.jsでOGPを追加したいのにやり方が分からない人
  • つまりオレ

何も知らない超初心者が脱WordPressしたくてNuxt.jsでサイト構築していくシリーズです。

今回はhead内にOGPを追加していくお話をしようと思います。

WordPressの上でな!

※ このブログはWordPress製です

OGPって?

僕もよく分かってないんですが、SNS上でこういう表示↓をする機能のことみたいです。 詳しくは公式サイト(英語)を見てください。

LINEの場合だと、URLを貼った時に次の4点が表示されます。

  • URL
  • タイトル
  • description
  • サムネイル画像

Twitterの場合↓はdescriptionなしの3点。

ページを作れば勝手にこんな表示にしてくれるわけではなく、head内にOGP専用の記述を追加しなければなりません。

今回はこの設定の仕方のお話です。

OGPって必要なの?

ちょっ、おまっ、何言ってんの!

SNSにURL貼ってもらった時にこう↓なんのよ!?

かっこいいでしょ!?

必須です。

必須です。
(大事なことなので2回言いました)

OGPの種類

OGPとして規格化されたものと、各SNSの拡張機能があるみたいです。

まずは基本のOGPから。

基本的なページ情報

OGP公式サイトによると次の4点が紹介されていました。

  • og:title
    ページのタイトル
  • og:type
    ページの種類(ウェブサイト、記事とか)
  • og:image
    ページのメイン画像
  • og:url
    ページのURL

「og:type」の種類

英語苦手なので紹介されていたものを機械的に列挙します。

  • music
  • video
  • article
  • book
  • profile
  • website

WordPressのようなコンテンツ形式の場合、使うのは次の3つくらいでしょうか。

  • トップページ
    →website
  • 著者ページ
    →profile
  • 記事ページ
    →article

追加のページ情報

同じく公式サイトでは6種類。

  • og:audio
    ページに関連する音楽ファイルのURL
  • og:description
    ページ内容の簡単な説明文
  • og:determiner
    よく分からない…「a」「an」「the」とか…日本語圏では使わなさそう…
  • og:locale
    ページの言語設定
  • og:site_name
    サイト名
  • og:video
    ページに関連する動画ファイルのURL

その他、構造化できたり配列にできたりとかなり多機能みたいなので、詳しく知りたい人はOGP公式サイトを見て勉強してください。

実際にSNSに貼った画像を見る限り、僕はそこまで詳細な設定は必要ないと考えている(今のところ)ので、この中から必要なのだけ選びます。

TwitterのOGP

Twitterの開発者向けサイトに記載があります。

  • twitter:card
    Twitter上でOGPを表示する際の表示形式
  • twitter:site
    サイトのTwitterアカウント名(@XXXXXXXXXのやつ)
  • twitter:creator
    著者のTwitterアカウント名(@XXXXXXXXXのやつ)

意外だったんですが、たった3つです。

というのも当サイトでは「All In One SEO Pack」というWordPressのプラグインを使ってOGPを出力しているんですが、ここに含まれる「twitter:title」「twitter:description」「twitter:image」が入ってないんですね。

どうやら不要みたいです。 OGPの方で設定してあればそっちから読み込んでくれるそうな。

「twitter:card」の種類

次の4種類。

  • summary
  • summary_large_image
  • app
  • player

Twitter公式サイトに詳細説明はなさそう…?

これまで使った感じだと、

  • summary
    →サムネイル画像を小さく表示
  • summary_large_image
    →サムネイル画像を大きく表示

大きい方が見栄えがいいのでいつも「summary_large_image」を使ってます。

残りの2つは分かりません。

名前的にも僕が使うことはなさそう。

FacebookのOGP

こちらも開発者向けサイトに記載があります。

Twitter同様に基本はOGPを参照してくれるようで、追加はひとつだけ「fb:app_id」。

Facebook側でアクセス解析する際に使うらしく、その場合はFacebookのアプリIDを取得して設定するようです。

今回追加する項目を選別

基本的なページ情報4つ全てに、追加のページ情報から「og:description」「og:locale」「og:site_name」の3つ。

Twitterはこのサイト用のアカウント持っていないので「twitter:card」のみ。

Facebookはアクセス解析不要なので追加なし。

というわけで次の8種類を追加していきたいと思います。

  • og:title
  • og:type
  • og:image
  • og:url
  • og:description
  • og:locale
  • og:site_name
  • twitter:card

設定するOGPを用途で分類

設定する8つのOGPを用途…というかですね、「全ページで共通の内容なのか」「ページ毎に個別に設定するのか」で分けます。

全ページで共通の場合、「nuxt.config.js」で設定すれば1回の設定で全ページに反映されます。

ページ毎に設定する場合は、各ページのvueファイル(index.vueとか)で個別に設定します。

全ページで共通のOGP

次の4つを全ページで使い回すものとして、「nuxt.config.js」で設定することにしました。

  • og:type
  • og:locale
  • og:site_name
  • twitter:card

「og:type」は「article」とします。 トップページは「website」にするつもりなのですが、全ページをとりあえず「article」に設定しておいて、トップページでのみ「website」に上書きします。 逆だと各ページで「article」に設定し直さなくちゃいけなくなりますからね。

「og:locale」は「ja_JP」とします。 なくてもいいかなと思ったんですが、「lang="ja"」は設定しておいた方がいいような感じだったので、それに習って設定しておくことにします。

「og:site_name」はサイト名、このブログなら「オレDEV.com」です。

「twitter:card」は「summary_large_image」です。

なぜならば!

大きい方が目立ってかっこいいからです。

ページ毎に設定するOGP

次の3つはページ毎に設定します。

  • og:title
  • og:image
  • og:description

ただし、設定漏れがあっても大丈夫なよう、念のためnuxt.config.jsの方にもデフォルト値を設定しておこうと思います。

「og:title」はtitleタグと、「og:description」はメタdescriptionと共通の値を放り込みます。

この都合、忘れやすいのは「og:image」の設定ですが、nuxt.config.jsで設定してあれば最悪忘れてもそんなに被害は大きくなりません。

「og:url」は特殊な位置づけ

「og:url」もページ毎に変わる内容なのでページ毎に設定してもいいのですが、「nuxt.config.js」で現在のページのURLに自動設定するようにしていれば最高です。

各ページでいちいちURL設定しなくていいですし、URL変更した場合にも再設定し忘れることがありません。

というわけで位置づけ的には「全ページ共通」の方で処理します。

以下、この3つに分類して設定方法を考えていきます。

全ページ共通OGPの設定

全ページ共通の内容のOGPは次の4つに決めました。

  • og:type
  • og:locale
  • og:site_name
  • twitter:card

これらをHTMLコードにするとこう↓。


<meta property="og:type" content="article">
<meta property="og:locale" content="ja_JP">
<meta property="og:site_name" content="(サイト名)">
<meta name="twitter:card" content="summary_large_image">

全部metaタグなのでメタdescriptionを設定した時と同じやり方で追加できます。

上でも書きましたが、「og:type」は上書きする回数が少なくて済むよう、デフォルト値を「article」とします。
(トップページのみwebsiteに上書き)

これをnuxt.config.jsに追加します。


export default {
  head: {
    meta: [
      { hid: 'og:type', property: 'og:type', content: 'article' },
      { hid: 'og:locale', property: 'og:locale', content: 'ja_JP' },
      { hid: 'og:site_name', property: 'og:site_name', content: '(サイト名)' },
      { hid: 'twitter:card', name: 'twitter:card', content: 'summary_large_image' },
    ],
  },
}

既に「head」や「meta」プロパティがあると思うので、そこに追記する形です。

このままコピペして「export default」を2回書くとエラーになりました。 ちゃんと既存の「export default」に追記する形にしてください。 デフォルトが複数回あるのもおかしな話ですからね…。

「head」「meta」を複数回書く↓のはOKみたいです。
文法的にはエラーは出ませんが、思った挙動になっていませんでした。

headプロパティ再定義の細かい挙動

まずはheadプロパティを二重に設定。


export default {
  head: {
    htmlAttrs: {
      lang: 'ja',
    },
    title: (タイトル名),
    meta: [
      { name: 'description', (略) },
    ],
    link: [
      { rel: 'icon', (略) },
    ],
  },
  head: {
    meta: [
      { property: 'og:type', (略) },
    ],
  },
}

赤字の部分でheadプロパティを再定義しています。

この場合、1回目+2回目の内容となると良かったんですが、残念ながら「1回目の内容を全て破棄して、2回目の内容のみになる」です。

具体的には次のような出力になります。

  • htmlAttrsは出力されない
  • titleは出力されない
  • metaプロパティ内は2回目に含まれているものだけ出力される(descriptionは出力されない)
  • linkプロパティ内は全て出力されない

1回目の内容は完全になかったことになっています。

次に同じheadプロパティ内で、metaプロパティを二重に設定。


export default {
  head: {
    htmlAttrs: {
      lang: 'ja',
    },
    title: (タイトル名),
    meta: [
      { name: 'description', (略) },
    ],
    link: [
      { rel: 'icon', (略) },
    ],
    meta: [
      { property: 'og:type', (略) },
    ],
  },
}

出力結果はこんな↓感じ。

  • htmlAttrsは出力される
  • titleは出力される
  • metaプロパティ内は2回目に含まれているものだけ出力される(descriptionは出力されない)
  • linkプロパティ内は全て出力される

今度はmetaプロパティだけをリセットして、新しい内容のものに変更されています。

つまり…。

エラーは出ないけど、head/metaプロパティの二重定義もダメ!

各ページで設定するものも念のため設定しておく

個別ページでの設定漏れがあっても大丈夫なように、nuxt.config.jsでもデフォルト値として設定しておきます。

  • og:title
  • og:image
  • og:description

HTMLコードはこう↓。


<meta property="og:title" content="(サイト名)">
<meta property="og:image" content="(サイトのメイン画像のURL)">
<meta property="og:description" content="(サイトの説明)">

これまた全部metaタグなので、同じ書き方でいけます。


export default {
  head: {
    meta: [
      { hid: 'og:title', property: 'og:title', content: (サイト名) },
      { hid: 'og:image', property: 'og:image', content: (サイトのメイン画像のURL) },
      { hid: 'og:description', property: 'og:description', content: (サイトの説明) },
    ],
  },
}

ここでこの3つの値をトップページのものにしておくと、トップページで再設定する手間を省けるので効率がいいです。

さらに、各ページで設定し忘れた場合にも、トップページの内容が表示されるならそこまで意図とずれることはありません。

hidは必ず設定しよう!

各ページで上書きする3要素があるので、hidは必ず設定しておきましょう。

hidを設定しておかないと同じコードが二重に出力されてしまいます。


<meta property="og:title" content="(サイト名)">
<meta property="og:title" content="(ページ名)">

hidは他と被ってなければ何でもいいみたいなので僕は「property」と同じ値にしました。

全ページ共通のものも、個別に設定するケースが出てくる場合があるので、念のためhidを設定しておきます。

TwitterのOGPはちょっと注意が必要

OGPは「property」(項目名)と「content」(値)のペアですが、Twitterだけは「name」と「content」のペアです。

つられて「property」としてしまわないよう注意しましょう。

Facebookの方は「property」なので特に注意はいりません。

各ページ毎のOGPの設定

設定するのは次の3つです。

  • og:title
  • og:image
  • og:description

HTMLコードはこう↓。


<meta property="og:title" content="(サイト名)">
<meta property="og:image" content="(サイトのメイン画像のURL)">
<meta property="og:description" content="(サイトの説明)">

設定を追加するのは各ページのvueファイル(index.vueとか)になります。

このまま先ほどと同様に追記してもいいんですが、各ページのファイルではtitleタグ、メタdescriptionなど、同じ値を設定することが多いと思います。

なのでメンテナンス性の点からひと手間加えて、このような↓形にしました。


const title_name = (サイト名)
const desc_name = (サイトの説明)
const img_url = (サイトのメイン画像のURL)

export default {
  head: {
    title: title_name,
    meta: [
      { hid: 'description', name: 'description', content: desc_name },
      { hid: 'og:title', property: 'og:title', content: title_name },
      { hid: 'og:image', property: 'og:image', content: img_url },
      { hid: 'og:description', property: 'og:description', content: desc_name },
    ],
  },
}

title、description共に2回使われていますが、このような形にすると変更があった際にも1箇所の修正で2箇所ともに反映されます。

「og:url」の自動設定…

大苦戦しました。

「og:url」のHTMLコードはこう↓です。


<meta property="og:url" content="(ページのURL)">

ここまでと同じく「property」と「content」のペアのmetaタグです。

あとは動的に現在のページのURLを動的に取得すれば簡単にできそうなもんです。

動的に相対パスを取得するのは「this.$route.path」だそうなので、


export default {
  head: {
    meta: [
      { hid: 'og:url', property: 'og:url', content: (トップページのURL) + this.$route.path },
    ],
  },
}

こんな感じでいけると思うじゃないですか!?

結果はこう↓。


Cannot read property '$route' of undefined

現在のページのURLを生成するだけのこの作業に気が狂うほど時間を費やしたので、その四苦八苦っぷりはcanonicalの記事を見てください。

このページでは結論だけ。

ページのURLを取得するにはheadメソッドを使う

Nuxt.jsの公式マニュアルを見ていると、「vue-meta」モジュールでheadを操作する方法として、「headプロパティ」という方法と「headメソッド」という方法があるようなんです。

これまで使ってきたのは全部headプロパティの方の書き方で、プロパティの方の説明にはこんな↓但し書きが…

コンポーネントの関数として head を使うこともでき、this を経由してコンポーネントのデータにアクセスできます。

つまりこれはどういうことかというと、

「this」からデータにアクセスしたいならheadメソッドの方を使いなさいよ

ってことでした。

headメソッドの書き方をするとこんな↓感じになります。


export default {
  head () {
    return {
      meta: [
        { hid: 'og:url', property: 'og:url', content: (トップページのURL) + `${this.$route.path}` },
      ],
    }
  },
}

こっちならエラーは出ませんでした。

メソッドというだけあって関数っぽい書き方になってますね。

nuxt.config.jsに追記する場合はこういう↓形に。


export default {
  head: {
    (略)
  },
  head () {
    return {
      meta: [
        { hid: 'og:url', property: 'og:url', content: (トップページのURL) + `${this.$route.path}` },
      ],
    }
  },
}

headプロパティとheadメソッドは書き方が違うので別枠で追加する必要があります。
この書き方ではheadプロパティでの設定(最初の方)の中身が全部リセットされて、2回目のメソッドで定義した内容だけが反映されてしまっていました。

なので、この↓ように、headプロパティの内容を全てメソッドの方に移してやる必要があります。


export default {
  head () {
    return {
      title: (タイトル名),
      meta: [
        { hid: 'description', name: 'description', content: (ページの説明) },
        { hid: 'og:url', property: 'og:url', content: (トップページのURL) + `${this.$route.path}` },
      ]
    }
  }
}

headメソッドはnuxt.config.jsでもindex.vueでもLayoutの中にも記述できますが、今回は全ページ自動取得を目指していたのでnuxt.config.jsにこれを追加しました。

OGPの設定する人はcanonicalも設定するんじゃないかと思うので、その場合はこう↓。


export default {
  head () {
    return {
      meta: [
        { hid: 'og:url', property: 'og:url', content: (トップページのURL) + `${this.$route.path}` },
      ],
      link: [
        { rel: 'canonical', href: (トップページのURL) + `${this.$route.path}` },
      ],
    }
  },
}

URL部分を2箇所で計算するのがイヤな場合は、先に定数として宣言しておくこともできるみたいです。


export default {
  head () {
    const url = (トップページのURL) + `${this.$route.path}`
    return {
      meta: [
        { hid: 'og:url', property: 'og:url', content: url },
      ],
      link: [
        { rel: 'canonical', href: url },
      ],
    }
  },
}

ほんとに関数っぽいですね。

ふぅ……。

まとめ

OGPを設定する場合は、

全ページで共通するもの

ページ毎に個別設定するもの

に分けて、共通のものはnuxt.config.jsに、個別設定するものはそのページのvueファイル(index.vueとか)に追加しましょう。

「og:url」だけはちょっとひと手間必要ですが、headメソッドの方を使えばnuxt.config.jsに追記することで自動で全ページのURLを取得してくれます。

以上、WordPressからお届けしました!

Nuxt.js HEADタグ操作編の目次

シェアする: