March 14, 2021

How To Work With Meta Data in Nuxt

What is meta data?

First let us talk about what meta data is. You can provide information about a html document inside <meta> tags. Meta tags belongs inside the <head> element of a html document. Meta tags could hold information about the following:

Meta data is not visible on the page. It gets parsed by the browser and search engine crawlers. You can inspect a webpage and look in the <head> tag for all the <meta> tags available on that page. The data inside the meta tags are not hidden in that sense.

Example of meta tags

<head>
	<title>Current title</title>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<meta name="description" content="This is my description that could be visible in search engine result pages" />
	<meta name="author" content="Rasmus Langvad" />
</head>

Technically the <title> tag is not a meta tag. It is commonly referred to as meta data and it have an impact on SEO and user experience. So I recommend to treat it that way.

For a complete list of available meta tags I like this list: Complete List of HTML Meta Tags.

What is Open Graph?

Open Graph is a protocol created by Facebook. With the purpose of structure information on links shared on social media platforms. The tags give the author the opportunity to decide what content is shown in the preview when sharing a link. The Open Graph meta tags adds a prefix to the property value with og:. Twitter also have their own tags for setting meta data. Instead of og: they use twitter:. Twitter also uses og tags as a fallback.

An example with og tags

<head>
	<meta property="og:title" content="Current title" />
	<meta property="og:description" content="Custom description. Might be the same as meta description" />
	<meta property="og:image" content="https://langvad.dev/image.jpg" />
	<meta property="og:url" content="https://langvad.dev" />
</head>

An example with Twitter tags

<head>
	<meta name="twitter:card" content="summary" />
	<meta name="twitter:creator" content="@rlangvad" />
	<meta name="twitter:description" content="Custom description. Might be the same as meta description" />
</head>

If you want to know more about the Open Graph and Twitter specific tags and which ones are required and recommended to use, I suggest reading The Essential Meta Tags for Social Media on CSS-Tricks.

How to set meta data in Nuxt

So, now we know what meta tags are and how they are being used to show information about your website. But how do we set the meta data values dynamically for each page? Lets say we have a blog. Like this one. Where we want to show a different title and description based on the current blog post.

In Nuxt you have access to a special property called head. The head property is next to all the other properties in a component. On the same level as data, fetch, methods etc. It can be either an object or a function. I will soon explain the difference. With the head property you can set title and meta data for each page in your application. You can also use head to set everything related to the <head> tag. Meaning you can add stylesheets, script tags, link tags and more. In this article I will focus on the meta data part but it’s useful to know the other parts as well.

Using the head property

You can set the data in head from any Vue component. The most common use case is to use head inside your pages components. It’s not that common to set the data from a smaller component that are being used on multiple pages. But it is possible. So we have some pages and want to set some meta data. All we need to do is to add the head property and set the data we want. Lets add a title and description.

export default {
	head: {
		title: 'My title',
		meta: [
			{
				hid: 'description',
				name: 'description',
				content: 'My description',
			},
		],
	},
}

As I mentioned before the title tag is not really a meta tag. Therefor it is being set outside the meta array property. If we take a look at the description property you might wonder what the property hid is. This is something specific for Nuxt and is being used as a unique identifier so the correct property can be overwritten by child components. So if the want to set the description from within a child component we need to use the same hid value.

When setting the meta data as above the values of title and description are not very dynamic. If we want to use static information we can use the object version of the head property. But it we want to set som dynamic data, for example title and description of this blog post, we need to use head as a method. Let me show you how I use head for this blog post.

head() {
    return {
        title: this.article.title,
        meta: [
            {
                hid: 'description',
                name: 'description',
                content: this.article.description,
            },
            {
                hid: 'og:title',
                name: 'og:title',
                content: this.article.title,
            },
            {
                hid: 'og:image',
                property: 'og:image',
                content: `/${this.article.image}`,
            },
            {
                hid: 'og:description',
                property: 'og:description',
                content: this.article.description,
            },
            {
                hid: 'og:url',
                property: 'og:url',
                content: `https://langvad.dev/blog/${this.article.slug}`,
            },
        ],
    }
},

Here I’m using the head as a function that returns an object. I’m setting all the meta data based on information on the current article. Making it more dynamic and unique for each page.

Setting meta data in nuxt.config

You also have access to the head property inside your nuxt.config.js file. Here you can set default values used on every page. Useful if you don’t want to duplicate some basic meta data for all pages in your application. You can also use a template for you title. If you want every title on your site to end with for example your site name. You can set this up from here with the titleTemplate property.

head: {
    title: 'My title',
    titleTemplate: '%s - langvad.dev',
    meta: [
        ...
    ]
}

Now every title will end with - langvad.dev. The %s symbol is a placeholder for whatever value is being set as title.

Using the new useMeta helper

Even though Nuxt 3 is not released yet you can use the upcoming new features related to Vue 3. For example the useMeta helper. Check out Nuxt Composion API Module for more information. The useMeta helper can be used within the setup() method. This makes it easier to set dynamic data and more clear on what data is being used. To enable the functionality of useMeta you need to import the helper and set the head property to an empty object. A basic example could look something like this.

import { defineComponent, useMeta } from '@nuxtjs/composition-api'

export default defineComponent({
	head: {},
	setup() {
		useMeta({
			title: 'My title',
			meta: [
				{
					hid: 'description',
					name: 'description',
					content: 'My description',
				},
			],
		})
	},
})

This is a neat way of setting our meta data. But it doesn’t look any different than using it in the head property directly. Which still of course is possible. useMeta is only a helper. If you want to have a more dynamic way of setting the data you could get the variables returned by useMeta.

import { defineComponent, useMeta } from '@nuxtjs/composition-api'

export default defineComponent({
	head: {},
	setup() {
		const { title } = useMeta()
		title.value = 'My title'
	},
})

In this case you can change the value of title within the setup method. Maybe the value is different based on some logic or data being fetched. Instead of initialising useMeta every time we want to change the data we can change the value of the variable title. We could also get the variable meta and apply changes to description and all the meta properties available in the meta array.

What if I want to make changes to the title (or any other meta data) from outside setup? Maybe the title should change based on some user interaction on the page. Our last example makes the title editable within the setup method. But it will not be accessible from our component. To achieve this we need to make a reactive variable and pass it in with a function to useMeta. By returning the reactive variable we can access it from our template and other parts of the component.

<template>
	<div>
		<button @click="title = 'New title'">Change title</button>
		<button @click="title = 'Another new title'">Change title again</button>
	</div>
</template>

<script lang="ts">
import { defineComponent, useMeta, ref } from '@nuxtjs/composition-api'

export default defineComponent({
	head: {},
	setup() {
		const title = ref('')
		useMeta(() => ({ title: title.value }))

		return {
			title,
		}
	},
})
</script>

Summary

Meta data is essential for how your site will look like in the eyes of search engine crawlers, social media platforms and your users. It is important to understand these concepts and how you can work with dynamic data. I hope this article made some concept clear and that you got some inspiration on how to work with meta data within your application. As your application grows there are many ways you can handle meta data in a a more structured way. It is very common to have some kind of meta data helper function. Since the meta data is only a plain object you can have a function that returns the meta object based on some input. This makes it even more dynamic and easier to work with on multiple pages.

Thank you for reading this far! 🎉

Follow me on Twitter for more inspiration and dev tips.

Feel free to reach out if you have any feedback or questions.

Check out the blog page for more articles.