Note: Built-in support for SEO through metadata, introduced in
13.2
, replaces the previoushead.js
implementation. Thehead.js
special file was deprecated in13.2
and will be removed in a future version. View migration guide.
Next.js allows you to define metadata (e.g. meta
and link
tags inside your HTML head
element) with an explicit metadata configuration in any layout or page.
Both static and dynamic metadata through generateMetadata
are only supported in Server Components.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Home',
description: 'Welcome to Next.js',
};
export default function Page() {
return '...'
}
You can use generateMetadata
to fetch
metadata that requires dynamic values.
import type { Metadata } from 'next'
// The `fetch` response is cached and reused between both functions
// below, resulting in a single API request. If you cannot use `fetch`
// directly, you can use `cache`. Learn more:
// https://beta.nextjs.org/docs/data-fetching/caching
async function getProduct(id) {
const res = await fetch(`https://.../api/products/${id}`);
return res.json();
}
export async function generateMetadata({ params }): Promise<Metadata> {
const product = await getProduct(params.id);
return { title: product.title }
}
export default async function Page({ params }) {
const product = await getProduct(params.id);
// ...
}
Good to know:
generateStaticParams
, generateMetadata
, Layouts, Pages, and Server Components.generateMetadata
to complete before streaming UI to the client. This guarantees the first part of a streamed response includes <head>
tags.JSON-LD is a format for structured data that can be used by search engines to understand your content. For example, you can use it to describe a person, an event, an organization, a movie, a book, a recipe, and many other types of entities.
Our current recommendation for JSON-LD is to render structured data as a <script>
tag in your layout.js
or page.js
components. For example:
export default async function Page({ params }) {
const product = await getProduct(params.id);
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
};
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
);
}
You can validate and test your structured data with the Rich Results Test for Google or the generic Schema Markup Validator.
You can type your JSON-LD with TypeScript using community packages like schema-dts
:
import { Product, WithContext } from 'schema-dts';
const jsonLd: WithContext<Product> = {
'@context': 'https://schema.org',
'@type': 'Product',
name: 'Next.js Sticker',
image: 'https://nextjs.org/imgs/sticker.png',
description: 'Dynamic at the speed of static.',
};