Cover image

How to Access Nuxt.js Page Data in Route Meta Fields

May 13, 2021

Hey folks, this article is about accessing page data in route objects. It's a use case I have frequently stumbled upon, for example when generating sitemaps.

Nuxt pages allow you to define structural data like the meta property or the auth property from @nuxtjs/auth (note that they should not be confused with meta tags). It would be great to be able to access them elsewhere. The route object can be accessed at quite a lot of places:

  • context.route in asyncData
  • this.$route.meta in components
  • this.extendRoutes in modules
  • context.route in Middlewares

I did some testing and found out that the only possibility to access page data outside pages is in asyncData and middlewares, as discussed in this issue. All other places do not work and have empty meta objects. Also, the case discussed in the linked issue adds a meta property in the route object itself, not in the matched array, as it is in vue-router (see the example from vue-router).

Alright, that's the current state. Now, how can we fix it and add page data to route objects?

nuxt-route-meta

I wrote the nuxt-route-meta module that does it by parsing the page components at build time and adding the data to the routes via this.extendRoutes. It's a zero config module, so you can just add it to your nuxt.config.js and it works out of the box.

First, install it via npm install nuxt-route-meta.

Then add it to your nuxt.config.js:

// nuxt.config.js

export default {
  modules: ['nuxt-route-meta'],
}

Now let's create a page with some data like so:

// pages/index.vue

export default {
  auth: true,
  meta: {
    theme: 'light',
  },
}

We are already done with the configuration! Let's go through the cases discussed above:

asyncData:

// pages/index.vue

export default {
  auth: true,
  meta: {
    theme: 'light',
  },
  asyncData({ route }) {
    // route.matched[0].meta.auth = true
    // route.matched[0].meta.theme = 'light'
  }
}

this.$route.meta:

// pages/index.vue

export default {
  auth: true,
  meta: {
    theme: 'light',
  },
  mouted() {
    // this.$route.meta.auth = true
    // this.$route.meta.theme = 'light'
  },
}

this.extendRoutes:

// modules/module.js

export default function () {
  this.extendRoutes(routes =>
    routes.forEach(route => {
      // route.meta.auth = true
      // route.meta.theme = 'light'
    })
  )
}

Middlewares:

// middleware/middleware.js

export default ({ route }) => {
  // route.matched[0].meta.auth = true
  // route.matched[0].meta.theme = 'light'
}

As we can see, we can access the page data everywhere now! That's it already on how to use the module.

Generating a sitemap with non-auth routes

A common use case of accessing page data is sitemap generation, especially conditionally adding entries to the sitemap. We will now configure @nuxtjs/sitemap to only add non-auth routes. So let's add the sitemap module via npm install @nuxtjs/sitemap and add it to our config:

// nuxt.config.js

export default {
  modules: [
    'nuxt-route-meta',
    '@nuxtjs/sitemap',
  ],
}

Filtering the routes is easy now because we only have to check the meta property:

// nuxt.config.js

export default {
  modules: [
    'nuxt-route-meta'
  ],
  ['@nuxtjs/sitemap', {
    filter: ({ routes }) =>
      routes
        .filter(route => [false, 'guest'].includes(route.meta.auth)),
  }],
}

And that's it, if you check /sitemap.xml, you should only see non-auth routes!

Conclusion

That was an introduction to nuxt-route-meta. I hope it's of some use for you! If you like it, feel free to leave a star at star at GitHub 🌟. Also, the module probably needs some more work, so in case you need something or there is a bug, file an issue. Thanks for reading!

If you like what I'm doing, follow me on Twitter or check out my website. Also consider donating at Buy Me a Coffee, PayPal or Patreon. Thank you so much! ❤️

Subscribe via RSS