きっかけ
突然ですがVuepressっていいですよね。
マークダウンとVue.jsのいいとこどりで、
簡単に記事が書けますし、レイアウトの調整もVue.jsの知識でかなりカバーできます。
WordPressなどと違って、mdファイルを手元においておけるのもうれしいです。
これでブログやマニュアルサイトを書いているのですが……
SEOにあたって、JSON-LDをつけてみようと思ったのが始まりです。
簡単にやってしまうなら
早速ググってみたところ、こんな記事を一番上に見つけました。
なんと、Frontmatterの下にscriptタグ直打ちです。
確かに簡単ではありますが、記事内でも
NOTE: This is more of a hack than an official solutions, and does not guranteed to work in the future.
とあるように、少し裏技的な様子。
しかもこれではページごとに入力する必要があります。困った……
vue-metaを使う
というわけで、ここからが本題、
Vuepressでvue-metaを使ってJSON-LDを自動生成します
まずはvue-metaのインストールから
yarn add vue-meta
続いてvue.use()をするために公式ドキュメントをもとに.vuepressフォルダ内にenhanceApp.jsを作成します。
import VueMeta from '../../node_modules/vue-meta'
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData, // site metadata
isServer // is this enhancement applied in server-rendering or client
}) => {
Vue.use(VueMeta)
}
なんでも、node_modulesへの参照は相対パスでしておかないと、build時にコケるらしいので、そこだけ注意です。
これでvue-metaを使う準備はできました。
Postページにscriptを仕込む
最後に、ブログの投稿ページ用のレイアウトであるPost.vueにmetaInfo()を作り込んでいきます。
この書き方はvue-metaを用いたOGPやJSON-LD用のメタタグ生成を参考にしました。
<script>
import PostMeta from '@theme/components/PostMeta.vue'
import Toc from '@theme/components/Toc.vue'
function createShcemaOrg(path, fm) {
return {
script: [
{
type: 'application/ld+json',
innerHTML: JSON.stringify(
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://www.794562.xyz" + path
},
"headline": fm.title,
"description": fm.description,
"image": "",
"author": {
"@type": "Person",
"name": fm.author
},
"datePublished": fm.date,
"dateModified": fm.update,
},
null, 2,
),
},
],
}
}
export default {
components: {
PostMeta,
Toc,
},
metaInfo() {
return createShcemaOrg(this.$page.path, this.$frontmatter)
}
}
</script>
あとは
yarn dev
で開発サーバーを立ち上げると……
きちんとhead内にscriptタグが生成されていました!
リッチリザルトテストでも問題ないと表示されたので、これでいけそうですね!