Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To make a Next.js website more search-engine friendly, give each route accurate metadata and a deliberate canonical URL, publish crawl rules and a current sitemap, make important content and links available in rendered HTML, and validate the production output. Next.js provides the implementation tools; Google decides what to crawl, render, canonicalize, index, and show in search results. None of these steps guarantees rankings or indexing.

How do I add SEO metadata in Next.js?

In the App Router, metadata belongs to the route. Use the Metadata API rather than manually duplicating title and description tags. A route with fixed copy can export a static metadata object; a route whose values depend on a slug, content record, or other route data can use generateMetadata. Both are Server Component APIs. See the Next.js Metadata API documentation.

Use static metadata for fixed pages

For an about page or other route with stable content, export metadata from its page or layout:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'About',
  description: 'Learn about our organization and its work.',
}

export default function AboutPage() {
  return <main><h1>About</h1></main>
}

Generate metadata for dynamic routes

For a content route such as /articles/[slug], load the record using the route parameter and return a title and description that accurately represent that page. Use the same source of truth as the visible page content; do not let a missing record produce misleading metadata.

import type { Metadata } from 'next'

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>
}): Promise<Metadata> {
  const { slug } = await params
  const article = await getArticle(slug)

  if (!article) return { title: 'Article not found' }

  return {
    title: article.title,
    description: article.summary,
  }
}

Adapt the parameter type and data-loading logic to the Next.js version and application in use. Write unique, accurate titles and descriptions for people deciding whether to visit. A title tag is not necessarily the exact title Google will display, and a meta description is not guaranteed to be the snippet: Google may construct title links from several page sources and usually derives snippets from page text, sometimes using the description. See Google’s title-link guidance and snippet guidance.

How do I set a canonical URL in Next.js?

A canonical identifies the URL you prefer among duplicate or substantially similar URLs. Set it deliberately for each page or route pattern, and use the public production origin—not a preview host. If your metadata uses relative image or canonical paths, configure a stable metadataBase in the root layout so Next.js can resolve them to absolute URLs.

import type { Metadata } from 'next'

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

For dynamic pages, construct the canonical path from the route’s intended public URL and return it from generateMetadata. Check the emitted document head to confirm the canonical points where intended. Next.js documents alternates.canonical in its metadata API reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A canonical annotation is a preference signal, not an instruction Google must follow. Google describes redirects and rel="canonical" as strong canonicalization signals and sitemap inclusion as a weaker one. When an obsolete duplicate should no longer be visited, a redirect can consolidate access more clearly than leaving both versions live; align redirects, canonicals, and sitemap URLs rather than sending conflicting signals. Google may still choose another canonical or infer one when none is specified. See Google’s canonicalization guidance.

How do I publish crawler rules and a sitemap?

Next.js App Router recognizes app/robots.ts and app/sitemap.ts as special metadata routes. They produce public endpoints for crawler rules and sitemap entries. These routes are cached by default unless their behavior or configuration makes them dynamic; account for caching if sitemap data must reflect content changes promptly. See the robots file documentation and sitemap documentation.

Use robots.txt to control crawler access

A robots file tells compliant crawlers which paths they may fetch; it does not reliably remove a URL from search results. For example, a public app/robots.ts can be shaped like this:

import type { MetadataRoute } from 'next'

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/private-preview/',
    },
    sitemap: 'https://www.example.com/sitemap.xml',
  }
}

Only disallow paths when you intend to prevent crawling. If Google cannot crawl a page, it may not see a noindex directive on that page, and the URL can remain indexed without its contents. To request exclusion of an accessible page from search, allow crawling so Google can see its noindex instruction; use authentication for genuinely private content. Review the intended effect before deploying either directive. Google explains the distinction in its robots.txt guidance and indexing-blocking guidance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Generate a sitemap for preferred public URLs

List the canonical, public pages you want crawlers to discover. A simple app/sitemap.ts can return a small site’s known routes:

import type { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: 'https://www.example.com/',
      lastModified: new Date(),
    },
    {
      url: 'https://www.example.com/about',
      lastModified: new Date(),
    },
  ]
}

For content sites, generate entries from the records that should be public, keeping removed or non-canonical URLs out. Next.js also supports fields such as image URLs, change frequency, and priority, and offers generateSitemaps to split large URL sets. The framework documentation cites Google’s limit of 50,000 URLs per sitemap file. A sitemap aids discovery; it does not guarantee that any listed URL will be crawled or indexed.

Does Google index Next.js websites?

Google can process JavaScript, so a Next.js site can be indexed; using Next.js alone does not ensure that it will be. Google describes crawling, rendering, and indexing as separate stages. Rendering may happen after crawling, and its systems have limitations. Googlebot can discover pages through links, sitemaps, and redirects; important pages should therefore have ordinary crawlable links, such as <a href="/articles/example">, not only click handlers that do not expose a URL.

Keep essential copy in textual content available in the rendered DOM. Server-side rendering or prerendering can make that content available without waiting for client-side JavaScript and can support bots that do not execute JavaScript. Google’s guidance says rendering can be delayed and recommends server-side or pre-rendering as useful for users and crawlers. This is a discoverability and compatibility consideration, not an indexing promise. See Google’s JavaScript SEO guidance and its SEO Starter Guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When should I add structured data?

Structured data can clarify what a page is about and make it eligible for certain rich results, but eligibility does not mean Google will display one. Add JSON-LD only when it accurately describes visible page content and the relevant page type supports a structured-data feature.

Next.js recommends emitting JSON-LD in a script from the relevant page or layout. Build the data from the page’s actual content and safely serialize untrusted fields: JSON.stringify alone does not sanitize malicious strings. Follow the Next.js JSON-LD implementation guide and Google’s structured data policies and guidance.

How do I verify the production result?

Inspect deployed output rather than relying only on source code or a local development view. Choose representative routes, including a dynamic page, and check both what the server returns and what Google’s tools can render.

  1. Check the document output. Confirm the expected title, description, canonical, robots directives, status code, visible text, and internal links. Make sure canonical and sitemap URLs use the intended production origin.
  2. Check crawler endpoints. Open the production /robots.txt and /sitemap.xml and confirm they expose the intended rules and current canonical URLs.
  3. Inspect a URL in Search Console. Use Google Search Console’s URL Inspection to review access and rendered content for a representative deployed page. The tool reports Google’s view; it does not guarantee future indexing.
  4. Test supported structured data. Use Google’s Rich Results Test for features it supports. A valid test does not guarantee a rich result will appear.
  5. Review performance separately. Run a production build and use Lighthouse for a lab simulation, then compare it with field Core Web Vitals. Lighthouse is not a substitute for real-user field data; Next.js outlines this distinction in its production checklist.

Google Search Console documentation for URL Inspection explains how to inspect a URL. A clean technical check establishes that the implementation is behaving as intended; crawling, canonical selection, indexing, and search presentation remain Google’s decisions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.