Next.js

Generate metadata from the actual content contract

Kamruz
Kamruz
Oct 14, 2026
5 min read
Generate metadata from the actual content contract

An article page displays the correct title, but its description says undefined and its canonical URL contains an internal preview hostname. The metadata function reads summary, while stored articles use excerpt. An AI-generated example added author.name even though author is stored as an identifier. Type assertions silenced the compiler, so the build never exposed the contract mismatch.

This example assumes the Next.js 15 App Router and a project on 15.1.11. It uses generateMetadata, async route parameters, and ordinary metadata fields. Later Next.js 15 releases introduced additional metadata streaming behavior; do not assume those later details apply to every 15.1.11 deployment. Verify the installed version and actual response.

Inspect one stored public record

Choose a synthetic article containing title, slug, excerpt, body, publication date, and an optional image. Write down which fields are required, nullable, or absent. Compare that shape with the metadata function and page renderer. The useful question is not whether the fields sound plausible but whether the application really stores and returns them.

If an author is populated, inspect the public projection and missing-author behavior. A display name may be appropriate, while email and internal account flags are not. A metadata function should not trigger a broader database read than the page requires simply to satisfy a decorative template.

Remove unsafe casts such as treating an unknown database response as a complete article interface. Validate at the boundary or explicitly map the stored record to a public view. A smaller trustworthy type is more useful than a large aspirational type that every caller assumes is true.

Define canonical identity separately from request origin

The canonical URL identifies the public resource. For a site with one production domain, configure that public origin deliberately rather than deriving it from an arbitrary incoming host header. Preview deployments can render articles for review while canonical metadata still refers to the intended public site, if that matches the product's indexing policy.

Use a valid metadataBase or complete URLs according to the metadata contract. Normalize the path construction so a trailing slash or encoded slug does not accidentally produce two resource identities. If slugs are restricted at write time, document that restriction and reuse its validation.

Do not mark a private preview as publicly indexable merely because it has the same title as a published page. Canonical identity, robots policy, and authorization are separate decisions. A canonical tag is not an access-control mechanism and does not stop a visitor from reading leaked draft content.

Build metadata from the same public lookup

A shared published-only read keeps page and metadata decisions aligned. It can use request-scoped memoization where appropriate, but do not add persistent caching without deciding how edits invalidate it. Keep absence and dependency failure distinct.

import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { readPublicArticle } from '@/lib/public-articles'

export async function generateMetadata({ params }: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params
const article = await readPublicArticle(slug)
if (!article) notFound()
return {
title: article.title,
description: article.excerpt,
alternates: { canonical: `/blog/${article.slug}` }
}
}

This outline assumes a correctly configured metadata base in a parent layout and a validated public record. The repository is application code. If optional images are supported, add them only when a usable public URL exists; do not return an empty image object and hope the framework repairs it.

A parent title template can change the final title. Inspect that composition rather than assuming the returned title is the exact resulting document title. Decide whether the brand suffix helps readers and keep it consistent across article and index routes.

Handle optional content honestly

An excerpt should be a deliberate concise description, not a raw slice through serialized editor data. Slicing JSON can produce field names, escaped characters, or broken words. Generate or validate the excerpt at the content boundary and review it as editorial content. It should describe this article rather than repeat the site's generic slogan.

If an article lacks an image, omit the image-specific metadata or use a documented site fallback. If an author is unknown, omit unsupported attribution. If a publication date is absent in a legacy record, do not manufacture one from the current server clock. Filling every template field is less important than providing accurate fields.

Consider what happens when an article is renamed. The page, canonical URL, redirect, sitemap, and social preview should refer to the same new identity. Invalidate cached metadata along with content. A fixed visible title does not prove that a search or social client receives the updated description.

Verify the output rather than the return object

Request a public article from the built application and inspect the resulting title, description, canonical link, and any social tags. Compare them with the public record and the visible heading. Test an article with no image, a missing author, and punctuation that requires HTML escaping.

Check the canonical destination itself. It should resolve to the intended public resource without an unexpected preview hostname or chain of redirects. Test deployment configuration with a harmless synthetic hostname setting before publishing. Do not rely only on development because environment values can differ between build and runtime.

For a missing or unpublished article, verify the missing-resource and robots behavior. For a storage outage, verify the operational error path. A generic metadata fallback that masks every exception might keep the response attractive while hiding the same class of bug described in real 404 responses.

Use AI to challenge field assumptions

Give an assistant the schema, public mapper, parent layout metadata, and article metadata function. Ask it to list every referenced field and show where that field becomes available. Ask it to identify URL construction assumptions and optional-field behavior. These bounded tasks are more useful than asking it to improve SEO without a content contract.

Review its suggested tags for unsupported claims. Structured data can introduce fabricated authors, dates, or relationships when generated from a generic example. Keep each value tied to actual content. Technical metadata cannot guarantee ranking or substitute for useful writing, accessible pages, and accurate public discovery.

If the assistant suggests using a newer API, compare it with the installed Next.js version before editing. Documentation selected by an AI may describe a different release. Version-aware review prevents a simple metadata repair from becoming a framework migration.

Keep the contract maintainable

Add a small fixture-driven metadata check that verifies real values and omission of absent optional fields. The test should fail if the mapper changes from excerpt to another name without updating consumers. It should not merely assert that a mocked function returns the same mock.

Readable initial article HTML establishes the body contract, and current sitemaps establishes discovery. Metadata connects those public surfaces through a single accurate resource identity.

Sources

About the Author

Kamruz

Kamruz

Full Stack Developer

A passionate developer who loves creating modern web applications and sharing knowledge with the community.

More About Me

Related Articles