Next.js can rank and get cited by AI search as well as any other framework, but only with deliberate choices: server rendering rather than client rendering, the Metadata API instead of hand-rolled tags, and JSON-LD structured data. Left on defaults, a client-heavy Next.js app can look blank to both Google and AI crawlers.
Quick links
- Does the way you render a Next.js page affect its SEO?
- How do you set metadata correctly in Next.js?
- How do you add structured data to a Next.js site?
- Can AI crawlers actually read a Next.js site?
- Does Next.js hurt your Core Web Vitals?
- When is Next.js the wrong choice for SEO?
- FAQ
Does the way you render a Next.js page affect its SEO?
More than almost anything else you will do to the site. Next.js lets you pick a rendering strategy per route, and the wrong pick can hide your content from crawlers entirely rather than just slow them down.
In the App Router, every component is a server component unless you mark it otherwise, which means the framework’s default already leans the right way for SEO. From there you are choosing between four patterns, and most sites use more than one:
- Static generation. The page is built once, at build time, into plain HTML. Fastest to serve, cheapest to run, and the right default for a marketing page, a pricing page or a case study that does not change per visitor.
- Server-side rendering. The page is built fresh on every request. Reach for it when content genuinely depends on the specific visitor or request: a personalised dashboard, a search results page, live pricing.
- Incremental static regeneration. A static page that quietly rebuilds itself in the background on a timer or on demand. This is the right middle ground for a blog or a listings page: fast to serve, but never more than a few minutes stale.
- Client-side rendering. The server sends a near-empty HTML shell and the browser fills it in with JavaScript. Fine for logged-in application screens nobody needs indexed. A bad choice for anything you want ranked or cited.
The App Router’s server and client component model is what makes this configurable per route rather than an all-or-nothing setting for the whole app, which is a genuine advantage over older single-page-app architectures. The trade-off is that it is also easy to reach for 'use client' out of habit and quietly push content-bearing sections back into the browser, undoing the default you started with.
How do you set metadata correctly in Next.js?
Use the built-in Metadata API rather than writing tags by hand. Export a static metadata object from a page or layout, or an async generateMetadata function when the values depend on fetched data, and Next.js writes the tags into the document head for you.
The static form suits fixed pages: an about page, a pricing page, a contact page. The dynamic form is for anything templated, such as a blog post or a case study, where the title and description need to come from the content itself rather than a hardcoded string. Next.js’s own documentation covers both, plus the file conventions for sitemaps, robots rules and Open Graph images, which used to be hand-built and are now generated for you.
A few things worth getting right on every route:
- A unique title and description per page. Title templates in a root layout keep this consistent without repeating your brand name everywhere.
- A canonical URL, especially if the same content is reachable through more than one path.
- Fallback values in
generateMetadata. If a data fetch fails and you return nothing, Next.js falls back to the parent layout’s metadata, which is rarely what you want on a page that is supposed to be distinct.
None of this is exotic. It is mostly discipline: nobody skipping the metadata export because a page felt too minor to bother with.
How do you add structured data to a Next.js site?
Render JSON-LD directly as a script tag in the page or layout component. Next.js has no separate structured-data API; you build the object in your server component and serialise it inline, and because the component runs on the server, the markup lands in the HTML the page actually ships.
Next.js’s guide to JSON-LD recommends a plain <script type="application/ld+json"> tag with dangerouslySetInnerHTML, not the next/script component, since next/script is built for executable JavaScript and JSON-LD is data, not code. Escape the output before you ship it. JSON.stringify does not sanitise the string for you, so a stray < in user-generated content could break out of the script tag if you serialise it unescaped.
Worth having, in rough order of value:
- Organization schema on the homepage, so your name, logo and social profiles are unambiguous.
- Article schema on blog posts, with an author and a published date.
- FAQPage schema on any page with a genuine FAQ section.
- BreadcrumbList schema once the site has real navigation depth.
Test what you have with Google’s Rich Results Test against the deployed URL, not a local copy. Dev and production HTML can differ enough that a check on localhost tells you nothing about what a crawler actually sees.
Can AI crawlers actually read a Next.js site?
Yes, provided the content that matters is server-rendered, which is the App Router’s default behaviour. Where sites fall down is content that only appears after client-side JavaScript runs, because most AI crawlers do not wait for that to happen.
Vercel’s own analysis of crawler behaviour found that GPTBot, ClaudeBot and PerplexityBot fetch the initial HTML and largely do not execute JavaScript on top of it. Googlebot is the exception: it renders JavaScript, but on a delay and a crawl budget, which is a different problem to solve than an AI crawler that simply never sees the content at all.
This is genuinely good news for a properly built Next.js site, since server components mean the content is already in the HTML by default, unlike the client-side single-page apps of a few years ago. To check your own pages:
- View page source, not the rendered page, and search for a sentence you know is on the page. If it is missing, it was injected by JavaScript after the fact.
- Check robots.txt for accidental blocks on GPTBot, ClaudeBot, PerplexityBot or Google-Extended.
- Audit any
'use client'boundary that wraps content rather than just interactivity. A pricing table or a case study body inside a client component is a common, avoidable mistake.
Does Next.js hurt your Core Web Vitals?
Not by default, but it will not protect you from yourself either. A Next.js site’s Core Web Vitals reflect how it is built far more than which framework built it.
Google measures three metrics at the 75th percentile of real visitors: Largest Contentful Paint should land under 2.5 seconds, Interaction to Next Paint under 200 milliseconds, and Cumulative Layout Shift under 0.1, according to Google’s published thresholds. Miss any one of the three and the page does not pass, regardless of how the other two score.
Next.js gives you the tools to hit those numbers: automatic image optimisation, font optimisation that avoids layout shift from late-loading web fonts, and code-splitting by route. It does not use them for you. A site built with heavy client components, large unoptimised images and a font loaded the old way will score badly on a framework that was fully capable of scoring well. The gap between a fast Next.js site and a slow one is almost entirely implementation, which is also why two agencies can hand you wildly different numbers on the same stack.
When is Next.js the wrong choice for SEO?
When the site is content, not software. A marketing site, a blog and a case study library do not need React’s application model, and every extra kilobyte of client JavaScript is a small tax on the same speed and readability metrics you are trying to win on.
We build most of our own client sites on Astro rather than Next.js for exactly this reason: it ships close to zero JavaScript by default, which removes an entire category of mistake before anyone gets the chance to make it. We cover the trade-off properly in our Astro versus Next.js comparison, but the short version is that Next.js earns its weight when there is real application logic behind the login: a dashboard, a configurator, personalised content, live inventory. A five-page site with a blog is rarely that.
If you are choosing a CMS to sit behind either framework, our ranked look at the best headless CMS options is a reasonable next stop. And if the honest comparison you actually need is against WordPress rather than another React-adjacent framework, our Astro versus WordPress piece covers the same ground from that angle.
None of this means Next.js is a poor SEO choice. It is a capable one that happens to give you more rope than you need for a marketing site. Used deliberately, with server rendering as the default and client components reserved for genuine interactivity, it ranks and gets cited fine. Used carelessly, it is easy to build something that looks great in the browser and nearly invisible to everything else reading it.
Work out what a properly built Next.js site should cost
Framework is one input. Rendering strategy, CMS, integrations and copy move the number far more than the name on the tin. Our calculator gives you an honest range in about a minute, with no form-gate and no follow-up sequence you did not ask for.
- A realistic range for your build, not a teaser price
- What actually drives the cost up, so you can trade off
- Real proof: PageSpeed 34 to 86 and a lead inside 24 hours