Skip to content

SEO · 7 min

Technical SEO in Next.js: what to check before launch

What to check on a Next.js website before it goes live: metadata, canonicals, hreflang, sitemap, indexing, redirects, rendering, structured data, images and performance.

By Roke Studio7 min

Next.js makes a lot of technical SEO easier.

It has a metadata API, sitemap and robots generation, Server Components, image optimisation and several ways to render a page.

But you can use all of that and still launch a website with conflicting canonicals, badly connected languages, missing pages that respond with a 200, or content Google can barely discover.

The framework gives you the tools.

The implementation is still up to you.

This is the list I'd go through before launching an App Router project.

Metadata: every page needs to describe itself properly

Next.js lets you define static metadata with metadata, or generate it from data with generateMetadata.

I'd check:

  • a specific, descriptive title on important pages;
  • a description that matches the actual content;
  • metadataBase set up correctly if you use relative URLs in metadata;
  • the right canonical;
  • Open Graph where it matters how the page looks when shared.

I wouldn't use generateMetadata just because it's there.

If the information is static, metadata is simpler.

On dynamic pages —a product, a project or a blog post— generateMetadata lets you build that data from the content.

In current versions of Next.js, some dynamic metadata can be streamed. Next.js documents that Googlebot reads that metadata after rendering, and handles bots that need to find it directly in the <head> differently.

I wouldn't treat that as an excuse to stop checking what each URL actually ends up generating.

Canonicals: consistency, not a patch for any URL

A canonical tells search engines which URL you prefer within a set of duplicate or very similar pages.

On a typical website I'd check that:

  • main pages have a consistent canonical;
  • the sitemap, internal links and canonical don't contradict each other;
  • genuinely duplicate variants point to the right destination;
  • internal links go directly to the URL you want to keep.

I wouldn't use canonicals as a fix for every indexing problem.

A filter, a combination of parameters and pagination aren't automatically the same case.

In fact, Google recommends not using the first page of a paginated sequence as the canonical for the rest, and giving each page its own canonical URL instead.

Before pointing a canonical at another URL, the question is:

do these two pages really represent the same content, or something very close to it?

Hreflang: connecting the versions that actually exist

On a multilingual website I'd check:

  • that each language declares its corresponding versions;
  • that the links are reciprocal;
  • that each page also includes itself;
  • that language and region codes are valid;
  • that the declared URLs are fully qualified, including the domain;
  • that no declared URL ends in a 404 or a redirect;
  • and that a translated slug points to its real equivalent, not just the same path with a different prefix.

Next.js lets you do this with alternates.languages.

It can also include alternates in the sitemap.

You don't need to use every method at once: Google treats them as equivalent.

What matters is that the set of URLs is correct and easy to maintain.

If you have a default version for languages you don't cover, you can also declare x-default.

Sitemap, robots and indexability are different things

A sitemap should list the URLs you actually want to present to search engines.

I wouldn't include:

  • redirects;
  • 404s;
  • drafts;
  • pages that deliberately carry noindex;
  • duplicate variants you don't want to keep.

Next.js can generate sitemap.ts and robots.ts, but having those files doesn't mean they're set up correctly.

It's also worth keeping the concepts apart.

robots.txt mainly controls crawling.

noindex tells search engines a page shouldn't appear in results.

And a genuinely private area needs authentication or access control: noindex doesn't turn a public URL into a private one.

Redirects and errors: make the HTTP response tell the truth

When a URL changes, the old one should lead straight to the new one.

Not A → B → C.

A → C.

With permanent redirects in next.config (permanent: true), Next.js currently uses a 308. If you need a different code in a specific case, you can set it with statusCode.

If a resource simply doesn't exist and has no replacement, returning a real 404 is the right answer.

In dynamic routes, notFound() lets you handle that case without ending up with an error page that returns a 200.

I'd also check that no internal links still go through redirects once a migration is finished.

Google can run JavaScript. That doesn't mean anything goes

Googlebot renders JavaScript.

So a website doesn't stop being indexable just because it uses Client Components or content generated with JS.

Even so, Google still considers server-side rendering and prerendering good options, because they improve the experience for users and crawlers, and not every bot runs JavaScript.

The practical check is simpler:

does the content you want indexed end up accessible without relying on a human action the crawler won't take?

An accordion isn't a problem if the content is part of the page.

But if the only way to get important information is to press a button that fires off a request afterwards, I wouldn't assume a crawler will follow that path. Google says so explicitly: its crawlers don't click buttons and generally don't trigger functions that require a user action.

The same goes for links.

If a URL matters, it should be discoverable through a real link with an href, not only through a click handler.

Structured data: only when it describes what's really there

Not every page needs its own schema.

I'd use JSON-LD when there's a useful type that represents the visible content:

  • Organization or LocalBusiness;
  • BlogPosting;
  • BreadcrumbList;
  • Product;
  • or other types that genuinely apply.

The markup should match what a person sees.

And passing the Rich Results Test means the implementation is valid for that check, not that Google will necessarily show a rich result.

Next.js recommends adding JSON-LD with a plain <script type="application/ld+json">.

If the object includes external or user-generated content, those values also need to be handled safely before being serialised.

Images and performance

next/image handles many common cases very well:

  • responsive sizes;
  • lazy loading by default;
  • reserving space;
  • format and size optimisation.

But it isn't a rule of "every image must use next/image" either.

For images that are part of the content, it usually makes a lot of sense.

For main images, I'd check in particular that you're not delaying whichever element ends up as the LCP.

In Next.js 16, priority was deprecated. There's preload, loading="eager" and fetchPriority, and the right choice depends on the case; the documentation itself usually recommends eager or fetchPriority="high" over preloading when it isn't needed.

I'd also check:

  • useful alt text on images with content;
  • alt="" on purely decorative ones;
  • correct dimensions or aspect ratio;
  • sizes where a responsive image needs it;
  • third-party scripts;
  • fonts;
  • and real-world Core Web Vitals.

Not to hit 100.

To stop a technical decision from turning a simple page into something unnecessarily heavy.

If you want to get into the metrics, we cover them separately in Core Web Vitals.

After launch

Before calling a website finished, I'd check:

  1. Search Console is set up.
  2. The sitemap is accessible and submitted.
  3. Important pages are crawlable and indexable.
  4. Canonical and hreflang come out as expected.
  5. Redirects and 404s respond with the right status.
  6. No internal links are broken or going through redirects unnecessarily.
  7. Important structured data validates.
  8. The website works just as well on mobile and desktop.

Then comes the part no checklist can solve: whether we've built the pages we actually needed.

You can have flawless technical implementation and a structure that doesn't answer any useful search.

That's why technical SEO is a foundation, not the whole strategy.

If you need to work on both from the start, that's what we plan in Web + SEO.

Roke StudioWeb · SEO · Software

We write about decisions that come up in real projects: how to structure a website, how to capture demand and when technology can simplify a business.

Web + SEO

Want your website to do this work?

We study what your customers search for, how the website should be structured and what has to happen to turn that visibility into opportunities.

See Web + SEO ↗