How to Access Nuxt.js Page Data in Route Meta Fields
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
inasyncData
this.$route.meta
in componentsthis.extendRoutes
in modulescontext.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! ❤️