Updating the head() properties in Nuxt.js via asyncData() is not possible

After creating a server-side rendered Vue.js blog with Nuxt.js using Typescript and Ghost, I encountered a problem updating html metatags with data from asyncData().

According to the Nuxt.js documentation, asyncData() is triggered before loading page components and combines with component data.

However, I keep receiving this error message:

The 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; }'.

Here is my current code snippet:

<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 have attempted various solutions, such as utilizing data() to establish default values for each item, but so far, nothing has worked. Any suggestions or insights would be greatly appreciated.

Answer №1

If you're looking to add Typescript support to your Nuxt project, consider using a typescript plugin like nuxt-property-decorator. Without it, type checking and autocomplete won't be available.

For proper integration, make sure to include asyncData & fetch within the Component options.

@Component({
  asyncData (ctx) {
    ...
  }
})
export default class YourClass extends Vue {
...
}

Rather than placing them outside of the component as shown below:

@Component
export default class YourClass extends Vue {
  asyncData (ctx) {
    ...
  }
}

If you prefer to use asyncData() within your component class instead of setting the option, refer to this demo that showcases the usage of the npm module nuxt-property-decorator.

Answer №2

Below is the updated code with the recommended changes 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
        }
      ]
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to designate the drop-down option as the default selection

Can anyone help me with setting a default drop-down value using JavaScript? I have been struggling to achieve this. You can find my code on jsFiddle <div ng-controller="csrClrt"> <div ng:repeat="(key, item) in items track by $index"> ...

How to Retrieve the Access Token from Instagram using Angular 2/4/5 API

I have integrated Instagram authentication into my Angular 2 project using the following steps: Begin by registering an Instagram Client and adding a sandbox user (as a prerequisite) Within signup.html, include the following code snippet: <button t ...

What is the method of utilizing shared services when the controllers do not rely on any shared services?

Let's imagine a scenario where there is a module containing only one factory, which serves as the shared service. angular.module('sharedService', []) .factory('sharedSrv', sharedService) function sharedService() { var numbe ...

What is the best way to implement dynamic generation of Form::date() in Laravel 8?

Is there a way to dynamically generate the Form::date() based on the selection of 1? If 1 is selected, then display the Form::date() under the Form::select(). However, if 0 is selected, then hide the Form::date() in this particular view. For example: Sel ...

Guide on using the backbone.js save() method to upload multiple files post-form submission

I am currently utilizing Backbone as my JavaScript framework. I have a form where I need the capability to upload up to 10 images simultaneously. To achieve this, I am setting the enctype attribute to "multipart/form-data" in the form tag and including the ...

Is there a way to cancel a fetch request and initiate a new one right away?

Below is an illustration taken from MDN. The example showcases two buttons - one for sending a request and the other for canceling it. var controller = new AbortController(); var signal = controller.signal; var downloadBtn = document.querySelector(&apos ...

Custom Tooltips arrow is not receiving the CSS styling

I have implemented ReactTooltip from the ReactTooltip library You can view an example here Component Setup <ReactTooltip className={styles.customTheme} id={id} place={placement} effect="solid"> {children} </ReactTooltip> Stylin ...

Error: Access Denied - discord.js bot command cannot be executed due to lack of authorization

Every time I initiate the bot and try to execute my "ping" command, an error occurs: js:350 throw new DiscordAPIError(data, res.status, request); ^ DiscordAPIError: Missing Access at RequestHandler.execute (C: ...

Simulating Vue RouterView/RouterLink interaction in Vitest using the Composition API

Can this task be accomplished? I am attempting to test a basic component of a Vue application, which consists of a heading and a button that takes the user to the next page. I aim to verify that when the button is clicked, an event or message is sent to t ...

Instructions on dynamically positioning a collection of div elements at the center of a webpage container

I am looking to create a set of divs that are centered on the page and adjust in size according to the length of the username. .Container1 { display: table; width: 100%; padding:0; margin:0; -webkit-box-sizing: border-box; -moz-box-sizing: bor ...

Building on the powerful foundation of Laravel 5.3, we have crafted a seamless Vue 2.0 form for

I'm encountering difficulties with user authentication using Vue 2.0. Within my Vue application, I have a form where users input their information and submit it via POST to a Laravel endpoint. Once the user is created in the UserController method wi ...

Animation effects compatible with iOS devices are professionally crafted using CSS

I just implemented a custom hamburger menu with animation using HTML, CSS, and JavaScript on my website. The animation works perfectly on Android devices but not on iOS. Any suggestions for fixing this issue? I attempted to add the Webkit prefix to each p ...

Using Vuex to import a specific state value from an object

I have a simple shop: CustomersStore.js state() { return { customers: { name: '', customerHasPermissions: false, } } } I am attempting to use mapState to access the state in my component. When I import th ...

Database entry does not appear in Internet Explorer until the browser is completely shut down and reopened

Currently, I have a form with two dropdowns. Selecting an option from the first dropdown automatically populates the second dropdown. Everything works well except for a minor issue I observed recently. When I add a new item to the second dropdown, it gets ...

Utilize the nest function in D3 to organize flat data with a parent key into a hierarchical structure

I'm searching for an elegant and efficient solution to transform my input data into a hierarchical structure using d3.js nest operator. Here is an example of the input data: [ {id: 1, name: "Peter"}, {id: 2, name: "Paul", manager: 1}, {id: 3, name: " ...

What is the best way to assign attributes to multiple HTML elements using an array?

Seeking assistance to hide various sections in my HTML file upon button click, with the exception of one specific section. Encountered an error message: Uncaught TypeError: arr[i].setAttribute is not a function Here's a snippet of my code: const hide ...

How can I style the inner div by adding a class to the first div?

In my project, I have a list of elements that are generated dynamically, all styled the same way but with different content. The first element has a specific styling, and if it doesn't render, I want the second element to inherit that styling. < ...

The minimum and maximum validation functions are triggered when I am not utilizing array controls, but they do not seem to work when I use array controls

Take a look at the stack blitz example where min and max validation is triggered: https://stackblitz.com/edit/angular-mat-form-field-icrmfw However, in the following stack blitz with an array of the same controls, the validation does not seem to be worki ...

The Vue application experienced issues with Github Actions as it began to encounter node pre-gyp errors

Today, while working on a project in GitHub, I encountered an issue where my Actions failed with the following error: npm ERR! code 1 ... The strange part is that I didn't make any recent changes from the previous successful PR. I haven't instal ...

Maintain the visibility of the jQuery dropdown menu even when navigating to a different page within the

I am experiencing an issue with my dropdown menu. Whenever I click on a "dropdown link", it opens another page on my website, but the menu closes in the process. I want to ensure that the menu stays open and highlights the clicked "dropdown link" in bold. ...