Quick answer
Technical SEO for a Next.js site means making every important page server-rendered, giving each one a unique title, description and canonical URL, publishing a sitemap and robots file, adding JSON-LD structured data, returning correct status codes, and keeping Core Web Vitals in the good range. The App Router provides built-in APIs for all of these.
Key takeaways
- Render indexable content on the server so crawlers and AI bots see it without running JavaScript.
- Set metadataBase once, then give every route its own title, description and canonical URL.
- Generate sitemap.xml and robots.txt from the same content source as your pages.
- Use JSON-LD for Organization, BreadcrumbList, Article and FAQPage where it matches visible content.
- Return real 404s and permanent redirects so search engines do not index broken or duplicate URLs.
Why does rendering strategy matter for SEO in Next.js?
Search engines can render JavaScript, but rendering is deferred, resource-limited and not guaranteed for every crawler. Many AI crawlers fetch raw HTML and do not execute scripts at all. If your headings, body copy and links only appear after client-side code runs, some systems will see an empty page.
In the App Router, components are Server Components by default and static routes are prerendered at build time. Keep it that way for content. Use "use client" only for interactive islands such as filters, menus and forms, and pass the content into them as props so the HTML still contains it.
How should I set titles, descriptions and canonical URLs?
Set metadataBase in the root layout so every relative URL in metadata resolves against your production origin. Use a title template so each page only declares its own name, then add a canonical URL per route with alternates.canonical.
// app/layout.tsx
export const metadata: Metadata = {
metadataBase: new URL("https://example.com"),
title: { default: "Example Co", template: "%s | Example Co" },
};
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
const { slug } = await params;
const post = getPost(slug);
return {
title: post.title,
description: post.description,
alternates: { canonical: `/blog/${slug}` },
openGraph: { type: "article", publishedTime: post.published },
};
}- Keep titles specific and roughly under 60 characters so they are less likely to be truncated.
- Write descriptions as a one-sentence answer to why someone should click; aim for about 150–160 characters.
- Canonical URLs should be absolute, use one protocol and host, and match the URL you put in the sitemap.
- Treat environment variables carefully: a site URL missing
https://silently produces invalid canonical and sitemap URLs.
How do I generate a sitemap and robots.txt in Next.js?
Add app/sitemap.ts and app/robots.ts. Both are special route handlers that are statically generated by default. Build the sitemap from the same data that generates your pages, so a new article or service page is listed automatically, and include lastModified for content that changes.
// app/sitemap.ts
export default function sitemap(): MetadataRoute.Sitemap {
return posts.map((post) => ({
url: `https://example.com/blog/${post.slug}`,
lastModified: post.updated ?? post.published,
}));
}In robots.txt, block only what should never be crawled, such as API routes, and point to the sitemap. Remember that robots.txt controls crawling, not indexing: use a noindex robots meta tag for pages that must not appear in results.
Which structured data should a business website use?
Structured data describes entities explicitly so search engines and AI systems do not have to infer them. In Next.js, render JSON-LD with a native <script type="application/ld+json"> tag in the page or layout, and escape < characters to prevent script injection.
| Schema type | Where to use it |
|---|---|
| Organization + WebSite | Root layout, once per site |
| BreadcrumbList | Every page below the homepage |
| Service | Each service detail page |
| BlogPosting or TechArticle | Each article, with author and dates |
| FAQPage | Pages with visible question-and-answer content |
| SoftwareApplication | Product pages for apps and platforms |
Only mark up content that is visible on the page. Google restricts FAQ rich results to a small set of authoritative sites, but the markup still helps other systems understand the questions you answer. Validate with the Rich Results Test and the Schema Markup Validator.
How do I handle 404s and redirects correctly?
Call notFound() for unknown slugs so the route returns an HTTP 404 instead of a page that says 'not found' with status 200 (a soft 404). When you rename a section, add permanent redirects in next.config.ts so existing links and rankings carry over to the new URL.
// next.config.ts
async redirects() {
return [
{ source: "/insights", destination: "/blog", permanent: true },
{ source: "/insights/:slug", destination: "/blog/:slug", permanent: true },
];
}What performance work matters most for rankings?
Page experience is one of many ranking signals, and it strongly affects conversion. Focus on the three Core Web Vitals: Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift. Our Core Web Vitals guide covers thresholds and fixes in detail.
- Use
next/imagewith explicit dimensions andpriorityonly for the main above-the-fold image. - Use
next/fontso fonts are self-hosted and do not shift the layout when they load. - Keep client components small; every extra kilobyte of JavaScript delays interaction.
- Prefer static generation for content pages so they can be served from a CDN edge.
How does internal linking help SEO?
Internal links help crawlers discover pages and show which pages are most important. Link articles to the services they relate to, link services to supporting articles, and use descriptive anchor text instead of 'click here'. Breadcrumbs add a consistent hierarchy that also appears in search results when marked up.
Organise articles into topic clusters: one category page per topic that links to every related article. This makes it clear which subjects your site covers in depth, which matters for both traditional search and AI answer engines.
Frequently asked questions
Is Next.js good for SEO?
Yes. Next.js renders pages on the server or at build time, so crawlers receive complete HTML. It also includes built-in APIs for metadata, sitemaps, robots files and Open Graph images. SEO quality still depends on content, structure and implementation.
Do I need a plugin for SEO in Next.js?
No. The App Router's Metadata API, sitemap.ts, robots.ts and opengraph-image conventions cover the technical foundations without third-party packages.
Does client-side rendering hurt SEO?
It can. Google renders JavaScript but with a delay and limited resources, and many other crawlers, including several AI crawlers, read only the initial HTML. Server-render content that you want indexed.