Skip to content
HomeArticlesWorksContact

Nabeel Nashid © 2026

development3 min read

Next.js SEO Checklist for 2026: Metadata, Sitemaps and Structured Data

A complete, copy-paste checklist to make your Next.js App Router site rank - metadata, canonical URLs, Open Graph, sitemaps, robots and JSON-LD.

N
Nabeel Nashid
Designer & Developer

Next.js gives you excellent SEO foundations out of the box, but "good defaults" are not the same as "ranked". This checklist covers everything you need to do to make a Next.js App Router site technically excellent for search — from metadata and canonical URLs to sitemaps, structured data and Core Web Vitals.

Everything here is copy-paste friendly. If you are also wiring up a database, start with the Next.js + Supabase guide first.

1. Use the Metadata API, not manual tags

The App Router exposes a typed metadata export. Next injects the tags for you, handles deduplication and streams them efficiently.

export const metadata: Metadata = {
  title: {
    default: 'Nabeel Nashid',
    template: '%s | Nabeel Nashid',
  },
  description: 'Designer and developer building thoughtful digital experiences.',
}

Use a title template so every page gets a consistent, keyword-rich suffix without repeating yourself.

2. Set metadataBase and canonical URLs

metadataBase resolves all relative URLs in your metadata — canonical, Open Graph, images — to absolute ones. Set it once in the root layout.

export const metadata: Metadata = {
  metadataBase: new URL('https://nabeelnashid.com'),
  alternates: { canonical: '/' },
}

Every page should declare its own canonical. This prevents duplicate-content problems from query strings, trailing slashes and pagination.

3. Open Graph and Twitter cards

Links get shared constantly. Without Open Graph tags your URLs look bare. Next can even generate images dynamically.

openGraph: {
  type: 'article',
  url: 'https://nabeelnashid.com/read/my-post',
  images: [{ url: '/opengraph-image', width: 1200, height: 630 }],
},
twitter: { card: 'summary_large_image' },

Drop an opengraph-image.tsx file next to a route and Next generates a 1200×630 image with ImageResponse. Add the same image to Twitter and let Twitter fall back to Open Graph when a dedicated tag is missing.

4. Generate a sitemap

Add app/sitemap.ts and return every URL you want indexed, with a real lastModified.

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getPosts()
  return [
    { url: 'https://nabeelnashid.com', priority: 1 },
    { url: 'https://nabeelnashid.com/articles', priority: 0.9 },
    ...posts.map((p) => ({
      url: `https://nabeelnashid.com/read/${p.slug}`,
      lastModified: new Date(p.published_at),
      priority: 0.8,
    })),
  ]
}

Submit the sitemap in Google Search Console and keep it accurate. Stale sitemaps waste crawl budget.

5. Control crawling with robots.ts

Tell crawlers what to index and point them at your sitemap. Keep private areas — dashboards, APIs, admin panels — out of the index.

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [{ userAgent: '*', allow: '/', disallow: ['/api/', '/admin/'] }],
    sitemap: 'https://nabeelnashid.com/sitemap.xml',
  }
}

6. Add structured data (JSON-LD)

Structured data helps search engines understand your content and unlocks rich results. For a blog, use BlogPosting and BreadcrumbList.

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{ __html: JSON.stringify({
    '@context': 'https://schema.org',
    '@type': 'BlogPosting',
    headline: post.title,
    datePublished: post.published_at,
    author: { '@type': 'Person', name: 'Nabeel Nashid' },
  }) }}
/>

Also add WebSite and Person on the home page. Validate everything with Google's Rich Results Test.

7. Nail Core Web Vitals

  • Use Server Components to ship less JavaScript.
  • Optimise images with next/image, correct dimensions and modern formats.
  • Preload fonts and use font-display: swap to avoid layout shift.
  • Reserve space for images and embeds so Cumulative Layout Shift stays near zero.
  • Cache aggressively with ISR (export const revalidate) for content that changes rarely.

8. Semantic HTML and heading order

Use one h1 per page, then h2 for sections and h3 for subsections. Search engines and screen readers both rely on heading structure. Prefer <article>, <nav>, <header> and <footer> over generic <div> soup.

Quick checklist

  • Title template and unique descriptions on every route
  • metadataBase set, canonical on every page
  • Open Graph and Twitter images present
  • Dynamic sitemap.xml submitted to Search Console
  • robots.txt disallows private routes
  • JSON-LD for articles, breadcrumbs, site and person
  • Core Web Vitals in the green
  • Semantic headings and landmarks

Final thoughts

Technical SEO in Next.js is mostly about being deliberate: set metadata once, canonicalise every page, ship a sitemap, add structured data and keep the site fast. Do those consistently and search engines will reward you. See the works page for real examples of sites built with this approach.

All articles

Related articles