Home > Net >  How to set Nuxt SSR async metadata in a typescript class component? Fetching using Apollo
How to set Nuxt SSR async metadata in a typescript class component? Fetching using Apollo

Time:12-15

I am trying to set page metadata in Nuxt after fetching data, but doing so inside of a class component. To make matters worse I am fetching using Apollo. There are plenty of examples for using asyncData such as here, and the documentation has information on fetching. However, I am finding that 1) I cannot access the data, or 2) I cannot use this.$apollo.query, if doing either of these inside of a class component. Here is what I have so far based on SO answers and documentation.

Problem with Apollo:

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component({
  head(): Record<string, unknown> {
    return { title: this.response.title }
  },
  async asyncData(): Promise<any> {
    const response = this.$apollo.query({ // <-- does't work
      query: SITE_PAGE,
      variables: {
        path: this.$route.path
      }
    });
    return { response }
  },
})
export default class StandardPage extends Vue {}
</script>

If I just hit a the server instead of Apollo to get data, here is the problem with accessing the data:

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component({
  head(): Record<string, unknown> {
    return { title: this.response.title } // <-- cant access response below / undefined
  },
  async asyncData({ params, $http }) {
    const response = await $http.$get(`https://<myserverapi>/getpage`)
    console.log(response.title) // <--got data along with title
    return { response }
  }
})
export default class StandardPage extends Vue {}
</script>

Could someone please tell me what I am doing wrong or what else I need?

CodePudding user response:

In order to access the data you need to put this: YOUR_CLASS_NAME in the head constructor.

In order to use Apollo you can get access to that by passing in context to asyncData.

The final code would look like this:

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component({
  head(this: StandardPagePage): Record<string, unknown> { // <-- added this:StandardPage
    return { title: this.response.title }
  },
  async asyncData(context): Promise<any> { // <-- added context

    // call to Apollo now looks like this:

    const client = context.app.apolloProvider?.defaultClient
    const response = await client!.query({
      query: SITE_PAGE,
      variables: {
        path: context.route.path,
      },
    })
    return { response }
  },
})
export default class StandardPage extends Vue {}
</script>
  • Related