Next.js SEO Checklist for the App Router
A practical Next.js App Router SEO checklist covering metadata, canonical URLs, OpenGraph, structured data, sitemap, RSS, and performance.
The App Router gives Next.js projects a clean way to colocate pages, metadata, loading states, and server data. That structure is useful for SEO because search optimization becomes part of the route instead of an afterthought.
This checklist focuses on practical SEO work for product pages, portfolio pages, and technical blogs.
Define page metadata first
Every indexable route should have a clear title and description. The title should describe the page intent, and the description should explain why the result is worth opening.
export const metadata = {
title: "Blog",
description:
"Technical writing on NestJS, Next.js, system design, and web performance.",
alternates: {
canonical: "https://hoangtuan.me/blog",
},
};For dynamic routes, generate metadata from the same source as the page content. This avoids mismatches where the rendered article says one thing but the search snippet says another.
Use canonical URLs consistently
Canonical URLs tell search engines which URL should represent the content. They are especially important when the same content can appear through filters, tracking parameters, or alternate routes.
For blog posts, use a stable canonical pattern:
alternates: {
canonical: `https://hoangtuan.me/blog/${slug}`,
}Keep the canonical host consistent with production. Mixing www and non-www versions weakens the signal.
Ship OpenGraph images for shareability
OpenGraph is not a ranking shortcut, but it improves how articles appear when shared on LinkedIn, Slack, Facebook, and messaging apps. Better previews usually improve click-through.
In App Router projects, route-level opengraph-image.tsx can generate a dynamic image from article metadata. At minimum, include the title, author, and site name. For portfolio blogs, a simple branded image is often enough.
Add structured data where it helps
Structured data helps crawlers understand the page. For technical articles, BlogPosting is usually the right schema.
Useful fields include:
headlinedescriptiondatePublisheddateModifiedauthorpublisherimagemainEntityOfPage
Do not invent fields that are not visible or true. Schema should reflect the page, not decorate it.
Keep sitemap and RSS in sync
Sitemap and RSS should read from the same content source as the blog routes. If a post exists at /blog/my-post, it should also appear in sitemap.xml and feed.xml.
This is one reason local MDX content works well for a small portfolio. The same file can drive the article page, metadata, sitemap, RSS feed, and homepage recent post cards.
Treat performance as SEO work
Performance affects crawl efficiency and user behavior. For content pages, focus on the basics:
- Serve static pages when content is known at build time.
- Use optimized images with stable dimensions.
- Avoid unnecessary client-side data fetching for article content.
- Keep JavaScript out of the article body unless the interaction is valuable.
- Make headings and links render in the initial HTML.
Frontend SEO depends on backend reliability too. If your pages consume API data, start with clear service boundaries as described in NestJS Modular Architecture: Building Production APIs That Scale. When the app is ready to ship, connect the SEO work to a predictable deployment flow with Dockerizing a NestJS App for Production.
Facing performance issues or scaling challenges?
I specialize in building low-latency map infrastructure, real-time streaming pipelines (Kafka, ClickHouse), and highly optimized backend systems. Let's work together to scale your product.