Search code examples
javascriptvue.jsnuxt.jsvue-meta

How to await for the post data before the page meta head property in Nuxt?


I'm using Nuxt SSR to dynamically inject the head property to set page level meta data. The data is fetching from Firebase. I'm getting property undefined because it doesn't wait for the post data finish loading. How do I wait for the post data before the head property?

client.js?16a3:97 TypeError: Cannot read property 'post' of undefined

// page\:post.vue
<script>
import { mapState, mapActions } from 'vuex'
export default {
  fetch() {
    this.fetchPost()
  },
  computed: {
    ...mapState('posts', ['post']),
  },
  methods: {
    ...mapActions('posts', ['fetchPost']),
  },
  head: {
    title: this.post.title,
    link: [{ rel: 'canonical', href: this.post.canonical }],
    meta: [
      { hid: 'name', itemprop: 'name', content: this.post.title },
      {
        hid: 'description',
        itemprop: 'description',
        content: this.post.content,
      },
    ],
  },
}
</script>

// store\posts.js
export const state = () => ({
  post: null,
})
export const mutations = {
  setPost(state, payload) {
    state.post = payload
  },
}
export const actions = {
  async fetchPost({ commit }, key) {
    const doc = await postsCollection.doc(key).get()
    if (doc.exists) commit('setPost', doc.dat())
  },
}


Solution

  • The way you construct the head (object) could be changed to be a function.

    head() {
        return {
            title: this.post.title,
            link: [
                { rel: 'canonical', href: this.post.canonical }
            ],
            meta: [
                { hid: 'name', itemprop: 'name', content: this.post.title },
                {
                    hid: 'description',
                    itemprop: 'description',
                    content: this.post.content,
                },
            ],
        }
    }
    

    I read a similar post on GitHub here. Since you are using the store I assume you are also using the asyncData function to fetch them.