Introduction
In Next.js 14, there are two primary ways to manage metadata for your application: using a static metadata
object or a dynamic generateMetadata
function. Below is a detailed guide on how to utilize both options effectively.
This guide provides an in-depth look at both approaches, helping you understand how to effectively implement metadata in your Next.js application.
Next.js Demo with Metadata Output
In this live example, we'll create a simple Next.js application showcasing the usage of metadata. Then, we'll view the rendered output in the browser and visualise the metadata in action.
We start by creating a new Next.js project with create-next-app
npx create-next-app@latest
Here's the options I chose while creating it.
Add this sample code in the following block and let's preview it in the browser.
Code:
Output:
And here's the browser output with get with the tags, keep reading the entire article to see how you could implement in your code.
Static Metadata
To define static metadata, you export a Metadata
object from a layout.ts
or page.ts
file using the App Router.
Example:
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Static Page Title',
description: 'This is a static page description',
}
export default function Page() {}
This method is suitable when the metadata does not depend on runtime information.
Dynamic Metadata
Dynamic metadata allows you to generate metadata based on dynamic data, such as route parameters or fetched data.
Example:
import { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
const id = params.id
const product = await fetch(`https://api.example.com/products/${id}`).then((res) => res.json())
const previousImages = (await parent).openGraph?.images || []
return {
title: product.name,
description: product.description,
openGraph: {
images: [product.imageUrl, ...previousImages],
},
}
}
export default function Page({ params, searchParams }: Props) {}
This method is useful when the metadata depends on dynamic data or needs to extend parent metadata.
Key Points
-
Server Components Only: Both
metadata
andgenerateMetadata
are only supported in Server Components. -
Single Export Rule: You cannot export both the
metadata
object andgenerateMetadata
function from the same route segment.
Metadata Fields
Next.js provides a variety of metadata fields to customize the metadata of your application comprehensively.
Title
- String
export const metadata: Metadata = {
title: 'Next.js Application',
}
Output: <title>Next.js Application</title>
- Template Object
export const metadata: Metadata = {
title: {
template: '%s | Next.js',
default: 'Next.js',
},
}
Output in child routes: <title>About | Next.js</title>
- Absolute
export const metadata: Metadata = {
title: {
absolute: 'About Us',
},
}
Output: <title>About Us</title>
Description
export const metadata: Metadata = {
description: 'The React Framework for the Web',
}
Output: <meta name="description" content="The React Framework for the Web" />
Basic Fields
export const metadata: Metadata = {
generator: 'Next.js',
applicationName: 'Next.js App',
keywords: ['Next.js', 'React', 'JavaScript'],
authors: [{ name: 'Author Name', url: 'https://example.com' }],
}
Output:
<meta name="generator" content="Next.js" />
<meta name="application-name" content="Next.js App" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="author" content="Author Name" />
<link rel="author" href="https://example.com" />
Open Graph
export const metadata: Metadata = {
openGraph: {
title: 'Next.js',
description: 'The React Framework for the Web',
url: 'https://nextjs.org',
siteName: 'Next.js',
images: [
{
url: 'https://nextjs.org/og.png',
width: 800,
height: 600,
},
],
locale: 'en_US',
type: 'website',
},
}
Output:
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
export const metadata: Metadata = {
twitter: {
card: 'summary_large_image',
title: 'Next.js',
description: 'The React Framework for the Web',
images: ['https://nextjs.org/og.png'],
},
}
Output:
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="The React Framework for the Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
Robots
export const metadata: Metadata = {
robots: {
index: false,
follow: true,
googleBot: {
index: true,
follow: false,
},
},
}
Output:
<meta name="robots" content="noindex, follow" />
<meta name="googlebot" content="index, nofollow" />
MetadataBase
metadataBase
allows setting a base URL prefix for metadata fields that require a fully qualified URL.
Example:
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
openGraph: {
images: '/og-image.png',
},
}
Output:
<meta property="og:image" content="https://example.com/og-image.png" />
Best Practices
- Use Static Metadata When Possible: If metadata doesn't depend on runtime information, prefer static metadata for simplicity.
Dynamic Metadata for Dynamic Data: Use
generateMetadata
for routes where metadata depends on dynamic data or needs to extend parent metadata.Combine Metadata Fields: Utilize a combination of different metadata fields to ensure comprehensive metadata coverage for SEO and social media integration.
Utilize
metadataBase
: Set ametadataBase
in your root layout to simplify URL-based metadata field definitions.
Conclusion
By following these guidelines, you can effectively manage metadata in your Next.js 14 application, enhancing both SEO and user experience.
Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!
Top comments (0)