Pre-render dynamic routes at build time and generate SEO-optimized metadata. How I use generateStaticParams with Sanity CMS and generateMetadata for canonical URLs and social cards.
generateStaticParams
You pre-render all blog posts and project pages at build time by fetching slugs from your GraphQL API.
This gives you:
Instant page loads (static HTML)
CDN-friendly caching
SEO benefits because crawlers see full content.
You handle post-build content with:
On-demand ISR via a /api/revalidate route and revalidateTag.
dynamicParams to control whether unknown slugs are rendered on-demand or 404.
generateMetadata
You generate dynamic SEO metadata per page (blog posts and projects) using the same data source as the page itself.
You:
Handle missing content with fallback titles (e.g., Project Not Found).
Build canonical URLs using NEXT_PUBLIC_SITE_URL.
Configure rich metadata:
title, description
alternates.canonical
openGraph (title, description, URL, siteName, type, images)
twitter cards (summarylargeimage, title, description, images)
Static metadata for non-dynamic pages
For pages like /projects, you export a static metadata object instead of generateMetadata.
Data fetching pattern
generateStaticParams, generateMetadata, and the page component all call the same data functions (getProject, getKnowledgeNode).
Next.js automatically deduplicates these fetches, so only one actual request is made per unique call.
Lifecycle summary
| Function | Purpose | When It Runs |
|-------------------------|-----------------------------|-----------------------------------|
| generateStaticParams | List all dynamic routes | Build time |
| generateMetadata | Generate page metadata | Build time + request time (as needed) |
| dynamicParams | Allow/block unlisted routes | Request time |
Your setup combines:
Static generation for speed and caching
Dynamic metadata for strong SEO and social previews
ISR + dynamicParams for handling new or unknown content flexibly.