SEO in Nuxt.js Website

Optimize Your Nuxt.js Website with These Essential 6 SEO Practices

June 17, 2021 Dykraf

A list of search engines optimizing your Nuxt.js website for better search results and indexing. On-site SEO with Nuxt.js modules and relevant JSON schemas.

Web Story VersionWeb Story

HTML 5 Structure

HTML Structures are very fundamental in search engine optimization build-up. HTML 5 semantic element markups such as <main><nav><section><article><header><footer> are very much recommended for use in any modern website. From the naming, the semantic element markups were very visible and easy to understand and identify what part was it for users and especially for search engines. Below is the sample for HTML 5 semantic element markups to begin my 6 SEO list to have on your Nuxt.js website:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Title of the Page</title>
    <meta name="description" content="Description of the page" />
  </head>
  <body>
    <header>
      <nav id="nav-header">
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Service</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <article>
        <section>
          <h1>Title of the content</h1>
          <div><p>Paragraph of the content</p></div>
        </section>
        <section>
          <h2>Other Title section of the content</h2>
          <div><p>Other paragraph of the content</p></div>
        </section>
      </article>
      <aside>
        <h3>Visit other links</h3>
        <nav>
          <ul>
            <li><a href="#">Link One</a></li>
            <li><a href="#">Link Two</a></li>
            <li><a href="#">Link Three</a></li>
          </ul>
        </nav>
      </aside>
    </main>
    <footer>
      <nav id="nav-footer">
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Service</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </footer>
  </body>
</html>

If there is any concern about HTML semantic browser compatibility, visit this link to get a better understanding. Explore and learn more on other semantic HTML visits this link.

Meta Tags

Put the related and relevant information on top of the HTML between the head tag. These will define your website information according to the content and the page that currently displayed to the visitor to see or crawled by the search engine bot.

<title>Nuxt.js with SEO | Home Page</title>
<meta name="robots" content="index, follow" />
<meta
  name="description"
  content="Nuxt.js with SEO | A List of SEO in Next.js"
/>
<meta property="og:title" content="Nuxt.js with SEO | Home Page" />
<meta
  property="og:description"
  content="Nuxt.js with SEO | A List of SEO in Next.js"
/>
<meta
  property="og:image"
  content="https://nextjs-sequelize.now.sh/nextjs.svg"
/>
<meta property="og:url" content="https://nextjs-sequelize.now.sh/post" />

JSON Schemas

Using structured data in webpage lead to rich results in search engines. Either use in direct HTML structure or JSON Schemas, the search engine will read your structure and displaying the search result in much richer content.

Put the JSON schemas between the head tags and display the relevant and informative content.

Article:

<head>
  <title>Website Title</title>
  <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "NewsArticle",
      "headline": "Article headline",
      "image": [
        "https://example.com/photos/1x1/photo.jpg",
        "https://example.com/photos/4x3/photo.jpg",
        "https://example.com/photos/16x9/photo.jpg"
      ],
      "datePublished": "2015-02-05T08:00:00+08:00",
      "dateModified": "2015-02-05T09:20:00+08:00"
    }
  </script>
</head>

Breadcrumb:

<head>
  <title>Website Title</title>
  <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Books",
          "item": "https://example.com/books"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Science Fiction",
          "item": "https://example.com/books/sciencefiction"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Award Winners"
        }
      ]
    }
  </script>
</head>

SEO Components and Nuxt.js meta tags default config

Develop a SEO component to handle HTML meta tags that will be used over and over in Nuxt.js pages components. Below is the sample of Meta tags on the open graph and Twitter open graph single components MetaHead.vue :

<template>
  <div v-if="false" />
</template>

<script>
/* default */
import { IMAGE } from '~/config/constants'

export default {
  props: {
    title: {
      type: String,
      required: true
    },
    description: {
      type: String,
      required: true
    },
    image: {
      type: String,
      default: IMAGE
    }
  },
  head() {
    return {
      meta: [
        {
          hid: 'twitter:title',
          name: 'twitter:title',
          content: this.title
        },
        {
          hid: 'twitter:description',
          name: 'twitter:description',
          content: this.description
        },
        {
          hid: 'twitter:image',
          name: 'twitter:image',
          content: this.image
        },
        {
          hid: 'twitter:image:alt',
          name: 'twitter:image:alt',
          content: this.title
        },
        {
          hid: 'og:title',
          property: 'og:title',
          content: this.title
        },
        {
          hid: 'og:description',
          property: 'og:description',
          content: this.description
        },
        {
          hid: 'og:image',
          property: 'og:image',
          content: this.image
        },
        {
          hid: 'og:image:secure_url',
          property: 'og:image:secure_url',
          content: this.image
        },
        {
          hid: 'og:image:alt',
          property: 'og:image:alt',
          content: this.title
        }
      ]
    }
  }
}
</script>

Include MetaHead.vue component in a Nuxt.js page:

<template>
  <MetaHead
    title="Page Title"
    description="Page Description"
    image="page_image.jpg"
  />
</template>

<script>
import MetaHead from './components/MetaHead'

export default {
  name: 'PageHome',
  components: { MetaHead }
}
</script>

Default Nuxt.js Config for SEO support with Meta Tags and JSON Schemas:

import CONSTANTS from './config/constants'

const { BASE_URL, NAME, TITLE, DESCRIPTION, IMAGE, SLOGAN, LOCALE, LANG } =
  CONSTANTS

export default {
  /*
   ** Headers of the page
   ** See https://nuxtjs.org/api/configuration-head
   */
  head: {
    htmlAttrs: {
      lang: LANG
    },
    title: TITLE || process.env.npm_package_name,
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { name: 'theme-color', content: '#000000' },
      {
        name: 'robots',
        content:
          'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1'
      },
      {
        hid: 'description',
        name: 'description',
        content: DESCRIPTION || process.env.npm_package_description
      },
      {
        hid: 'og:title',
        property: 'og:title',
        content: TITLE || process.env.npm_package_name
      },
      {
        hid: 'og:description',
        property: 'og:description',
        content: DESCRIPTION || process.env.npm_package_description
      },
      {
        hid: 'og:image',
        property: 'og:image',
        content: IMAGE
      },
      {
        hid: 'og:image:secure_url',
        property: 'og:image:secure_url',
        content: IMAGE
      },
      {
        hid: 'og:url',
        property: 'og:url',
        content: BASE_URL
      },
      {
        hid: 'og:type',
        property: 'og:type',
        content: 'website'
      },
      {
        hid: 'og:site_name',
        property: 'og:site_name',
        content: NAME
      },
      {
        hid: 'og:locale',
        property: 'og:locale',
        content: LOCALE
      },
      {
        hid: 'twitter:card',
        name: 'twitter:card',
        content: 'summary_large_image'
      },
      {
        hid: 'twitter:url',
        name: 'twitter:url',
        content: BASE_URL
      },
      {
        hid: 'twitter:title',
        name: 'twitter:title',
        content: TITLE
      },
      {
        hid: 'twitter:description',
        name: 'twitter:description',
        content: DESCRIPTION
      },
      {
        hid: 'twitter:image',
        name: 'twitter:image',
        content: IMAGE
      },
      {
        hid: 'twitter:site',
        name: 'twitter:site',
        content: `@${NAME}`
      }
    ],
    script: [
      {
        hid: 'organization',
        type: 'application/ld+json',
        json: {
          '@context': 'https://schema.org',
          '@type': 'Organization',
          name: TITLE,
          url: BASE_URL,
          logo: {
            '@type': 'ImageObject',
            '@id': `${BASE_URL}/#logo`,
            inLanguage: LOCALE,
            url: IMAGE,
            width: 512,
            height: 512,
            caption: TITLE
          },
          image: {
            '@id': `${IMAGE}#logo`
          },
          slogan: SLOGAN,
          description: DESCRIPTION
        }
      },
      {
        hid: 'website',
        type: 'application/ld+json',
        json: {
          '@context': 'https://schema.org',
          '@type': 'WebSite',
          name: TITLE,
          alternateName: BASE_URL.replace(/^.*:\/\//i, ''),
          url: BASE_URL,
          description: DESCRIPTION,
          publisher: {
            '@id': `${BASE_URL}/#website`
          },
          potentialAction: [
            {
              '@type': 'SearchAction',
              target: `${BASE_URL}/blog/{search_term_string}`,
              'query-input': 'required name=search_term_string'
            }
          ],
          inLanguage: LOCALE
        }
      }
    ]
  }
}

Here is the demo on an example of the uses of HTML Tags for SEO Meta in the Nuxt.js component complete with JSON Schemas. Here are the source code on GitHub.

Content Creation

SEO in a website needs content to be recognized by the search engines. Content is always the king and essential part of your website to serve, not just visitors to scan, but search engines too.

The website content will be read by the search engines based on the content, starting with all the meta tags down with all the HTML tags. HTML structures will form related informative content between the tags from top to bottom and displayed it on the browser along with the keywords and content of your pages.

Nuxt.js has a content module that provides you with MarkDown content files that can be translated into static HTML pages that will bring your Nuxt.js website content easier to maintain.

Link building in a website is essential for getting links to your website. You can build links in your content directing to other pages that are relevant to other content and you could build links on another website that is linking to your website contents.

Optimized Assets

Assets optimization will determine the website in presenting the content and rendering the web page. Minify the assets is one way of optimizing website asset files. This is crucial for website that wanted to have a good scores on Google Lighthouse tool.

Sitemap

The sitemap will be the anchor for search engines to look up your website page links. Nuxt.js provides official plugins to generate sitemaps for our website. Add the module @nuxt/sitemap to the package.json and add a config set up in nuxt.config.js file. The sitemap will be formed in the build stage or in generating stage.

Sitemap XML direct access on URL Sitemap XML direct access on URL ready to be submitted

AMP Framework

Adapting the AMP framework component will bring more traffic to your website. Made by Google focusing on optimized and intended for mobile devices for loading faster content to the web browser. Nuxt.js community module has support for AMP components. Add the module @nuxtjs/amp and set the config and develop the web pages.

There is an AMP Web Stories feature to support you with excellent feeds with animation and other media supports. This will impact your website to be on discover and featured on the Google search engine. Hey, even this website has a page with AMP Web Stories version.

AMP Story since it implemented AMP Story in Google Analytics

AMP Story submitted in Google Search Console AMP Story submitted in Google Search Console

AMP Story clicks and impressions in Google Search Console AMP Story clicks and impressions in Google Search Console

If you already implement AMP in your website and several other SEO on-page lists. You will have the lists of enhancements that you already implement and consider valid by the Google search engine console.

Enhanchement Analytic in Google Search Console Enhancement Analytic in Google Search Console

RSS, Atom, or JSON Feed

Feed-reader is one of the tools used in many applications that involved in aggregating information from many websites on the internet. Many websites add lists from their content in a specific format such as RSS, Atom os JSON for content feed consumption. Here is my writing on how to create Nuxt.js dynamic sitemap and feed for seo.

Direct URL access on RSS Feed Direct URL access on RSS Feed xml

Chrome feed reader UI in URL access on RSS Feed Chrome feed reader UI in URL access on RSS Feed

Closing

There are several ways to upload your Nuxtjs website, you could use any hosting service provider or use free static website hosting like Vercel and Netlify.

I have been using these hosting service provider for quite some time for publish several of my web projects. As a web developer, these hosting providers have been extremely helpful in terms of hosting my static websites.

All the modules from Nuxt community are very handy and helpful for your website SEO lists, so you do not have to write your own function that probably doing the same way you wanted. Just have to read and understand how the modules work and implement them on your project. Thank you for visiting and reading this blog, I really appreciate it, and helps you in one way or another.

Topics

Recent Blog List Content:

Archive