Ultimate SEO Guide for Nuxt 3
A comprehensive guide to successful technical search engine optimization with Nuxt 3. Learn topics such as HTML basics, JSON-LD, OGP and Sitemap generation.
:quality(80))
The content shown in this post is related to Nuxt 3. If you are looking for SEO with Nuxt 2, you can check out the post Simple steps for successful SEO with Nuxt 2.
Basics
Title & Description
The most basic measures for SEO is probably setting the title and description of the respective pages. The title and description show up in search engine results and are very important to convince the visitor of your website.
:quality(80))
To set the title and description of a page, Nuxt 3 has the Composable useHead
, which can be called inside <script setup>
of every page and component.
<script setup lang="ts">
useHead({
title: 'Nuxt: The Intuitive Web Framework',
meta: [
{
name: 'description',
content: 'Build your next Vue.js application with confidence using Nuxt....'
},
],
});
</script>
As an alternative, you can also use meta components like <Title />
or <Meta />
provided by Nuxt. These work similar to useHead
, only on the template level, and has to be wrapped around the <Head />
component.
<template>
<Head>
<Title>Nuxt: The Intuitive Web Framework</Title>
<Meta
name="description"
content="Build your next Vue.js application with confidence using Nuxt...."
/>
</Head>
</template>
Take a look at the list of all available meta components to learn more about them.
From now on, we will focus only on the use of useHead
.
Language
You should always specify which language your site is in. For example, if your site has only one language, you could specify it globally in the app.vue
or continue to specify it on a page-by-page basis. For this, you can again use the useHead
method.
<script setup lang="ts">
useHead({
htmlAttrs: { lang: 'en' },
});
</script>
Canonical
The canonical URL describes where the original content of your page is located at and should be set for each page. Search engines will consider the canonical URL with increased relevance.
<script setup lang="ts">
useHead({
link: [{ rel: 'canonical', href: 'https://nuxt.com/' }],
});
</script>
Open Graph protocol (OGP)
Specifying metadata for social media is an important aspect, allowing you to generate a detailed preview card of your pages when sharing. In this example, we will cover how to implement Facebooks Open Graph protocol (OGP).
The Open Graph protocol enables any web page to become a rich object in a social graph. For instance, this is used on Facebook to allow any web page to have the same functionality as any other object on Facebook.
The Open Graph protocol
You should specify at least the title, type, image, and the URL of the page. You can of course specify other properties like a description or the language. For more in depth information, read further on Open Graph protocol.
<script setup lang="ts">
useHead({
meta: [
{ property: 'og:title', content: 'The Intuitive Web Framework' },
{ property: 'og:description', content: 'Build your next Vue.js application with confidence using Nuxt...' },
{ property: 'og:type', content: 'website' },
{ property: 'og:url', content: 'https://nuxt.com' },
{ property: 'og:locale', content: 'en_US' },
{ property: 'og:image', content: 'https://nuxt.com/social.jpg' },
});
</script>
These details will result in a preview with title, description and image when shared on social media, as shown in the image below.
:quality(80))
Structured data (JSON-LD)
JSON-LD is a standardized format for writing structured data. For example, you can store FAQ elements of your website as structured data and these will show up in search results as questions and answers element if implemented correctly.
Setup
We will use the Nuxt module nuxt-jsonld. First, install the dependency.
npm install nuxt-jsonld
Now add it to your modules inside your Nuxt configuration.
export default defineNuxtConfig({
modules: ['nuxt-jsonld'],
});
Implementation
Now we have the composable useJsonld()
available within <script setup>
, allowing us to specify any structured data. In the following we will add a single FAQ element to the page as structured data.
<script setup lang="ts">
useJsonld({
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: [
{
'@type': 'Question',
name: 'How do I implement SEO with Nuxt 3?',
acceptedAnswer: {
'@type': 'Answer',
text: 'I think you have the solution in front of you.',
},
},
],
});
</script>
You can use the playground of json-ld.org to try out some examples. Also, you can test your structured data at any time with Test Rich Results. On Schma.org, you can see all the different types and parameters that are available to use.
HTML
Headline hierarchy
Search engines try to understand your website. It is advisable to establish a well-structured heading structure. For example, each page should only have one <h1>
element. The headings should be logically structured according to the content.
But you don't have to check the structure manually in your HTML. There are tools for that. If you use Google Chrome, I can highly recommend META SEO inspector.
:quality(80))
Links
Links should always contain a text and the relation attribute like rel="external"
. Search engines try to understand these links. If you have a link with only an icon, you can still place a text and hide the text via CSS. Include this information with all links. The list of possible rel
values can be seen in this MDN article.
Images
With images, it is like with links, only here other attributes are used.
Each image must contain an alternative text that describes the image. This is implemented by using the
alt
attribute.The
loading
attribute specifies when the image should load. Suppose an image is far outside the visibility area, then the image does not necessarily have to be loaded. In this case, the value can belazy
. The image will load only when you approach it. If you want the image to load immediately, specify the valueeager
.Always use the
width
andheight
attributes to avoid layout shift (CLS). Search engines like Google will rank your page poorly if the layout of your page shifts as it builds.The
title
is also helpful for accessibility and understanding the context by search engines.
<template>
<img
src="https://placeholder.pics/svg/640x480"
alt="A description of the image"
loading="lazy"
width="640"
height="480"
title="A description of the image"
/>
</template>
Favicon
Your website should also show your logo in the browser tab. For this purpose, there is a really handy tool called realfavicongenerator. You can upload your logo, and it will help you convert it to favicons. After that, you can download the favicons and paste them into your /public
directory.
The only thing left for you to do is to include the favicons globally. For this, we will use app.vue
in this example to set the favicon globally.
This is how it could look like:
<script setup lang="ts">
useHead({
link: [
{ rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' },
],
});
</script>
Sitemap
Every website should have a sitemap. The sitemap allows your website to be indexed by search engines. It contains all the subpages of the website that you want to show as well. Mostly, the sitemap is called sitemap.xml
and is addressable in the main directory of a page.
A solution for the sitemap will be added in the future.
Conclusion
I hope you were able to get a good insight into how to successfully implement for SEO with Nuxt 3.
Thanks for reading! If you have any feedback, please feel free to email us to info@thenextbit.de. We are happy to receive any feedback.
Related posts
:quality(80))
Simple steps for successful SEO with Nuxt 2
In this post I explain how to successfully implement SEO aspects like OGP, JSON-LD and good HTML structure technically in Nuxt.js.
:quality(80))
Advanced SEO-Workflow with Nuxt 2
Learn how to improve your Nuxt SEO-Workflow using Mixins and the "Don’t repeat yourself" principle.