We have a webpage built with vue.js and nuxt. We use nuxt generate
to generate static html files, which also should contain the SEO and og tags.
That's why we use nuxt's head ()
to generate the meta info.
So far so good.
But now we have a page that asynchronously loads a post into a nested route. If you go to that page, it loads the post's data via ajax call. Then it would use the post's meta to populate the <head>
.
The meta information is updated correctly after some time (after the post is loaded) BUT when we use nuxt generate
the post's data and therefore it's meta info is not present at the time when we generate the meta information with head ()
.
That's why our static html does not contain the necessary meta info. What would be possible solutions for this? Ideal would be that the generation process waits for the post to be loaded. Could it be solved with promises? Or are there some other ideas?
Here this.post
is set to false first.
our helper function generateMetaInfo is called but obviously does not have the correct data.
head () {
this.log('this.post: ', this.post)
if (this.post) {
return generateMetaInfo(this.post)
}
}
We load the post like this, when calling the url:
getPost () {
// Only if postSlug is present
if (this.$route.params.postSlug) {
// If postslug > try to get it from store
if (this.getCompletePostBySlug(this.$route.params.postSlug)) {
this.activePost = this.getCompletePostBySlug(this.$route.params.postSlug)
}
// if it is not in store get it via axios
else {
const ax = axios.create({
baseURL: `${window.location.origin}/${this._checkRouteByString('programm') ? 'events' : 'posts'}`
})
ax.get(`posts.${this.$i18n.locale}.${this.$route.params.postSlug}.json`)
.then((response) => {
const newActivePost = response.data && response.data.items ? response.data.items.find(p => p.slug === this.$route.params.postSlug) : false
if (newActivePost) {
this.post = newActivePost
this.$store.dispatch('data/saveCompletePosts', this.activePost)
} else {
this.post = '404'
}
})
.catch((error) => {
// console.log(error.response)
})
}
} else {
this.setActivePost()
}
},
So we would have to wait for the ajax call to be finished.
Any idea that could help us find a solution is very much appreciated.
Cheers
============================
EDIT:
Using a promise did not work either:
methods: {
getPostMeta: async function () {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
const result = {
title: 'Promise Title Test',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'keywords', content: 'keyword 1, keyword 2'},
{ hid: 'description', name: 'description', content: 'PROMISE. This is the generic promise descr.'}
]
}
resolve(result)
}, 1000)
})
let result = await promise
console.log('result: ', result)
return result
}
},
head () {
return this.getPostMeta()
}
This would not wait until the promise is resolved... :( (of course this was only an example with a timeout, in the real world this would have to be exchanged with an ajax call, getting the post's data)