Dynamic Metadata

Fetching database records to populate SEO tags.

Next.js4 min readConcept 55 of 66

The generateMetadata Function

For dynamic routes like /product/[id], exporting a static metadata object doesn't work because you don't know which product the user is requesting yet.

Instead, you export an async generateMetadata function. Next.js will pass the URL params into this function, allowing you to fetch the specific database record and return a dynamic metadata object.

Dynamic Social Previews

When someone pastes a link to a specific product on Twitter or iMessage, the crawler bots don't execute JavaScript. They only read the raw HTML <head>.

If you try to set the document title dynamically using React Client Components (like useEffect), the crawler bots will only see a blank title.

generateMetadata ensures the exact product name is injected into the HTML <head> on the server before it is sent to the bot.

Implementation

tsx

export async function generateMetadata({ params }) {

const product = await fetchProduct(params.id);

return { title: ${product.name} | Acme Store };

}

Dynamic Head Injection

Interact with the product list to see how Next.js executes generateMetadata on the server, halts the render to fetch data, and constructs the HTML head dynamically.

Request:
Client
Next.js ServergenerateMetadata()
Database
Blocking TTFB
export async function generateMetadata({ params }) {
// Slow DB query blocks render!
const product = await db.query(params.id);
return {
title: `${product.name} | Store`,
};
}

Compiled HTML <head>

<html>
<head>
// Generated from await db.query()
<title>Nike Air Max | Store</title>
<meta name="description" content="Classic athletic footwear."/>
</head>
<body>
<h1>Nike Air Max</h1>
...
</body>
</html>

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1What is the primary performance risk of using `generateMetadata` with a slow database query?

Remember this

  • Export async function generateMetadata() for dynamic SEO tags.
  • It receives the URL params just like a page component.
  • generateMetadata blocks the page render until it finishes.
  • React automatically deduplicates fetch requests, so you can safely fetch the same product in generateMetadata and page.tsx.

Done with this concept?

Mark it complete to track your progress. No login needed.