I created a server-side rendered Vue.js blog using Nuxt.js with Typescript and Ghost but I'm having some issues to update html metatag using data from asyncData()
.
From Nuxt.js documentation I know that asyncData()
is called every time before loading page components and merges with component data.
I'm getting this error:
Property 'title' does not exist on type '{ asyncData({ app, params }: Context): Promise<{ title: string | undefined; excerpt: string | undefined; feature_image: Nullable | undefined; html: Nullable | undefined; }>; head(): any; }'.
This is my code:
<script lang="ts">
import { Context } from '@nuxt/types'
import { PostOrPage } from 'tryghost__content-api'
export default {
async asyncData ({ app, params }: Context) {
const post: PostOrPage = await app.$ghost.posts.read(
{
slug: params.slug
},
{ include: 'tags' }
)
return {
title: post.title,
excerpt: post.excerpt,
feature_image: post.feature_image,
html: post.html
}
},
head () {
return {
title: this.title,
meta: [
{
hid: 'description',
name: 'description',
content: this.excerpt
}
]
}
}
}
</script>
I already tried some solutions like using data() to set a default value for each item but nothing. Do you have any suggestion?
CodePudding user response:
Without a typescript plugin like nuxt-property-decorator
you won't have Typescript support for nuxt (type checking and autocomplete still won't work).
That's why asyncData
& fetch
should be in Component options.
@Component({
asyncData (ctx) {
...
}
})
export default class YourClass extends Vue {
...
}
instead of
@Component
export default class YourClass extends Vue {
asyncData (ctx) {
...
}
}
If you still want to use asyncData()
inside of your component class instead of setting the option, see this working example
CodePudding user response:
Here is the working code after implementing the suggestion from @nonNumericalFloat :
import { Component, Vue } from 'nuxt-property-decorator'
import { Context } from '@nuxt/types'
import { PostOrPage } from 'tryghost__content-api'
import Title from '~/components/Title.vue'
@Component({
components: {
Title
}
})
export default class Page extends Vue {
post!: PostOrPage
async asyncData ({ app, params }: Context) {
const post: PostOrPage = await app.$ghost.posts.read(
{
slug: params.slug
},
{ include: 'tags' }
)
return {
post
}
}
head () {
return {
title: this.post.title,
meta: [
{
hid: 'description',
name: 'description',
content: this.post.excerpt
}
]
}
}
}