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