Key takeaways

  • Use static metadata for static pages and generateMetadata for record-specific pages.
  • Set metadataBase before relying on relative canonical or social-image URLs.
  • Give every indexable page a truthful title, description, canonical, and share preview.
  • Verify the rendered HTML and crawler-visible response after deployment.

Metadata helps browsers, search engines, and sharing services understand a page before a person opens it. In the Next.js App Router, static pages can export a metadata object, while dynamic pages can export generateMetadata. Next.js resolves these values through the route tree and creates the corresponding document tags.

The Next.js Metadata Generator can produce a focused starting object. The important work is editorial and architectural: each page needs accurate text, canonical URL ownership, an image strategy, and verification against the deployed origin.

Choose static or generated metadata

Use a static metadata export when the values are known with the source: an About page, legal page, or stable landing page. Use generateMetadata when title and description depend on a route parameter or fetched record, such as a product, article, or profile.

Metadata exports are supported in Server Components. A route segment cannot export both the metadata object and generateMetadata. Keep client interaction in child components rather than making the page a Client Component merely to assemble head tags.

For dynamic content, share the record-loading function between generateMetadata and the page so both use the same canonical data and absence behavior. Next.js can memoize compatible fetches, and React cache can help for non-fetch loaders. Avoid two unrelated queries that can disagree about title, permissions, or existence.

Establish an absolute origin

Canonical URLs and social images ultimately need absolute URLs. Set metadataBase at the root to a trusted production origin, then use route-relative values where supported. Do not build canonical URLs from an unchecked forwarded Host header; proxies and malicious requests can supply unexpected values.

Preview deployments require a policy. A production canonical on a preview can prevent accidental indexing of the preview origin, but a private preview may instead be noindex. Make the environment behavior explicit rather than allowing localhost, staging, or internal hostnames into production tags.

Custom domains should become the canonical origin after they are verified and stable. Redirect alternate hosts to the canonical host, use one protocol, and normalize trailing slash behavior consistently.

A page-level example

import type { Metadata } from "next";

export async function generateMetadata({ params }): Promise<Metadata> {
  const { slug } = await params;
  const article = await getArticle(slug);

  if (!article) return {};

  return {
    title: article.title,
    description: article.summary,
    alternates: { canonical: "/blog/" + article.slug },
    openGraph: {
      type: "article",
      title: article.title,
      description: article.summary,
      url: "/blog/" + article.slug,
      images: [{ url: article.image, alt: article.imageAlt }],
    },
  };
}

The loader must validate slug and publication state. If the article does not exist, the page should also return a not-found result rather than rendering a generic title over an error screen. The social image needs a stable absolute URL after metadataBase resolution and descriptive alt text.

A practical metadata workflow

  1. Define the canonical origin. Configure metadataBase from a trusted environment value or fixed production URL.
  2. Write the visible page first. Metadata should accurately summarize the actual content, not a keyword list created separately.
  3. Create a title pattern. Keep the distinctive page subject early and apply the site name consistently through a root title template where appropriate.
  4. Write a useful description. Summarize the page’s value and scope in natural language. Avoid duplicate descriptions across hundreds of records.
  5. Assign canonical ownership. Parameter variations, filters, aliases, and pagination need an explicit indexing strategy.
  6. Create share images. Use a site-wide image for the home or broad pages and item-specific images for independently shareable records when available.
  7. Set robots deliberately. Index useful public content. Noindex private, duplicate, thin, or temporary surfaces as the product requires; do not rely on robots.txt to protect secrets.
  8. Verify output. Inspect the deployed HTML and test with sharing debuggers or crawler tools that reflect the services you support.

Titles and descriptions

A title should identify the page without requiring the rest of the site context. Put the specific product, article, or task before a repeated brand suffix. Avoid a single global title copied onto every route and avoid stuffing variations of the same keyword.

Descriptions do not guarantee a particular search snippet, but they provide useful candidate text and improve share previews. State what the reader can accomplish and any important limitation. Record descriptions should come from editorial data rather than slicing the first 160 characters of rich content, which can produce broken sentences or navigation text.

When a page has no distinct value—an empty search result, internal filter combination, or duplicate sort order—improving the title alone does not make it index-worthy. Fix the content and canonical strategy first.

Open Graph and social previews

Open Graph fields commonly include title, description, URL, site name, type, and images. Article records can add published time and authors. X/Twitter metadata may use similar values but should be checked separately because platforms evolve and cache aggressively.

Images need predictable dimensions, file size, format, and public availability. A generated image endpoint should use stable fonts and assets, handle long titles, and avoid leaking private data. Item-specific pages should not all inherit a generic image if a record image is part of the content users expect to share.

After changing a preview, remember that social platforms may retain cached tags. Use their supported refresh/debug flow. Always test the direct image URL without an authenticated session.

Merging and inheritance

Next.js evaluates metadata from root layout toward the final page. Nested objects such as openGraph are shallowly replaced when a later segment defines that field; they are not automatically deep-merged. A child that supplies only openGraph.title can unintentionally drop a parent description or image.

Share reusable nested fragments explicitly, or provide complete fields at the page level. Check at least two representative dynamic records so item-specific values are not accidentally inherited from the root.

File-based metadata such as icons, sitemap, robots, and Open Graph image files has its own precedence. Keep ownership clear so a file convention does not silently override a config value you expected to win.

Common mistakes

  • Using relative social-image URLs without metadataBase.
  • Reading the public origin from an untrusted request header.
  • Giving every page the home-page canonical.
  • Copying one description across all records.
  • Defining a partial child openGraph object and losing inherited fields.
  • Publishing a social image that requires authentication or blocks crawlers.
  • Returning indexable metadata for missing, private, or draft records.
  • Checking React source but never inspecting deployed output.

Deployment checklist

  • Root metadataBase is the intended canonical HTTPS origin.
  • Every indexable route has one H1, a specific title, and a truthful description.
  • Canonicals resolve to the preferred public URL.
  • Dynamic metadata and page content use the same record.
  • Missing and unauthorized records do not leak metadata.
  • Open Graph and X fields contain complete absolute image URLs.
  • Images are publicly fetchable and readable at share-card sizes.
  • robots, sitemap, redirects, and canonical tags agree.
  • At least two dynamic records and one not-found case are verified after deployment.

Frequently asked questions

Should generateMetadata fetch data separately from the page?

Prefer a shared loader or memoized fetch so title and rendered content come from the same record and authorization rules. Duplicate independent fetching increases latency and can create inconsistent output.

Do I need keywords metadata?

Focus on useful content, title, description, canonical ownership, and structured information appropriate to the page. A long keyword list is not a substitute for those fundamentals.

Can metadata protect a private page?

No. noindex and robots directives are crawler instructions, not authorization. Enforce access on the server and avoid emitting private record details in metadata for unauthorized requests.

Why is an old social image still showing?

Sharing services cache page metadata and images. Confirm the deployed HTML and direct image URL first, then use the platform’s refresh/debug tool or publish a versioned image URL when appropriate.

Further reading

Metadata quality follows page quality. When the visible page has one clear purpose and one canonical owner, the title, description, and preview become straightforward, accurate summaries rather than an SEO patch.

Try the related tool

Apply the guide to a focused example, then verify the result in your own project.

Open the related tool →