Adding Meta tags in Nuxt 3 and Nuxt Content 2
As a developer, I love to build websites. I enjoy the process itself and the results I see. As a product owner, I want to make the website noticeable in search engines and social media. To make that happen, you need to work on your website Meta tags. Adding Meta, Open Graph, and Twitter Meta tags are the same in Nuxt.
As for now, Nuxt 3 is still not released, so that things may change in the future.
There are several ways to set the Meta tags in Nuxt 3. Not all of them are dynamic:
- nuxt.config.ts (dynamic ❌)
- useHead composable (dynamic ✅)
- Meta components (dynamic ✅)
- useMeta (deprecated)
Let's see how you can use them in your code.
Nuxt.config.ts
You can set the META tags in nuxt.config.ts
. I believe this is a good place for the tags
that rarely / never change.
export default defineNuxtConfig({ // Global page headers: https://go.nuxtjs.dev/config-head app: { head: { htmlAttrs: { lang: 'en' }, meta: [ {name: 'viewport', content: 'width=device-width, initial-scale=1'}, {property: 'og:site_name', content: 'XDEVS.PRO'}, {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'}, {property: 'og:url', content: 'https://xdevs.pro/'}, {property: "og:type", content: "website"}, ], link: [ {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'} ] }, },})
useHead composable
It can be used to set constant Meta tags, or you can use it in combination with useRoute
, which adds a bit of flexibility. useHead
can be used both globally and on per page basis.
In your app.vue
, you can set global Meta tags in useHead
composable:
<script setup lang="ts">const route = useRoute()useHead({ title: 'My App', // or, instead: // titleTemplate: (title) => `My App - ${title}`, viewport: 'width=device-width, initial-scale=1, maximum-scale=1', charset: 'utf-8', meta: [ {property: 'og:url', content: computed(() => `https://xdevs.pro${route.path}`)}, // extract og:type from route.meta.ogType which is defined in definePageMeta({}) on any other page {property: 'og:type', content: computed(() => route.meta.ogType || 'website')} ],})</script>
Any other page component, e.g., blog/index.vue
// You can override the global title // that was set in app.vue like thisuseHead({ title: 'XDEVS Team Blog – our latest articles 📚', }) // it won't have direct access to your meta tagsdefinePageMeta({ layout: 'blog', ogType: 'OgType', otherArgs: youWantToPass })
useHead Title Templates
Finally, something we can use to set the page title dynamically. Unfortunately, it works only with the title
tag.
// in your app.vue, add the following.const route = useRoute()useHead({ // route.meta.title is is defined in definePageMeta({}) in another page component titleTemplate: (titleChunk) => { return titleChunk || route.meta.title || 'Site Default Title' },})
Now you can set the title using definePageMeta
or useHead
on any other page of your website.
useHead({ title: 'Some other page title.',})
or
definePageMeta({ title: 'Any other page title.',})
In case no title is set, the default title will be used.
definePageMeta
definePageMeta
is extracted at build time via a macro, so it can't be set dynamically.
It extends route.meta
with any non-dynamic information you pass. It's important to notice that you can't set Meta tags using definePageMeta
without using useHead
composable.
page1.vue
definePageMeta({ someInformation: 'You may need elsewhere available at a build time.'})
app.vue
const route = useRoute()console.log(route.meta.someInformation)
Meta components
You may find the Meta component a more flexible and valuable solution to set Meta tags.
Nuxt provides
<Title>
,<Base>
,<Script>
,<Style>
,<Meta>
,<Link>
,<Body>
,<Html>
and<Head>
components so that you can interact directly with your metadata within your component's template.
They can be used with any dynamic data like a regular Nuxt component.
<template> <div> <Head> <Meta property="og:title" content="XDEVS – Top Software Engineers for your needs ❤️🔥"/> <Meta property="og:description" content="Web / mobile app development and consulting across different cycles of your product life." /> <Meta name="description" :content="pageDescriptionRef" /> </Head> </div></template>
How do I set META tags with Nuxt Content v2?
Managing Meta tags in Nuxt Content is made very easy.
Front-matter:
Front-matter is a convention of Markdown-based CMS to provide meta-data to pages, like description or title. In Nuxt Content, the front-matter uses the YAML syntax with
key: value
pairs.
yourArticle.md
---
title: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2
description: Your article description.
---
useContentHead()
This is basically the same as useHead()
that we talked about earlier.
useContentHead() is a composable providing a binding between your content data and
useHead()
.
yourArticle.md
---
title: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2
description: Your article description.
image:
src: '/assets/image.jpg'
alt: 'An image showcasing My Page.'
width: 400
height: 300
head:
meta:
- name: 'keywords'
content: 'nuxt, vue, content'
- name: 'robots'
content: 'index, follow'
- name: 'author'
content: 'NuxtLabs'
---
Moreover, you can dynamically use Nuxt Meta components
to set Meta tags on the article page. To see a real-world example of setting Meta tags in the Nuxt 3 project, you can check our repo.
Conclusion
There is definitely more than one way to set Meta tags in the Nuxt 3 framework. Is it bad or good? It's up to you. Having the possibility to make the same thing in multiple ways may be confusing for some people, including myself, but as Nuxt 3 is getting released, I believe we will get more clarification regarding adding Meta tags :)