Manage SEO in Next.js with Next SEO
Tags: nextjs, webdev
Published: 2023-01-12 15:27:01

**Written by [Nilanth Sriram](https://blog.logrocket.com/author/nilanthsriram/)✏️**

[SEO](https://blog.logrocket.com/how-next-js-can-help-improve-seo/) is a critical aspect of marketing that helps websites rank more effectively in search engine results pages (SERPs). A higher rank in the SERPs increases organic traffic and leads to greater business opportunities, so you can see why it's vital to keep it in mind! 

Because of this, it’s crucial for us as developers to ensure our projects’ website SEO is managed correctly without missing any properties. 

In this article, we will be using Next SEO to manage search engine optimization in our Next.js applications.

*   [Next SEO and Next.js](#next-seo-and-nextjs)
*   [Quick setup](#quick-setup)
*   [Adding Next Seo to a page](#adding-next-seo-to-a-page)
*   [Default SEO](#default-seo)
    *   [Override default properties](#override-default-properties)
*   [Open Graph support](#open-graph-support)
*   [Audio example](#audio-example)
*   [Structured data support](#structured-data-support)
*   [Next SEO options](#next-seo-options)
*   [Next.js 13 app directory support](#next-js-13-app-directory-support)
*   [Common meta tags](#common-meta-tags)
    *   [Default meta config](#default-meta-config)
    *   [Override the default SEO](#override-the-default-seo)
*   [Adding JSON-LD components](#adding-json-ld-components)

## Next SEO and Next.js

[Next.js](https://blog.logrocket.com/tag/nextjs/) has static site generation (SSG) support, which delivers better SEO capability than client-side rendering. It also has an in-built head component to manage SEO meta information like title, description, canonical, and Open Graph tags. 

When there are more pages on a website, there are also more meta tags to account for. As a site grows, managing these can become a daunting process. 

To simplify this, we can use a package called [next-seo](https://github.com/garmeeh/next-seo). Next SEO makes managing SEO easier in your Next.js projects. 

By using Next SEO, we can pass SEO properties as an object and the package automatically adds the properties to the page head. 

You can add this to every page individually or use the `DefaultSeo` component and overwrite it onto other pages. 

Let's get started and see it in action.

## Quick setup

First, install the next-seo package in your Next.js project using the following command: `yarn add next-seo`

## Adding Next SEO to a page

Let’s import the next-seo package into the `page` component with SEO properties. To do this, add the following code to the `home` component:

```javascript
//home.js

import { NextSeo } from 'next-seo';

const Home = () => (
    <>
        <NextSeo
            title="Home Page Title"
            description="Home page description of the page"
        />
        <p>Simple Usage</p>
    </>
);

export default Home;
```

This will render a `<head>` tag with a title and description for your page. You can verify it by inspecting it, as shown here: ![Inspecting Head Tag](https://blog.logrocket.com/wp-content/uploads/2023/01/inspecting-head-tag.png) You can see that the tag includes `og:title` and `og:description` by default, using the title and description properties. 

This is a simple configuration; let's explore the other options available to us in Next SEO.

## Default SEO

To add default properties to all of our pages, we can use the `DefaultSeo` component, instead of manually adding the properties individually to each page. We can also override any property on a page, if needed. 

Add the `DefaultSeo` component to `_app.js` and add the following code:

```javascript
//_app.js

import '../styles/globals.css'
import {DefaultSeo} from 'next-seo';

function MyApp({Component, pageProps}) {
    return (
        <>
            <DefaultSeo
                title="Next SEO Example"
                description="Next SEO is a plug in that makes managing your SEO easier in Next.js projects."
                openGraph={{
                    type: 'website',
                    locale: 'en_IE',
                    url: 'https://www.url.ie/',
                    siteName: 'SiteName',
                }}
                twitter={{
                    handle: '@handle',
                    site: '@site',
                    cardType: 'summary_large_image',
                }}
            />
            <Component {...pageProps} />
        </>
    )
}

export default MyApp
```

Now, the SEO properties added to the default component will be rendered on all pages. You can verify this by once again inspecting the page, as shown here: ![Verify Seo Properties Default Component](https://blog.logrocket.com/wp-content/uploads/2023/01/verify-seo-properties-default-component.png)

### Override default properties

Now, let's override the default SEO properties on our **Blog** page, as each blog will have an individual title and description. Add the following code to the page:

```javascript
//blog.js

import {NextSeo} from 'next-seo';

const Blog = () => (
    <>
        <NextSeo
            title="Manage SEO in NextJS with Next SEO"
            description="Next SEO packages simplifies the SEO management in Next Apps with less configurations"
            canonical="www.example.com/next-seo-blog"
            openGraph={{
                type: 'article',
                article: {
                    publishedTime: '2022-06-21T23:04:13Z',
                    modifiedTime: '2022-01-21T18:04:43Z',
                    authors: [
                        'https://www.example.com/authors/@firstnameA-lastnameA',
                        'https://www.example.com/authors/@firstnameB-lastnameB',
                    ],
                    tags: ['Tag A', 'Tag B', 'Tag C'],
                },
                url: 'www.example.com/next-seo-blog',
                images: {
                    url: 'https://www.test.ie/images/cover.jpg',
                    width: 850,
                    height: 650,
                    alt: 'Photo of text',
                },
                site_name: 'Next Blog'
            }}
        />
        <p>Manage SEO in NextJS with Next SEO - Blog</p>
    </>
);

export default Blog;
```

Here, we have overridden the `title`, `description`, and other properties. You can also see a few new properties specifically related to our blog posts:

*   `publishedTime`: Blog published date
*   `modifiedTime`: Blog updated date
*   `tags`: Tags associated with the blog post
*   `authors` : Author of the blog

You can verify these by inspecting the page: ![Verify Default Properties Override](https://blog.logrocket.com/wp-content/uploads/2023/01/verify-default-properties-override.png) As you can see, there is some meta info related to Twitter cards, but we didn’t include those in the blog page — it was added by Next SEO, which we added earlier using the `DefaultSeo` Component. You can see with this example how it supports blog-related SEO properties out of the box for ease of use.

## Open Graph support

The Open Graph protocol controls what content should be displayed when sharing links on social media. Using Open Graph tags in web pages enables them to become rich objects in a social graph. 

For instance, the OG protocol allows you to control what title, image, and description are displayed when sharing links on social media platforms. If you share without OG tags, social media platforms will choose a random title, image, and description. 

Platforms like Twitter, LinkedIn, and Facebook recognize Open Graph tags — however, Twitter also has meta tags called Twitter Cards, but will use OG tags when there is no need to use Twitter Card tags. 

Next SEO supports the following OG properties:

1.  Audio
2.  Video
3.  Article
4.  Profile
5.  Book

## Audio example

The following configuration enables audio Open Graph support with multiple audio files:

```javascript
//Podcast.js

import { NextSeo } from 'next-seo';
const Podcast = () => (
  <>
    <NextSeo
      title="Podcast Page Title"
      description="Next SEO PodCast"
      openGraph={{
        title: 'Open Graph Audio',
        description: 'Description of open graph audio',
        url: 'https://www.example.com/audio/audio',
        audio: [
          {
            url: 'http://examples.opengraphprotocol.us/media/audio/1khz.mp3',
            secureUrl: 'https://d72cgtgi6hvvl.cloudfront.net/media/audio/1khz.mp3',
            type: "audio/mpeg"
          },
          {
            url: 'http://examples.opengraphprotocol.us/media/audio/250hz.mp3',
            secureUrl: 'https://d72cgtgi6hvvl.cloudfront.net/media/audio/250hz.mp3',
            type: "audio/mpeg"
          },
        ]
        site_name: 'SiteName',
      }}
    />
    <h1>Audio Page SEO</h1>
  </>
);
export default Podcast;
```

You can take a look at other [examples](https://github.com/garmeeh/next-seo#open-graph-examples) for other OG types to learn more.

## Structured data support

Structured data is a standardized format for providing information about a page and classifying the page’s content. This helps search engines understand the web page and display the most relevant titles, descriptions, images, and other information to end users. 

Next SEO also supports structured data with limited configuration necessary, supporting multiple JSON-LD types like `article`, `blog`, `FAQ`, and `course`. 

Let’s see this in action with an example. 

The `ArticleJsonLd` component is used to add structured data to a page. Add the following code to add structured data to our blogs:

```javascript
//blog.js

import {ArticleJsonLd, NextSeo} from 'next-seo';

const Blog = () => (
    <>
        <NextSeo
            title="Manage SEO in NextJS with Next SEO"
            description="Next SEO packages simplifies the SEO management in Next Apps with less configurations"
            canonical="www.example.com/next-seo-blog"
            openGraph={{
                type: 'article',
                article: {
                    publishedTime: '2022-06-21T23:04:13Z',
                    modifiedTime: '2022-01-21T18:04:43Z',
                    authors: [
                        'https://www.example.com/authors/@firstnameA-lastnameA',
                        'https://www.example.com/authors/@firstnameB-lastnameB',
                    ],
                    tags: ['Tag A', 'Tag B', 'Tag C'],
                },
                url: 'www.example.com/next-seo-blog',
                images: {
                    url: 'https://www.test.ie/images/cover.jpg',
                    width: 850,
                    height: 650,
                    alt: 'Photo of text',
                },
                site_name: 'Next Blog'
            }}
        />
        <ArticleJsonLd
            type="BlogPosting"
            url="https://example.com/blog"
            title="Manage SEO in NextJS with Next SEO"
            images={[
                'https://example.com/photos/1x1/photo.jpg',
                'https://example.com/photos/4x3/photo.jpg',
                'https://example.com/photos/16x9/photo.jpg',
            ]}
            datePublished="2022-06-21T23:04:13Z"
            dateModified="2022-06-21T23:04:13Z"
            authorName="Author Name"
            description="Next SEO packages simplifies the SEO management in Next Apps with less configurations"
        />
        <p>Manage SEO in NextJS with Next SEO - Blog</p>
    </>
);

export default Blog;
```

We have now added a few SEO properties to the `JsonLd`, which will be rendered like so: ![Add Seo Properties To Json](https://blog.logrocket.com/wp-content/uploads/2023/01/add-seo-properties-to-json.png) The JSON data is rendered in the `<script>` tag. You can check all the available [JSON-LD types](https://github.com/garmeeh/next-seo#json-ld) for more information on this.

## Next SEO options

The following are the properties for the `NextSeo` component, which we can use to handle different meta tag properties. Some of the most used properties are:

*   `defaultTitle`: If no title is set on a page, this string will be used instead of an empty title
*   `noindex`: Option to set whether the page should be indexed or not
*   `nofollow`: Option to set whether the page should be followed or not
*   `canonical`: Set the page’s canonical URL
*   `facebook`.`appId`: Add Facebook app ID to your page to receive Facebook Insights data
*   `additionalMetaTags`: Additional meta tags like `title` and `content`
*   `additionalLinkTags`: Additional meta links like favicons

## Next.js 13 app directory support <a name="next-js-13-app-directory-support">

Next.js 13 introduced a beta feature to the `app` directory for routing alongside the `pages` directory. 

Due to this change, the usage and configuration of next-seo also changes, as the new `app` directory brings the following changes to the existing flow:

1.  Next.js no longer removes the duplicate tags in the head, so we can’t use the `DefaultSeo` component for global SEO
2.  The `app` directory includes the `head.js` file to include `<head>` tags, but it doesn’t support synchronous inline script. As a result, JSON-LD components can’t be added in `head.js`, so it needs to be added in `page.js`, which adds to the `<body/>` of the document
3.  Next.js doesn’t add below meta tags by default, so we need to add this manually in the root layout

## Common meta tags

As per the new `app` directory, `DefaultSeo` meta tags can’t be overwritten on other pages. 

Because of this, we need to identify common tags and place them in the root layout (`/app/layout.js`), as demonstrated here:

```javascript
// app/layout.js
import { NextSeo } from 'next-seo';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {/* Used to be added by default, now we need to add manually */}
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width" />
        {/* 
          Anything we add in layout will appear on EVERY PAGE. At present it can not be overridden lower down the tree.
          This can be useful for things like favicons, or other meta tags that are the same on every page.
        */}
        <NextSeo
          useAppDir={true}
          facebook={{ appId: '1234567890' }}
          themeColor="#73fa97"
          titleTemplate="%s | Next SEO"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}
```

> **N.B.,** the new prop `useAppDir` forces next-seo to use the `app` directory that is a compatible version.

The following are the rendered meta tags from the above example: ![Rendered Meta Tags](https://blog.logrocket.com/wp-content/uploads/2023/01/rendered-meta-tags.png)

### Default meta config

To use common meta tags like `og`, `image`, `title`, and `description`, start by adding the `next-seo-config.js` file with common meta tags and importing it into the required pages. Here’s an example of what I mean:

```javascript
// next-seo-config.js
export const NEXT_SEO_DEFAULT = {
  title: 'Page Title',
  description: 'Page Description',
  openGraph: {
    type: 'website',
    locale: 'en_IE',
    url: 'https://www.url.ie/a',
    title: 'OG Title',
    description: 'OG Decription',
    siteName: 'Example',
  },
};
```
Now, import the `next-seo-config.js` file into `head.js`, as shown here:

```javascript
// app/head.js
import { NextSeo } from 'next-seo';

import { NEXT_SEO_DEFAULT } from './next-seo-config'; // your path will vary

export default async function Head() {
  return <NextSeo {...NEXT_SEO_DEFAULT} useAppDir={true} />;
}
```

Here’s our output for the above example: ![Output Of Example Properties](https://blog.logrocket.com/wp-content/uploads/2023/01/output-of-example-properties.png)

### Override the default SEO

You can override the default `next-seo-config` meta tags on other pages if necessary — take a look at the following example to see how it’s done:

```javascript
 // app/profile/head.js
import { NextSeo } from 'next-seo';

import { NEXT_SEO_DEFAULT } from '../next-seo-config'; // your path may vary

export default async function Head() {
  const updateMeta = {
    ...NEXT_SEO_DEFAULT,
    title: 'Profile',
    description: 'User Profile',
  };
  return <NextSeo {...updateMeta} useAppDir={true} />;
}
```

Here, we are updating the title and description of the default SEO meta tags to our own specifications. 

Here’s the output for the above example: ![Output Default Seo Updated Title And Description](https://blog.logrocket.com/wp-content/uploads/2023/01/output-default-seo-updated-title-and-description.png)

## Adding JSON-LD components <a name="adding-json-ld-components">

As we saw earlier, the new `app` directory `head.js` does not support an inline `<script>`. We can add the JSON-LD to `page.js` file, which adds the JSON-LD structured data into the document body. 

Check out the following example:

```javascript
// app/blog/page.js
import { ArticleJsonLd } from 'next-seo';

const Article = () => (
  <>
    <h1>Article</h1>
    <p>Inspect page for output.</p>
    <ArticleJsonLd
      useAppDir={true}
      type="BlogPosting"
      url="https://example.com/blog"
      title="Blog headline"
      images={[
        '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:00:00+08:00"
      authorName="Jane Blogs"
      description="This is a mighty good description of this blog."
    />
  </>
);

export default Article;
```

Here’s the output for the above example: ![Final Output For Default Seo Export](https://blog.logrocket.com/wp-content/uploads/2023/01/final-output-for-default-seo-export.png)

## Conclusion

SEO is essential for web pages that need to be discovered organically. To have high page rankings, sites need to be organized so that they can be easily crawled by search engines. 

Next SEO makes the management of search engine optimization in Next.js projects very simple and is easy to implement — it helps devs add SEO properties efficiently without missing any important meta tags, while avoiding the occurrence of duplicates. 

You can find other properties and examples in the official [docs](https://github.com/garmeeh/next-seo). 

Let me know of your own experiences using Next SEO in the comments below and thanks for reading!

---

## [LogRocket](https://logrocket.com/signup): Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try [LogRocket](https://logrocket.com/signup). 

[![LogRocket signup](https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)](https://logrocket.com/signup)

[LogRocket](https://logrocket.com/signup) is like a DVR for web and mobile apps, recording literally everything that happens on your Next app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — [start monitoring for free](https://logrocket.com/signup).