Metadata for Next.js project
What is Metadata in Next.js?
Metadata in Next.js refers to information about your web pages-such as titles, descriptions, Open Graph tags, and favicons that appears in the HTML <head>
section. This metadata is crucial for SEO (search engine optimisation), social sharing, and improving how your site appears in search results and link previews.
How to Use Metadata in Next.js
Next.js provides a Metadata API that lets you manage metadata at different levels of your application using either a static object or a dynamic function. This system works with the App Router and is only supported in Server Components.
1. Static Metadata
You can export a static metadata
object from any layout.js/ts
or page.js/ts
file:
1import type { Metadata } from 'next'
2
3export const metadata: Metadata = {
4 title: "My Website",
5 description: "A great website built with Next.js",
6}
7
8export default function Page() {}
This metadata will be injected into the <head>
for that route and all nested routes unless overridden.
2. Dynamic Metadata with generateMetadata
For pages where metadata depends on dynamic data (like a blog post title or product info), export a generateMetadata
function:
1import type { Metadata, ResolvingMetadata } from 'next'
2
3type Props = {
4 params: Promise<{ id: string }>
5 searchParams: Promise<{ [key: string]: string | string[] | undefined }>
6}
7
8export async function generateMetadata(
9 { params, searchParams }: Props,
10 parent: ResolvingMetadata
11): Promise<Metadata> {
12 // read route params
13 const id = (await params).id
14 // fetch data
15 const product = await fetch(`https://.../${id}`).then((res) => res.json())
16 // optionally access and extend (rather than replace) parent metadata
17 const previousImages = (await parent).openGraph?.images || []
18
19 return {
20 title: product.title,
21 openGraph: {
22 images: ['/some-specific-page-image.jpg', ...previousImages],
23 },
24 }
25}
26
27export default function Page({ params, searchParams }: Props) {}
- This function runs on the server before rendering, ensuring metadata is ready for SEO and bots.
- You cannot use client-side state or hooks to set metadata; it must be static or server-side dynamic.
- The
generateMetadata
function can dynamically generate metadata based on route parameters or other data. fetch
requests insidegenerateMetadata
are automatically memoized. Reactcache
can be used iffetch
is unavailable.
3. Metadata Inheritance and Overriding
- Global metadata is set in the root
layout.tsx
and applies to all pages. - Page or nested layout metadata can override or extend global metadata for specific routes.
1import type { Metadata } from 'next'
2
3// app/layout.tsx
4export const metadata: Metadata = { title: "Site", description: "Default" };
5
6// app/about/page.tsx
7export const metadata: Metadata = { title: "About - Site", description: "About us" };
4. Best Practices
- Use static metadata for pages with fixed content.
- Use
generateMetadata
for dynamic pages (e.g., blog posts, products). - Memoize data fetching if both your page and metadata need the same data, to avoid duplicate requests.
- Metadata can include advanced fields: Open Graph, Twitter cards, canonical URLs, alternate languages, and more.
5. Example: Dynamic Metadata for a Blog Post
1import type { Metadata } from 'next'
2import { getPost } from '@/app/lib/data';
3
4type Props = {
5 params: Promise<{ id: string }>
6 searchParams: Promise<{ [key: string]: string | string[] | undefined }>
7}
8
9export async function generateMetadata({ params, searchParams }: Props) {
10 const post = await getPost(params.slug);
11 return {
12 title: post.title,
13 description: post.description,
14 openGraph: {
15 images: [post.image],
16 },
17 };
18}
19
20export default async function Page({ params, searchParams }: Props) {
21 const post = await getPost(params.slug);
22 return <div>{post.title}</div>;
23}
24
Other points to consider for Next.js SEO:
- Meta Tags: Use meta tags to help search engines understand your site better. Use the Metadata API for meta tags with the App Router.
- Server-Side Rendering (SSR) and Static Site Generation (SSG): Improve SEO by delivering fully rendered HTML to search engines. Pre-rendering makes content more accessible and helps search engines understand it. Use SSG for content that doesn’t change often and SSR for pages updated more frequently.
- Open Graph Customisation: Customise Open Graph meta tags and titles to control how content appears when shared on social media.
- Website Optimisation: Optimise websites through code splitting and image optimisation. Faster loading and rendering contribute to a positive user experience and better SEO performance.
- Internationalisation and Localisation: Create localised versions of your site to attract a broader audience and cater to specific language and cultural preferences.
- JSON-LD: Integrate JSON-LD for structured data to provide search engines with richer information about your content.