Next.js SEO Checklist for 2026
The metadata, sitemap, robots and rendering checks a Next.js App Router site needs before launch, using the built-in Metadata API rather than manual tags.
A Next.js SEO checklist covers four things: metadata set through the Metadata API on every route, a generated sitemap and robots file, a deliberate rendering strategy per route, and canonical URLs on any page reachable more than one way. Get those right and the framework does the rest.
The checklist below assumes App Router. If you're coming from WordPress SEO and comparing platforms, the difference is that none of this needs a plugin — it's file conventions and exported functions the framework reads directly.
On this page
What does a Next.js SEO checklist actually need to cover?
Four layers: metadata (titles, descriptions, Open Graph, canonical), discoverability (sitemap and robots), rendering strategy (static, dynamic or streamed), and structured data (JSON-LD). Miss any one and the others don't compensate for it — a perfect sitemap doesn't help a page with no title tag.
| Concern | File or function | Applies to |
|---|---|---|
| Title, description, OG tags | generateMetadata() or metadata export | Every route |
| Sitemap | app/sitemap.ts | Whole site |
| Robots rules | app/robots.ts | Whole site |
| Canonical URL | alternates.canonical in metadata | Any route with more than one reachable path |
| Structured data | JSON-LD script in the page component | Pages where a rich result applies |
Treat this as a per-route checklist, not a one-time site setup. A new dynamic route added six months from now needs the same four layers as the ones that shipped at launch, and it's easy to add a route and forget one of them.
How do you set metadata correctly?
With generateMetadata, an async function each route exports that returns the title, description, Open Graph and canonical data for that specific page — including data fetched from your CMS or database, which a static metadata object cannot do [1].
Use generateMetadata for anything dynamic
A blog post, product page or any route whose title depends on fetched data needs the async function, not the static export.
Set a title template at the root layout
A template like "%s | Your Brand" applied once in the root layout means every child route's title gets the suffix automatically, without repeating it everywhere.
Always set alternates.canonical explicitly
Next.js does not infer a canonical URL for you — a route reachable via a trailing slash, a query parameter, or a locale prefix needs its canonical set by hand.
Fill Open Graph and Twitter fields on every public page
A missing OG image is the most common reason a shared link looks broken on social platforms, and it's a one-line fix once you know to check.
Do you need a sitemap.ts file?
Yes, on any site with more than a handful of pages. app/sitemap.ts is a file convention: export a function returning an array of URLs with their last-modified dates, and Next.js serves it at /sitemap.xml with the correct content type automatically [2].
For a large or multi-locale site, sitemap.ts can return multiple sitemap files instead of one, which keeps each file under the 50,000-URL limit search engines expect and makes it easier to see which section of the site a crawl issue is coming from.
How should robots.txt work in Next.js?
The same way: app/robots.ts exports rules and a reference to the sitemap URL, and Next.js serves it at /robots.txt [3]. The checklist item here isn't the file's existence — it's making sure it doesn't accidentally disallow the whole site, which happens more often than it should on a staging deploy that gets promoted to production without the robots rule being reviewed.
Does rendering strategy affect SEO in Next.js?
Yes, indirectly, through indexing speed rather than ranking ability. A statically generated route is available to crawlers the moment it deploys; a dynamically rendered one has to be fetched live on each crawl, which works but is slower and puts more load on your server during a crawl spike.
generateStaticParams pre-renders a dynamic route's known params at build time, so a blog with a thousand posts can ship all thousand as static HTML rather than rendering each one on its first visit. Pages that genuinely need fresh data on every request — a live dashboard, a personalized page — are the right use case for dynamic rendering; a blog post is usually not.
There's a middle option worth knowing about: a route can be static at build time and still pick up new content without a full redeploy, through revalidation on a schedule or on demand after a content change. That combination — static by default, fresh when the content actually changes — covers most content sites better than choosing purely static or purely dynamic for the whole route.
Does structured data need special handling in Next.js?
Not really — it's a <script type="application/ld+json"> tag with a JSON object inside it, rendered from your page component like any other markup. There's no dedicated file convention for it the way there is for the sitemap and robots files.
The checklist item is consistency, not the JSON itself: build the structured data from the same data source that populates the visible page and the metadata, rather than hand-writing a separate JSON-LD object that can drift out of sync with what a visitor actually sees. A product page whose JSON-LD price disagrees with the price shown on the page is a mismatch search engines can and do flag, and it's avoidable by generating both from one place.
What do people get wrong about canonical URLs?
They assume Next.js infers one, and it does not. A product page reachable at /products/widget and /products/widget?ref=email is, to a crawler, two different URLs unless alternates.canonical on that route explicitly says which one is authoritative.
This gets worse on routes with query-parameter-driven filters or sorting, where the same content is reachable through dozens of parameter combinations. Set the canonical to the clean, parameter-free URL on every one of them, and the duplicate-content risk goes away without touching the filtering logic itself. The same discipline matters whatever platform you're comparing against — see our WordPress SEO checklist for the equivalent list on that platform, and Yoast vs Rank Math if a client is choosing between WordPress plugins instead of a framework.
How do you verify all of this actually shipped?
Fetch each route type — static, dynamic, and one with query parameters — with a plain HTTP client and read the raw HTML, not the rendered browser output. The title tag, meta description, canonical link and JSON-LD should all be present in that raw response, because that's closer to what a crawler actually sees on the first pass.
Then check /sitemap.xml and /robots.txt directly in a browser after every deploy that changes routing, not just after the initial launch. A checklist run once at launch catches nothing that breaks six months later when a new route type gets added without anyone re-running it.
Questions people also ask
Does Next.js need an SEO plugin like WordPress does?
No. Metadata, sitemaps and robots rules are built into the framework through file conventions and the Metadata API, so there is no plugin ecosystem to choose between — the checklist is about using what already ships.
Is App Router better for SEO than Pages Router?
Neither router is inherently better ranked. App Router's Metadata API is more ergonomic and reduces the chance of forgetting a tag on a route, which is a real but indirect advantage.
Do I need generateStaticParams for SEO?
You need it for a dynamic route to be pre-rendered at build time rather than only on first request, which affects how quickly a new page becomes crawlable — not a direct ranking factor, but a real speed-to-index difference.
Does Next.js generate a sitemap automatically?
No — you write a sitemap.ts or sitemap.xml file yourself using the file convention. Next.js handles the routing and content type for you, but the list of URLs is still your data.
What is the most common Next.js SEO mistake?
Missing or duplicate canonical URLs, usually from a dynamic route that can be reached through more than one path without a canonical tag pointing search engines at the one you want indexed.
Sources
- generateMetadata — Next.js (checked 23 September 2026)
- sitemap.xml — Next.js (checked 23 September 2026)
- robots.txt — Next.js (checked 23 September 2026)
Run this checklist against your own Next.js site
Book a free 30-minute consultation with Ibrahem and Jeremy. We look at your site while we talk, and you leave with a prioritised plan.
Who wrote this
Ibrahem HelalCo-founder
Leads strategy and delivery.
Works on: SEO, GEO
Reviewed before publishing by Jeremy Zava, Co-founder.
- WordPress SEO: the complete guide for 2026How to do WordPress SEO properly: settings, plugins, speed, security, structure and when to leave WordPress for HubSpot or a headless stack.
- Headless CMS SEO: What Actually ChangesHeadless CMS SEO doesn't come from a plugin. Here's what moves to your frontend framework, what you lose without one, and how to verify it works.
- HubSpot CMS SEO: What's Automatic, What Isn'tWhat HubSpot's CMS Hub handles for SEO out of the box, what its built-in recommendations actually check, and where you still need to do the work yourself.
- WordPress Technical SEO: The Full Fix ListWhy WordPress sites get crawl and indexing problems by default, and the specific settings, sitemap and canonical fixes that resolve them.
