Vue Routerのナビゲーションガードを使用する方法について書いています。ネット検索をするとunheadを使用する方法がヒットしますが、この記事では使用しません。
注意
以下の方法は、サイトを開いているとtitleタグが更新されてタブの表示も変わりますが、クローラーには認識されません。そもそもページ自体がGoogle Search Consoleでインデックス登録をリクエストしても、404エラーになりました。SPAですからね…
"SEO的にも、headのmetaタグの内容は動的に変更したい!"という場合は、
unheadを導入するとできるようです(参考:https://note.kurodigi.com/vue3-custom-head/)
ステップ 1: ルート定義にタイトルを追加
まず、router/index.js(またはルート定義ファイル)で、各ルートの定義にmetaフィールドを使ってタイトルを定義します。
// router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'ホーム | サービス名' } // ★ 各ページ固有のタイトル
},
{
path: '/works',
name: 'Works',
component: Works,
meta: { title: '実績一覧 | サービス名' }
},
// ... 他のルート ...
];
ステップ 2: グローバルガードでタイトルを更新
次に、Vue RouterのグローバルなbeforeEachナビゲーションガードを使用して、ルーティングが切り替わるたびにドキュメントのタイトル(document.title)を更新します。
// router/index.js (routerのインスタンス定義後)
router.beforeEach((to, from, next) => {
// to.meta.title にルート定義で設定したタイトルが含まれているかチェック
if (to.meta.title) {
document.title = to.meta.title;
} else {
// タイトルが設定されていないページの場合は、デフォルトのタイトルを設定
document.title = 'サービス名';
}
next();
});
export default router;
補足: 動的なタイトルの設定
もし、商品詳細ページのようにURLパラメータに基づいてタイトルを変えたい場合は、コンポーネントのonMountedフック内で直接document.titleを更新します。
<script setup>
import { onMounted, ref } from 'vue';
const productName = ref('特別な商品X'); // 商品名
onMounted(() => {
document.title = `${productName.value} - 商品詳細 | サービス名`;
});
</script>
あとがき
意外と簡単です。今作業している案件は、下層をクローラーに認識させる必要がなかったので、この方法を使いました。
ご指摘やアドバイス等あれば、コメントいただけると嬉しいです!