Skip to content

Next.js SEO prompt

Rules that make your coding agent ship Next.js 16 pages that search engines and social cards read correctly: metadata, canonicals, sitemaps, OG images, JSON-LD and a fast LCP.

What it makes your agent good at

Agents still reach for next/head and next-seo, set priority on images, read params synchronously in generateMetadata, stamp every sitemap URL with new Date() and paste JSON-LD without escaping it. This prompt gives them the Next.js 16 Metadata API and file conventions, the canonical, noindex and redirect rules that keep the index clean, and the checks that prove the served HTML is right.

  1. The Metadata API, not next/headmetadataBase and a title template in the root layout, generateMetadata with awaited params, openGraph that survives the shallow merge.
  2. One canonical URL per pagealternates.canonical on every indexable page, one trailing-slash form, noindex for filters, internal search and account pages.
  3. Sitemaps that tell the truthOnly canonical 200 URLs with real lastModified dates, generateSitemaps with its async id, every file listed in robots.ts.
  4. Share images from codeopengraph-image.tsx with ImageResponse at 1200 by 630, alt text, ttf fonts and the 500 KB limit in mind.
  5. Structured data, escapedJSON-LD in a native script tag with the < character escaped, describing only what the page shows.
  6. Fast where it countsfetchPriority on the LCP image instead of the deprecated priority, next/font, no layout shift, useReportWebVitals.

The Next.js SEO rules

100 lines, current to Next.js 16.4 and React 19.3. Last reviewed October 23, 2026. Plain Markdown, no front matter: each agent's is below.

Download

nextjs-seo.md

# Next.js SEO

You are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.

## Before you write code

- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.
- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.
- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.

## Metadata API

- Export `metadata` (static) or `generateMetadata` (data-dependent) from Server Component layouts and pages only: never both in one segment, never from a Client Component, never hand-written `<title>` or `<meta>` tags.
- Root layout: `metadataBase: new URL(siteUrl)`, `title: { default: "Brand", template: "%s | Brand" }`, a default `description`, `openGraph` with `siteName`, `type` and `locale`, and `twitter: { card: "summary_large_image" }`. Pages set `title` and `description`; use `title.absolute` for a title that should skip a parent's template (a template never applies to the `page.tsx` beside its layout, so the home page needs no override).
- Metadata merges shallowly: a page that sets `openGraph` replaces the parent's whole object. Spread a shared base (`{ ...baseOpenGraph, title }`) or leave `openGraph` out: an `openGraph` without a title or description inherits the page's, and `twitter` fills itself from `openGraph`.
- In `generateMetadata`, await `params`, and read data through the same `cache()`-wrapped function the page uses, so it loads once. Call `notFound()` there too.
- With Cache Components, `generateMetadata` that reads uncached data on an otherwise prerenderable page is an error: add `"use cache"` to it (cached metadata must be serializable: `metadataBase` as a string).
- `themeColor` and `colorScheme` go in `export const viewport`, not in `metadata`.

```tsx
export async function generateMetadata(props: PageProps<"/blog/[slug]">): Promise<Metadata> {
  const { slug } = await props.params;
  const post = await getPost(slug); // cache()-wrapped, shared with the page
  if (!post) notFound();
  return {
    alternates: { canonical: `/blog/${post.slug}` },
    description: post.excerpt,
    openGraph: { ...baseOpenGraph, publishedTime: post.publishedAt, type: "article" },
    title: post.title,
  };
}
```

## Titles, descriptions and canonical URLs

- Titles about 60 characters including the template's suffix, the page's subject first. Descriptions about 155 characters, whole sentences saying what the page offers. Unique on every indexable page.
- Set `alternates.canonical` on every indexable page as a path relative to `metadataBase`, without tracking or sort parameters. Paginated pages canonicalize to themselves, not to page 1.
- Pick one URL form. Next.js redirects `/about/` to `/about` unless `trailingSlash: true`. Metadata URLs follow that setting; URLs you build by hand (sitemap, JSON-LD, links) must match it too.
- Filtered, sorted, internal search, cart, account and thank-you pages get `robots: { follow: true, index: false }`. Keep them crawlable: a page blocked in robots.txt never shows its noindex.
- Resolve records and call `notFound()` before the first Suspense boundary, so the status is a real 404. When it fires inside streamed content, Next.js can only add a `noindex` meta to a 200.

## Social images

- Use the file conventions: `opengraph-image.tsx` (plus `twitter-image.tsx` only if it differs) in the segment, exporting `alt`, `size = { width: 1200, height: 630 }` and `contentType = "image/png"`, returning `new ImageResponse(jsx, { ...size, fonts })` from `next/og`. A deeper segment's image overrides its parent's.
- The image function receives `params` as a promise in Next.js 16; with `generateImageMetadata`, `id` is a promise too.
- `ImageResponse` renders flexbox and a subset of CSS (no grid), takes `ttf`, `otf` or `woff` fonts (not `woff2`), and caps the bundle at 500 KB. Read fonts from the project with `readFile`.
- Static `opengraph-image.png` files work too: under 8 MB (5 MB for `twitter-image`), with an `opengraph-image.alt.txt`.

## Sitemaps, robots and JSON-LD

```ts
// app/sitemap.ts
import type { MetadataRoute } from "next";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getPublishedPosts();
  return posts.map((post) => ({ lastModified: post.updatedAt, url: `${SITE_URL}/blog/${post.slug}` }));
}
```

- List only canonical, indexable URLs that return 200: no redirects, noindex pages or parameters. Set `lastModified` from the content's real date, never `new Date()`. Google ignores `changeFrequency` and `priority`.
- Past 50,000 URLs, split with `generateSitemaps()`. The default export then receives `id` as a `Promise<string>` in Next.js 16: `const id = Number(await props.id)`. Each file is served at `/…/sitemap/[id].xml` and Next.js writes no index, so list them in `robots.ts`'s `sitemap` array.
- `app/robots.ts` returns `{ rules: { allow: "/", disallow: [...], userAgent: "*" }, sitemap }`. Disallow only what must not be crawled (API routes, admin); robots.txt does not remove pages from the index. Disallow everything on preview deployments.
- JSON-LD: a native `<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data).replace(/</g, "\\u003c") }} />` in the page or layout, not `next/script`. Type it with `schema-dts` if the project has it. Describe only what the page shows: `Organization` and `WebSite` in the root layout; `BreadcrumbList`, `Article`, `Product` where they fit.

## Redirects

- Moved URLs get permanent redirects: `redirects()` in `next.config.ts` with `permanent: true` (308) for known paths, `permanentRedirect()` in a page when a slug changed. `redirect()` (307, or 303 after a form post) is for temporary moves. Large, data-driven maps go in `proxy.ts` with a lookup.
- Redirect in one hop to the final canonical URL. Never redirect removed content to the home page: return a 404.

## Rendering, bots and Core Web Vitals

- Content that should rank renders on the server: text, headings, links. Never load primary content in `useEffect`. Internal links use `<Link href>`, so crawlers see real anchors.
- Streaming metadata: on dynamic pages Next.js may send metadata after the first bytes; HTML-limited bots (detected by user agent) get it in the `<head>`. Keep the default; extend `htmlLimitedBots` only for a crawler that misses tags.
- LCP: the hero `next/image` gets `fetchPriority="high"` (or `preload` when it is the LCP element at every viewport); `priority` is deprecated in Next.js 16. Never lazy-load it. Every image has `width` and `height`, or `fill` with `sizes`.
- Fonts come from `next/font`, self-hosted with fallback metrics that prevent layout shift, applied once on `<html>`.
- CLS: reserve space for images, embeds and ads, and make Suspense fallbacks the size of what replaces them.
- INP: keep Client Components small, wrap heavy updates in `useTransition`, and load third-party scripts with `next/script` and a lazy `strategy`.
- Report field data with `useReportWebVitals` from `next/web-vitals` in a small `"use client"` component in the root layout, with a stable callback. Aim, at the 75th percentile, for LCP under 2.5 s, INP under 200 ms, CLS under 0.1.

## Internationalization

- Locale routes live under `app/[lang]/`, prerendered with `generateStaticParams`, with `<html lang={lang}>`.
- Every localized page lists all its versions, itself included, in `alternates.languages` (`{ en: "/en/pricing", fr: "/fr/pricing", "x-default": "/en/pricing" }`) and canonicalizes to its own locale. Mirror the alternates in the sitemap.
- Translate titles, descriptions and Open Graph text per locale. Detect the locale in `proxy.ts` only for the bare `/`; never redirect a locale URL by `Accept-Language` or IP, or crawlers never reach the other versions.

## Do not

- Do not use `next/head`, `next-seo` or hand-written meta tags in the App Router.
- Do not use `priority` on `next/image`, read `params` synchronously in metadata or image routes, or use the sitemap `id` without awaiting it.
- Do not put `themeColor` or `viewport` in `metadata`, stuff `keywords`, or point every page's canonical at the home page.
- Do not block a page in robots.txt to remove it from search, or list a noindex page in the sitemap.
- Do not skip escaping `<` in JSON-LD, or mark up content the page doesn't show.

## Before you finish

- Run `next build` and read its route table: pages meant to be static are, and no metadata error is reported.
- Check the served HTML, not the live DOM: `curl -s <url> | grep -E "<title|canonical|og:|robots"`, and again with a crawler user agent such as `facebookexternalhit` on streamed pages.
- Open `/sitemap.xml`, `/robots.txt` and each image route. Validate JSON-LD with the Rich Results Test and run Lighthouse on each main template.
- Confirm every title and description is unique and within length, and every canonical returns 200.

9,519 characters, 1,389 words. Under Windsurf's 12,000-character limit for a rule, as every prompt here is.

Use it in your agent

The same rules, where your agent reads them. Each file has the front matter its agent needs, set to load when the task fits.

Claude Code

A rule it loads every session

  1. Save it as .claude/rules/nextjs-seo.md in your project, front matter included, or run the install command.
  2. Its paths front matter loads it when Claude reads or edits a matching file, and keeps it out of other work.
  3. Prefer one file? Paste it into CLAUDE.md under its own heading instead.

.claude/rules/nextjs-seo.md

---paths:  - "**/sitemap.ts"  - "**/robots.ts"  - "**/opengraph-image.tsx"  - "**/twitter-image.tsx"---# Next.js SEOYou are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.## Before you write code- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.## Metadata API…

Or let the shadcn CLI write this file: sign in (free) for your command.

Cursor

A project rule with front matter

  1. Save it as .cursor/rules/nextjs-seo.mdc, front matter included, or run the install command.
  2. Cursor attaches it when you work on matching files, or when the task fits its description.
  3. Check it under Cursor Settings, Rules, then commit the folder for your team.

.cursor/rules/nextjs-seo.mdc

---description: "Search and sharing in Next.js 16: metadata, titles, canonical URLs, sitemaps, robots, OG images, JSON-LD, redirects, hreflang and Core Web Vitals."globs: **/sitemap.ts,**/robots.ts,**/opengraph-image.tsx,**/twitter-image.tsxalwaysApply: false---# Next.js SEOYou are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.## Before you write code- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.## Metadata API…

Or let the shadcn CLI write this file: sign in (free) for your command.

Windsurf

A workspace rule for Cascade

  1. Save it as .windsurf/rules/nextjs-seo.md, or run the install command.
  2. trigger: model_decision lets Cascade pull it in when the task fits its description.
  3. Windsurf reads up to 12,000 characters per rule; this one is 9,519.

.windsurf/rules/nextjs-seo.md

---trigger: model_decisiondescription: "Search and sharing in Next.js 16: metadata, titles, canonical URLs, sitemaps, robots, OG images, JSON-LD, redirects, hreflang and Core Web Vitals."---# Next.js SEOYou are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.## Before you write code- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.## Metadata API…

Or let the shadcn CLI write this file: sign in (free) for your command.

GitHub Copilot

Instructions for the repository

  1. Save it as .github/instructions/nextjs-seo.instructions.md, or run the install command.
  2. applyTo limits it to the files it's about, in chat, the coding agent and code review.
  3. Or paste it into .github/copilot-instructions.md, which Copilot reads for every request.

.github/instructions/nextjs-seo.instructions.md

---description: "Search and sharing in Next.js 16: metadata, titles, canonical URLs, sitemaps, robots, OG images, JSON-LD, redirects, hreflang and Core Web Vitals."applyTo: "**/sitemap.ts,**/robots.ts,**/opengraph-image.tsx,**/twitter-image.tsx"---# Next.js SEOYou are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.## Before you write code- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.## Metadata API…

Or let the shadcn CLI write this file: sign in (free) for your command.

Codex & AGENTS.md

The file most agents read

  1. Paste it into AGENTS.md at your project's root, under its own heading.
  2. Codex reads AGENTS.md before it starts work, and so do Cursor, Zed, Jules, Amp and Copilot's coding agent.
  3. A folder can have its own AGENTS.md: the one closest to the file being edited wins.

AGENTS.md

## Next.js SEOYou are working on search and sharing for a Next.js 16 App Router project. Write metadata, metadata files and markup for the version in `package.json`, not the one in your training data: the Metadata API and file conventions replace hand-written `<head>` tags, and several props and signatures changed in Next.js 16.### Before you write code- Read `node_modules/next/dist/docs/01-app/01-getting-started/14-metadata-and-og-images.md`, `03-api-reference/04-functions/generate-metadata.md`, `03-api-reference/03-file-conventions/01-metadata/` and `02-guides/json-ld.md`.- Check the root layout for `metadataBase`, the title template and the shared `openGraph`; `next.config.ts` for `trailingSlash`, `redirects` and `htmlLimitedBots`; `app/` for `sitemap.ts`, `robots.ts`, `opengraph-image.*` and `icon.*`.- Find the production URL (an env var such as `NEXT_PUBLIC_SITE_URL`) and the URL form the site uses (trailing slash or not). Every absolute URL you write uses both.### Metadata API…

AGENTS.md is shared with your own instructions, so paste the rules in: the copy sets their headings a level down.

Rules teach it. The MCP equips it. With Pro, your agent installs every component, block and icon it needs, from a prompt.

Get Pro

Pricing

Give your agent the parts, with Pro

The prompts are free. Every Pro plan adds the MCP server, so your agent installs the components, blocks and icons it writes code around.

4.9/5 out of 5 · 150+ reviewsfrom 150+ founders and developers.

Billed once a year in USD. Cancel anytime.

Individual

For personal projects & open source

$32instead of $49/mo

$389 billed yearly

  • How many people can use the license.Seats: 1 seat
  • Client work, SaaS products and anything you charge for.Commercial use: Personal & open source only
  • Page sections in 56 categories, from heroes and pricing tables to dashboards and settings, on every framework and UI library, in your theme.Blocks: All 6,181 blocks
  • Complete Next.js sites for startups, SaaS, agencies and portfolios, every page designed, ready to ship.Templates: All 14 templates
  • Your AI agent searches, previews and installs any component, block, icon or DESIGN.md from a prompt: 22 tools in Claude Code, Cursor, VS Code and 35 more clients.MCP server: 38 AI clients
  • Buttons with motion and states of their own, from an arrow that slides in to a burst of confetti.Animated buttons: All 35 buttons
  • Typewriters, scrambles, counters and more, for headlines, labels and numbers.Text effects: All 97 effects
  • Animated backgrounds for heroes, sections and cards, from a soft aurora to a flock that flees the cursor. Most are pure CSS.Backgrounds: All 100 backgrounds
  • WebGPU shaders, from a slow aurora to a black hole, each drawing only while it's on screen.Shaders: All 100 shaders
  • One design and one theme on all four: the components, blocks and effects are built for each framework.Frameworks: React, Vue, Svelte, Solid
  • React on Base UI, Radix UI, React Aria or Ark UI: install the version for the library your project already uses. Vue, Svelte and Solid run on Ark UI.UI libraries: Base UI, Radix, Aria, Ark
  • From a button to a date picker, a color picker or a guided tour: accessible, typed in TypeScript, each with live demos.Components: All 174 components
  • Real-world patterns built from the components, in 53 galleries: forms, tables, menus, dialogs and more.Examples: All 1,103 examples
  • Area, bar, line, pie, radar and radial charts on TanStack Charts, on every framework. React also gets the Recharts originals.Charts: All 70 charts
  • Debounce, local storage, media queries and more: each hook is one typed file you own.React hooks: All 35 hooks
  • From 222 libraries, Lucide, Heroicons, Tabler and Material Symbols among them, as SVG or a React component in one command.Icons: 294k+ icons
  • Stripe, Linear, Apple and 497 more: a brand's colors, typography and components in one file your AI agent builds from.DESIGN.md files: All 500 brands
  • Restyle every component and block at once: 8 styles, 7 grays, 18 colors and 5 radii, shared as a shadcn preset code.Theme builder: 8 styles × 18 colors
  • Priority requests are answered first.Support: Standard

Team

Most popular

For freelancers, agencies & startups

$66instead of $99/mo

$789 billed yearly · ≈ $13/dev/mo

Everything in Individual, plus

  • How many people can use the license.Seats: Up to 5 seats
  • Client work, SaaS products and anything you charge for.Commercial use: Included
  • Priority requests are answered first.Support: Priority

Organization

For companies with larger teams

$132instead of $199/mo

$1,589 billed yearly

Everything in Team, plus

  • How many people can use the license.Seats: Unlimited seats
  • Secure checkout via Stripe
  • Code lives in your repo
  • Keep what you've shipped if you cancel
  • License terms

Next.js SEO prompt FAQ

What the Next.js SEO prompt covers and how to use it in your agent.

How does the Next.js SEO prompt handle sitemaps in Next.js 16?

A sitemap.ts that lists only canonical URLs returning 200, with lastModified from real content dates. Past 50,000 URLs it uses generateSitemaps, awaits the id the sitemap function now receives as a promise, and lists every generated file in robots.ts, since Next.js writes no sitemap index.

Should filtered and search pages be noindex in Next.js?

Yes. The prompt marks filtered, sorted, internal search, cart and account pages with robots index false and follow true, and keeps them crawlable so search engines can read that tag. Blocking them in robots.txt would hide the noindex instead.

Which redirect should a moved Next.js page use?

A permanent one: redirects in next.config.ts with permanent set to true, which sends a 308, or permanentRedirect() when a slug changes in the page. redirect() sends a 307 and is for temporary moves. The prompt also asks for one hop to the final URL and a 404 for removed content.

How does the Next.js SEO prompt set up hreflang?

Each localized page lists every version, itself included, in alternates.languages with an x-default, canonicalizes to its own locale, and the sitemap mirrors the same alternates. Locale detection redirects only the bare root, so crawlers can reach every language.

4.9 out of 5 from 150+ developers

Rules teach it. The MCP equips it.

Every component, block and icon, installed by your AI agent on your stack. The prompts stay free.

Get Pro
  • Cancel anytime
  • Keep what you've shipped