skip to Main Content

I have a Nuxt3 application where a blog article is loaded from Firestore using an ID that is passed as a path variable. To make my site more SEO friendly, I want to populate Nuxt title and meta tags (<Title> and <Meta>) with information regarding the article such as the title and images. However, it seems that by the time that the article data was retrieved from Firestore, the page has loaded, leaving the meta tags temporarily empty. Although it is temporary, since the request is deemed to be completed, the meta tags are considered to be empty when tested on Postman. SSR is set to true. I prefer to use the Options API, if possible.

Is there a solution that would allow for the meta tags to be populated with the data fetched from Firestore before the page has loaded?

I tried playing with SSR settings and moving the code in beforeMount() to created() and mounted() , but no luck. I am new to Nuxt, and it would be fabulous if you could help me out.

/pages/app/[id].vue


<script>
export default {
  name: "AppPage",
  data() {
    return {
      title: "",
      catchphrase: "",
      images: [],
      description: "",
      owner: "",
      url: "",
      isOwner: false,
    };
  },
  async beforeMount() {
    const auth = getAuth();
    const id = this.$route.params.id;
    const docRef = await doc(this.$db, "apps", id);
    getDoc(docRef).then(async (doc) => {
      if (doc.exists()) {
        const data = doc.data();
        this.title = data.title;
        this.catchphrase = data.catchphrase;
        this.images = data.images;
        this.description = data.description;
        this.owner = await (await getDoc(data.owner)).data();
        this.url = data.url;

        auth.onAuthStateChanged((user) => {
          if (user) {
            if (user.uid === this.owner.id) {
              this.isOwner = true;
            }
          }
        });
      } else {
        console.log("No such document!");
      }
    });
  }
}
</script>

<template>
  <Head>
    <Title>{{ title }}</Title>
    <Meta name="description" :content="catchphrase"/>
    <Meta property="og:title" :content="title"/>
    <Meta property="og:description" :content="catchphrase"/>
    <Meta property="og:image" :content="images[0]"/>
    <Meta property="og:url" :content="url"/>
    <Meta property="og:type" content="website"/>
    <Meta property="og:site_name" content="Circle4Devs"/>
    <Meta name="twitter:card" content="summary_large_image"/>
    <Meta name="twitter:site" content="@Circle4Devs"/>
    <Meta name="twitter:title" :content="title"/>
    <Meta name="twitter:description" :content="catchphrase"/>
    <Meta name="twitter:image" :content="images[0]"/>
  </Head>

  <div id="article">
      ...
  </div>

Here is a response given by postman. The meta tags are empty

image

Here is a response given by the browser a few moment after the page has loaded. The meta tags here are populated.

image

2

Answers


  1. You can use the useHead Composable

    useHead({
      title: "My page with ads",
      // or, instead:
      // titleTemplate: (title) => `My App - ${title}`,
      viewport: "width=device-width, initial-scale=1, maximum-scale=1",
      charset: "utf-8",
      meta: [{ name: "description", content: "My amazing site." }]
    })
    

    You can use the useSeoMeta Composable too:

    useSeoMeta({
      description: 'My about page',
      ogDescription: 'Still about my about page',
      ogTitle: 'About',
      ogImage: '<>',
      twitterCard: 'summary_large_image',
    })
    

    Or even, for performance reasons, useServerSeoMeta:

    useServerSeoMeta({
      robots: 'index, follow'
    })
    

    You should place them inside your <script> tag and don’t need to import anything.

    Sources:

    https://nuxt.com/docs/api/composables/use-head

    https://nuxt.com/docs/api/composables/use-seo-meta

    https://nuxt.com/docs/api/composables/use-server-seo-meta

    Login or Signup to reply.
  2. In a Nuxt.js application, you can populate meta tags before the page is completely loaded using the head property in your pages or components. The head property allows you to define metadata for the page, including title, meta tags, and more. To dynamically update meta tags before the page is fully loaded, you can use the asyncData or fetch methods.

    Here’s an example using the asyncData method:

    Javascript Code

    <template>
      <!-- Your component template -->
    </template>
    
    <script>
    export default {
      async asyncData({ params }) {
        // Fetch data or perform any asynchronous operation to get dynamic information
        const dynamicData = await fetchData(params.id);
    
        // Set dynamic data to meta tags
        return { dynamicData };
      },
    
      head() {
        return {
          title: this.dynamicData.title, // Set the dynamic title
          meta: [
            {
              hid: 'description',
              name: 'description',
              content: this.dynamicData.description, // Set the dynamic description
            },
            // Add other meta tags as needed
          ],
        };
      },
    };
    </script>

    In this example:

    The asyncData method is used to fetch dynamic data. Replace fetchData with your actual data fetching function. The dynamic data is then returned as part of the component’s data.

    The head method is used to dynamically set the title and meta tags based on the fetched data. this.dynamicData refers to the data fetched in the asyncData method.

    Make sure to adapt the code to fit your specific use case and data fetching requirements. Additionally, consider error handling and loading states depending on your application’s needs. SEO friendly

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search