Generate Dynamic Metadata in Next.js: Metadata Object & generateMetadata Options

Generally, we use something like this to create metadata in Next.js:

export default function Home() {
    return (
      <div>
        <title>Home Page</title>
        <h1>Home Page</h1>
      </div>
    );
};

And it works very well, as we can see below:

Home Page with Metadata

But if you observe the source code, you can see one other that is by default defined by Next.js by root layout:

Source Code Title

The same goes for descriptions and other tags:

Source Code Description

Having duplicate metadata tags affects SEO ranking and is not an efficient way to define metadata in Next.js. So how can we define it? Using the Metadata object and nice generateMetadata function. Let’s see how.

Next.js Metadata Object

We can import the Metadata object from ‘next’ and generate static metadata for each page just like the root layout does for all the pages.

Root Layout

Using the Metadata object does not create duplicate tags which happens when metadata is manually added to each page file. It modifies the metadata that is generated by layout.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Home Page',
  description: 'This is the home page'
}

export default function Home() {
    return (
      <div>
        <h1>Home Page</h1>
      </div>
    );
};
Source Code With Metadata Object

But still, we have to define it on each page or layout file. Let’s see how to create dynamic metadata.

Next.js generateMetadata Function

Metadata like page title, description, keywords, etc. are important for SEO, so it is important to create them differently for different pages depending on the content of that page.

This is mainly useful for applications having pages with dynamic content, like blog websites where custom metadata is necessary to rank content. Here comes the generateMetadata function to help us dynamically generate metadata for each page.

By dynamically generating metadata based on the content, we can avoid redundancy and make SEO performance better.

Syntax:

export function generateMetadata({ params }: { params: { key: string } }): Metadata {
  return {
    title: `${params.key} Page`,
    // ...
  };
}

Creating Dynamic Metadata with generateMetadata

Let’s try to dynamically generate metadata using Dynamic Segment. For this create a new folder inside the app directory and wrap the folder name in square brackets, also create a page.tsx file inside it:

New Folder

This is the code for catching the params and rendering it as h1:

export default function Home({ params }: { params: { slug: string } }) {
  return (
    <div>
      <h1>{params.slug} Page</h1>
    </div>
  );
};
Home Page

In the output, we can see that the requested route is ‘/Home’ which doesn’t exist on our application, so it gets caught by [slug]/page.tsx and inserted into the h1 and rendered. Also, the title is default which is generated by root layout as we have removed the metadata object

Now let’s look at the updated code that uses generateMetadata that takes the segment and inserts it into the title and description:

import { Metadata } from "next";

export default function Home({ params }: { params: { slug: string } }) {
  return (
    <div>
      <h1>{params.slug} Page</h1>
    </div>
  );
};
  
export function generateMetadata({ params }: { params: { slug: string } }): Metadata {
  return {
    title: `${params.slug} Page`, 
    description: `This is the ${params.slug} page`,
  };
}

Now let’s hit different URLs and see if the title and description automatically change based on that or not:

Source Code With generateMetadata 1
Source Code With generateMetadata 2

And so on.

*What’s Next?

In our next tutorial, we will give you the best 8 optimization techniques to improve Next.js performance, don’t miss it!

Summary

In short, in Next.js if you try to use metadata tags directly in HTML it will generate error or duplicate meta tags. We have two ways to avoid this: first using the Metadata object and second by using the generateMetadata function.

We can use the Metadata object when we need to generate static metadata that does not require changes. If we want to generate dynamic metadata, we can use the generateMetadata function and generate metadata based on params, content, title, etc. We can also use this function in the layout component to generate metadata based on props for efficiently managing metadata for all pages in large applications.

Reference

https://nextjs.org/docs/app/api-reference/functions/generate-metadata

Aditya Gupta
Aditya Gupta
Articles: 144