• Homeright=arrow
  • Blogright=arrow
  • Creating Dynamic Metadata with Next.js
featureImage

Creating Dynamic Metadata with Next.js

Metadata is data that provides information about other data. It describes the data's characteristics, context, quality, condition, or other descriptive aspects. On a webpage, these data are not directly shown to the users. Rather it can help search engines, browsers, and other technologies.

What is Dynamic Metadata

Dynamic metadata changes or updates automatically based on a certain page. Unlike static metadata, which remains constant, dynamic metadata can change for each page. For instance, if there are several blog pages, the metadata for each page will be unique.

How to create a dynamic Metadata

To create dynamic metadata in a Next.js application using the App Router, we can use Next.js's metadata API to generate metadata based on the page's content dynamically. This is particularly useful for setting dynamic <title>, <meta> tags, and other SEO-related tags that change depending on the page's content.

Here's how we can create dynamic metadata with Next.js App Router:

Step-by-Step Guide

  • Create a Page Component with Dynamic Metadata: Let's assume we have a Next.js project set up using the App Router (app directory structure). For more, read the article.
  • Define Metadata Function in Page Components: In Next.js App Router, each page component can export a generateMetadata function. This function can dynamically generate metadata based on the route parameters or other data. An example is given below:

// app/posts/[id]/page.js
import { getPostData } from '@/lib/posts';
// Example to fetch data statically or dynamically
export async function generateMetadata({ params, searchParams }, parent) {
const { id } = params;
const post = await getPostData(id);
return {
title: post.title,
description: post.excerpt,
};
}

export default function Post({ params }) {
const { id } = params;
const post = await getPostData(id); // Assume this function fetches post data
return (
<main>
<h1>{post.title}</h1>
<p>{post.content}</p>
</main>
);
}

In this example:

  • generateMetadata is an async function that receives the params object, which contains route parameters (like id for /posts/[id]).
  • It fetches the post data based on the id and returns an object with dynamic metadata.
  • The returned object from this  generateMetadata can include different metadata properties also:
  • title and description for basic SEO. For a title, aim for 50-60 characters. This length is optimal for search engines to display the entire title without truncation, ensuring the title is fully readable to users. For an effective meta description, aim for 50-160 characters. This length ensures that your description is concise yet detailed enough to provide a clear summary of the page's content, which helps improve SEO and click-through rates from search engine results.

Parameters

generateMetadata function accepts several props. props is an object containing the parameters of the current route:

  • params - It is an object that contains the dynamic route parameters object from the root segment down to the segment generateMetadata is called from.For example, if the route is app/shop/[slug]/page.js, then the URL will be /shop/1 and the params will be { slug: '1' }
  • searchParams - an object that holds the current URL's search parameters. For Example, if the URL is  /shop?a=1 and the searchParams will be { a: '1' }
  • parent - A promise of the resolved metadata from parent route segments.

Returns

generateMetadata should return a Metadata object containing one or more metadata. A list of Basic Metadata fields is given below:

export const metadata = {
generator: 'Next.js',
applicationName: 'Next.js',
referrer: 'origin-when-cross-origin',
keywords: ['Next.js', 'React', 'JavaScript'],
authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
creator: 'Jiachi Liu',
publisher: 'Sebastian Markbåge',
formatDetection: {
email: false,
address: false,
telephone: false,
},
}

What happens if both dynamic and Static Metadata are at the same time

We can also define static metadata at the layout level if the metadata doesn't need to be dynamic for every page. This is done by exporting a metadata object in a layout file:

// app/layout.js
export const metadata = {
title: 'My Blog',
description: 'Welcome to my blog where I share my thoughts and tutorials.',
};

export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}

Note: We can use both static and dynamic metadata together. The static metadata in layout.js provides a default for all pages, and the dynamic metadata in page.js overrides it for specific routes as needed.

When should we use generateMetadata

  • Use generateMetadata if the content on your page differs based on a dynamic route (e.g., a product or blog post).
  • Use generateMetadata to generate metadata conditionally depending on fetched data or route parameters. For example, you can use generateMetadata to create a robots tag if you wish to avoid particular pages (like preview pages) from being indexed.
  • Use generateMetadata if any of the data in your metadata has to be fetched from a database or API. Because this function is asynchronous, you can dynamically construct metadata by fetching data during build or request time.
  • generateMetadata should be avoided in favour of the static metadata object when defining metadata if it is not dependent on runtime data.

Conclusion

Using dynamic metadata in Next.js with the App Router is straightforward and helps improve our application's SEO and social sharing capabilities. By utilizing the generateMetadata function and the metadata object, we can dynamically set metadata based on the content or context of the page, ensuring our web pages are properly indexed and displayed in search engine results and social media.

If you still feel the need for help, feel free to contact us. The dedicated teams at StaticMania are ready to assist you 24/7. 

footer-particlefooter-particlefooter-particlefooter-particlefooter-particle
back-to-top