Nuxt3でOGPを定義する
Nuxt3でOGPを設定する方法
以前自分のサイトをVuePressからNuxt3に変更しましたが、Vue3自体の理解の低さなどもあり
OGPの設定を行うのに非常に手間取ってしまったのとNuxt3向けの解説がそこまでなかったので備忘録的にまとめておきます。
最終的なコードから解説
細かい説明などは省いて、設定するためのコードの書き方を中心にまとめます。
用語の説明などがない部分もありますが、基本的にNuxt3の初期設定ぐらいは分かってVueもなんとなく触ったことがあるぐらいの人を想定して記載しています。
分かりづらい箇所などありましたらコメントなどでお知らせください。
サイト共通かつ静的な値はnuxt.config.tsに記載
まずは、サイト全体で共通の項目をnuxt.config.tsに設定します。
ここで指定した値はApp.vueやpages/**/*.vue・layout/**/*.vueで上書きされるようで、フォールバック的に他の項目を設定しておいても問題ありません。
一方でnuxt.config.tsには動的な値が設定できないため、あくまでこちらに記載するのはサイト全体で共通の静的な項目のみとなります。
-
htmlタグにprefixを追加 -
og:typeをwebsiteに指定 -
og:site_nameにサイト名を指定 -
og:imageに画像を絶対パスで指定
export default defineNuxtConfig({
// ...
app: {
head: {
htmlAttrs: {
lang: 'ja', prefix: 'og: https://ogp.me/ns#'
},
meta: [
{ property: 'og:type', content: 'website' },
{ property: 'og:site_name', content: '<サイト名>' },
{ property: 'og:image', content: '<ogpに使われる画像の絶対パス>', },
]
}
}
// ...
});
動的な値の設定はApp.vueで指定
og:urlなどのページごとに異なるが動的に指定可能なものに関してはApp.vueに指定を行います。
layoutが1つしかない場合はlayout/default.vueに設定しても同じように動作します。
<script lang="ts" setup>
import { computed } from '#imports';
import { useHead, useRouter } from '#app';
const router = useRouter();
const currentPath = computed(
() => `https://example.com${router.currentRoute.value.path}`
);
useHead({
meta: [
{ property: 'og:url', content: currentPath }
],
});
</script>
useHead
useHeadは各種コンポーネントから直接<head>を設定できる関数で、この場合は<meta>の追加・上書きに使用しています。
computed
絶対パスを取得するcurrentPathの指定方法ですが、computedを利用しています。
この値はuseRouterを利用して現在のパスを取得していますがcomputedを使用しないと再計算が行われないため指定しています。
`import.meta`を使用する場合の注意点
SSRの場合new URL(import.meta.url)を利用してprotocolとhostを取得できますが、この指定をする場合URLはクライアント側のJSで解決されるためOGPのクローラーが正しく読み取れない場合があります。
そのため各種環境ごとにURLを変更したい場合は.env経由で指定するなどビルド時に解決される方法を選択する必要がありそうです。
余談ですが個人的にVue3を使用していて一番混乱したのがこのcomputedの指定方法でした、reactのstateやpropsのように再計算を行わないため明示的に更新の指示を行う必要があるようです。
ページ固有のものはpages/**/*.vueで指定
最後にページ固有かつ静的な項目はぞれぞれページごとにuseHeadを使用して指定を行います。
og:descriptionについては指定必須ではありませんが設定する場合はpagesで指定するのが適切だと思います。
<script lang="ts" setup>
import { useHead } from "#app";
useHead({
title: '<ページタイトル>',
meta: [
{ property: 'og:title', content: '<ページタイトルを記載>' },
{ property: 'og:description', content: '<descriptionを記載>' }
]
});
</script>
動的ルーティングを使用している場合
nuxt/contentなどを使用している場合は動的ルーティングを行っている場合があると思いますがpagesにおいてもApp.vueのように動的な指定が可能です。
下記はnuxt/contentを使用している場合です。
<script lang="ts" setup>
import { useHead, useRoute } from '#app';
import { queryContent } from '#imports';
const route = useRoute();
const content = await queryContent(route.fullPath).findOne();
useHead({
meta: [
{ property: 'og:title', content: content.title },
{ property: 'og:type', content: 'article' },
],
});
</script>
-
useRouteで現在のパスを取得 - 現在のパスから
queryContentでmarkdownのコンテンツを取得 -
content.titleでタイトルを取得
また、記事コンテンツの場合はog:typeもarticleに指定します。
まとめ
自分の環境では上記の設定でTwitterでのOGP表示が行えるようになりました。
Discussion