SPA(vue.js2)のSEO対策の以下つの問題点を解決したい。
1) SPA(vue.js2)で動的なメタタグを読み込ませたい
2) vue-headだとディスクリプションが変わるたびに増えていくため、制御したい。
何卒よろしくお願いいたしますm(_ _)m
■環境
Laravel, vue.js
■現状
- ライブラリ:vue-head
動的にメタタグの変更はできるが、変更後のメタタグがSEOで読み込まれていない。
必ずこれでなければいけないというわけではありませんので、おすすめのライブラリがございましたら、教えていただきたいです。
- 確認方法
こちらのサイトにURLを貼り付けると、読み込まれたメタタグ、ディスクリプションが表示されるのですが、検証ツール上では表示されているメタタグ(タイトル、ディスクリプション)がサイト上では表示されない。
SEO確認サイト上表示
画像のLaravelと記載があるところに「北海道 | アプリ名」という動的に読み込まれた内容が入っていて欲しいのですが、.envに設定している初期の値が反映されている。
(discriptionも値を渡しているので反映されて欲しい。)
2)ディスクリプション
vue-headだとディスクリプションが変わるたびに増えていってしまうという問題もあり、
こちらも合わせてご存知の方がいれば解決策を教えていただきたいです。
該当のソースコード
■ index.blade
php
1<!DOCTYPE html> 2<html lang="{{ config('app.locale') }}"> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <meta name="csrf-token" content="{{ csrf_token() }}"> 8 <meta name="robots" content="noindex,nofollow"> 9 <title>{{ config('app.name') }}</title> 10 <link rel="stylesheet" href="{{ mix('css/app.css') }}"> 11 <link 12 href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" 13 rel="stylesheet" 14 /> 15 <link 16 href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" 17 rel="stylesheet" 18 /> 19 {{-- Bootstrap CSS --}} 20 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"> 21 <link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet"> 22 </head> 23 <body> 24 <div id="app"></div> 25 </body> 26 <script src="{{ mix('js/app.js') }}"></script> 27 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 28 {{-- Bootstrap --}} 29 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.4/umd/popper.min.js"></script> 30 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script> 31 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/js/mdb.min.js"></script> 32</html>
■ App.vue
全てのページの大元
js
1<template> 2 <RouterView /> 3</template>
■ main.vue
各ページが RouterView として表示される感じの設計です。
各ページから 親にemitとしてヘッダーの変更を伝えています。
this.$emit('updateHead', <表示したいタイトル>)
js
1<template> 2 <div> 3 <RouterView @updateHead="updateHead" /> 4 </div> 5</template> 6 7<script> 8export default { 9 data: () => ({ 10 metaTitle: '', 11 }), 12 13 head: { 14 title() { 15 return { 16 // innerに入力したものがタイトルになりますが、separatorとcomplementを使用すると「タイトル | 捕捉」のようになります。 17 inner: this.metaTitle, // ■ 動的に切り替えたいタイトル 18 separator: '|', 19 complement: 'アプリ名', 20 } 21 }, 22 meta() { 23 return [{ name: 'description', content: this.discription }] 24 }, 25 }, 26 methods: { 27 updateHead(title, discription) { 28 this.metaTitle = title 29 this.discription = discription 30 this.$emit('updateHead') 31 }, 32 }, 33} 34</script> 35
■ 子供.vue
全てのページの大元
js
1 async created() { 2 this.showLoader() 3 await this.fetchBoatShowViewer(this.id) 4 await this.$emit('onLoading', this.metaTitle, this.discription) // ■ ここで親に渡してます。 5 await this.fetchCityListByPrefecture(this.boatDetail.lender.prefecture.id) 6 await this.fetchLenderPostIndex() 7 this.hideLoader() 8 }, 9 10 methods: { 11 async fetchBoatShowViewer(id) { 12 this.showLoader() 13 await boatRepository 14 .viewerShow(id) 15 .then(res => { 16 if (res.status !== HTTP_STATUS.OK) { 17 this.$toast.errorToast() 18 return 19 } 20 this.boatDetail = res.data 21 const targetList = this.boatDetail.targets 22 const paymentOptionList = this.boatDetail.lender.payment_options 23 const operationList = this.boatDetail.operations 24 // meta設定 ■ メタとディスクリプションの内容はここで決定します。 25 this.metaTitle = this.boatDetail.lender.prefecture.prefecture_name // ■ メタとディスクリプションの内容はここで決定します。 26 this.discription = this.boatDetail.lender.prefecture.prefecture_name // ■ メタとディスクリプションの内容はここで決定します。 27 this.$emit('updateHead', this.metaTitle, this.discription) 28 }.....省略 29 } 30
試したこと
ライブラリvue-headを使用して、メタ、ディスクリプションの変更を行いました。
問題、課題
読み込みがワンテンポ遅れているのか、google SEOには反映されていない様子。
あなたの回答
tips
プレビュー