我们有一个使用vue.js和nuxt构建的网页。我们使用nuxt generate
生成静态html文件,该文件还应包含SEO和og标签。
这就是为什么我们使用nuxt's head ()
来生成元信息的原因。
到目前为止,一切都很好。
但是现在我们有了一个页面,该页面将帖子异步加载到nested route中。如果转到该页面,它将通过ajax调用加载帖子的数据。然后它将使用帖子的元数据填充<head>
。
当我们使用nuxt generate
时,元数据会在一段时间后(在帖子加载后)正确更新,但是,我们使用{生成元信息时,该元信息不存在{1}}。
这就是为什么我们的静态html不包含必要的元信息的原因。 有什么可能的解决方案? 理想的情况是生成过程等待帖子被加载。可以用承诺解决吗?还是还有其他想法?
这里head ()
首先设置为false。
我们的辅助函数generateMetaInfo被调用,但显然没有正确的数据。
this.post
我们在调用url时像这样加载帖子:
head () {
this.log('this.post: ', this.post)
if (this.post) {
return generateMetaInfo(this.post)
}
}
所以我们必须等待ajax调用完成。
非常感谢任何可以帮助我们找到解决方案的想法。
欢呼
============================
编辑:
使用承诺也不起作用:
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()
}
},
这不会等到诺言解决... :( (当然,这只是一个带有超时的示例,在现实世界中,必须将其与ajax调用交换,以获取帖子的数据)
答案 0 :(得分:0)
Nuxt是一个很棒的框架,但是SEO和在动态路由上分配元标记非常困难。这可能不是为什么它不好的极少数原因之一。
我认为这里的主要问题是您试图从仅在Promise或函数解析后才被调用的方法中加载元数据,这意味着直到页面呈现后它才永远不会获取元数据。我不会为此使用函数或诺言。
从本质上讲,我发现解决此问题的方法是,您需要以以下格式加载所有元数据(连同您的帖子名称作为ID或其他内容)
posts: [
{
slug: 'some_id',
meta: [
{
name: 'title',
content: 'some_title'
},
{
...
]
},
{
...
将动态页面分成一个数组-例如,我正在使用VueX商店-然后您可以使用
这样的语句this.$store.state.array.find(p => p.slug === this.$route.params.postSlug).meta
.vue文件中的,其中id是要与route参数比较的任何值。这将返回元数据数组。
我意识到这种方法效率不高,大多数人可能会对此有所畏惧,但是对于动态路线而言,它似乎确实很有效。
我的head()方法看起来像这样
head() {
return {
title: "Title " + this.$route.params.id,
meta: this.$store.state.results.find((result) => result.id === this.$route.params.id).meta
}
}
这对我来说非常有效。如果您尝试这样做,我很想听听它的进展。
欢呼
答案 1 :(得分:0)
您必须使用asyncData
来获取动态数据(例如从api),然后从中获取数据。那将在服务器端获取。
答案 2 :(得分:0)
代码说明
double
将页面标题设置为“ Article + this.page.title中的值”
答案 3 :(得分:0)
在设置元数据之前检查页面对象是否存在。
head() {
if (this.page) {
return {
title: 'Articles: ' + this.page.title
}
}
}