I have developed a Vue app that has navigation and content on each page. What i need is to setup meta tags for each different page for Twitter and Facebook cards. For that i use vue-meta library and I have come up with the following code:
metaInfo() {
return {
meta: [
{
property: 'og:title',
content: `Card #${this.card_no ? this.card_no : ''}`,
vmid: 'og:title'
},
{
property: 'og:image',
content: `${this.card ? this.card.participantA.image : ''}`,
vmid: 'og:image'
},
{
property: 'og:description',
content: `${this.card ? this.card.description : ''}`,
vmid: 'og:description'
},
{
property: 'twitter:title',
content: `Card #${this.card_no ? this.card_no : ''}`,
vmid: 'twitter:title'
},
{
property: 'twitter:image',
content: `${this.card ? this.card.participantA.image : ''}`,
vmid: 'twitter:image'
},
{
property: 'twitter:description',
content: `${this.card ? this.card.description : ''}`,
vmid: 'twitter:description'
},
{
name: 'twitter:card',
content: `summary_large_image`,
vmid: 'twitter:card'
}
]
}
}
The properties are fetched from an API at the mounted() hook and I can see they are properly added. But the sharing is yet no working, what I believe is they need to be added to the main index.html? But that is impossible in my case since they are dynamic and not always fixed. Is there a way around this? I know that SSR can solve the issue but that is currently not an option since re-writing most of the app using Nuxt is not acceptable at this point of time.
4
Answers
To explain simply what I did is took some advice from all comment above and used a solution in between, shortly I added another middleware in my Express backend that will intercept social bots:
So if the request is from a bot I just render a view using mustache
If the request if not from a bot i just call
And bellow is the code of the index.mustache file I am using:
You can implement SSR without nuxt in any vue app. Unfortunately, I haven’t done this myself. But, you can look at this package:
https://github.com/vuejs/vue/tree/dev/packages/vue-server-renderer#readme
I faced the similar issues and spent a lot of time in coming with the right solution which involved least amount of code changes in an already tested production-ready code.
You can see my question here – Keeping asset and public path different in vue app for CDN
I finally circled out on Rendertron and it worked like a charm. If you face any issues in it’s setup, I can help you further. You can see how rendertron renders a particular page in this sandbox app – https://render-tron.appspot.com/
Crawlers don’t execute JS, so any solution that uses JS will not work. You’ll see the meta’s being rendered because your browser executes it.
I had a similar problem and I ended up using the following solution.
This solution is easy to implement if you already use AWS as your hosting.
Note: Google and co don’t consider this as cloaking, at least for now.