Skip to content

Technical SEO

Technical SEO for Next.js

Crawlability, canonicals, hreflang and structured data built into the render path - generated from one source of truth instead of maintained by hand.

Technical SEO in a Next.js application is not a plugin. It is a property of how the application renders, and it fails in ways that are invisible from the browser: a canonical tag that points at the wrong locale, an hreflang cluster that advertises translations that do not exist, a sitemap generated from a different list of routes than the router actually serves.

None of that shows up in a page that looks correct when you open it. It shows up months later as two URLs splitting one page's rankings, or a locale that was never indexed at all.

What we audit

  • Crawl and render. What the crawler receives in the initial HTML versus what appears after hydration, and which of your content only exists in the second one.
  • Canonicalisation. Trailing slashes, query parameter handling, pagination, and whether every route agrees with itself about its own address.
  • International routing. The full hreflang cluster, including x-default, validated against the translations that actually exist rather than the ones that were planned.
  • Structured data. A connected @graph with stable @id references, not four disconnected blobs that each re-declare the organisation.
  • Sitemaps and robots. Generated from the same route source the application renders from, so the two cannot drift.

The five faults we find most often

A canonical that was never written. generateMetadata is optional, so a route without one inherits nothing and Google chooses an address for you - often the one with a tracking parameter attached.

Two URLs that both answer. /about and /about/, or a locale served at both /en/about and /about. Both return 200, both get indexed, and the page's authority is divided between them. The fix is a redirect, not a canonical, and the difference matters.

hreflang that advertises a translation nobody wrote. A locale list in a config file generates the alternates, so every page claims four languages while only two exist. Google follows the tag, finds the wrong language or a 404, and discounts the cluster. The rules, in detail.

A sitemap built from a second list of routes. Maintained by hand, or generated from a directory scan that does not know about route groups. It drifts within one sprint and then quietly misreports every date.

Structured data that describes nothing. Four separate JSON-LD blocks, each declaring its own Organization, none of them referring to each other. Valid JSON, no graph, and nothing for a search engine to resolve into an entity. What a connected graph looks like.

How we fix it

By making it impossible to get wrong. Canonicals, alternates and structured data get generated from a single typed helper that every route must call. A page cannot ship without a canonical, because the metadata function will not compile without one.

That is the whole method, and it is worth stating plainly because it is the opposite of how most technical SEO is delivered. A findings document that lists forty issues gets forty fixes, and then the forty-first page ships without a canonical because the list was a snapshot and nobody re-ran it. A generated canonical cannot be omitted on the next page, because there is no code path that produces a page without one.

The same applies to the sitemap and the feed: both are derived from the route source the application renders from, so a new page appears in them because it exists, not because somebody remembered. And hreflang is generated from the translations present on disk, so deleting a translation removes its tag on the next build rather than leaving a claim behind.

Where generation is not possible, the check moves into CI instead. This site fetches every URL in its own sitemap on every push and fails the build on a missing, duplicated or mismatched canonical, on a page absent from its own hreflang cluster, and on a duplicate URL form that answers instead of redirecting. The reasoning behind that check.

This site is built that way, and the implementation is public - the buildMetadata helper and the JSON-LD graph in this repository are the same pattern we deploy for clients.

Multilingual, which is where it usually breaks

A single-language site has one way to get canonicalisation wrong. A four-language site has the locale prefix, the default locale served without one, the x-default target, the translation that exists in two languages but is claimed in four, and a language switcher built from a <select> that a crawler cannot follow to any of them.

We treat the locale list, the prefix rule and the translation inventory as one source that metadata, the sitemap and the switcher all read from. The architecture that produces is the difference between a site with four locales and a site with one locale and three orphans.

What we do not do

Not content strategy, not keyword research, not link acquisition. This is the engineering floor those things stand on, and a team that sells you all four at once is usually strong at one of them.

We will tell you when the technical work is not your constraint. If your pages are indexed correctly, resolve cleanly and validate, and the traffic still is not there, the answer is in the content and we will say so rather than invoicing for a second audit.

How an engagement runs

A fixed read first - crawl, render comparison, canonical and hreflang validation across every route template, structured data validation, and log analysis where server logs are available. That produces a findings document ranked by impact with each item traced to the code that causes it.

Then the fixes, as pull requests in your repository, in that order. Then the checks that keep them: generation where the fault was a missing value, CI assertions where generation is not possible.

If you only want the first part, the findings document stands on its own and several clients have implemented it themselves. That is a reasonable outcome and the audit is the engagement for it.

The measurable outcome

Correct indexation of the routes you want indexed, and nothing else. Rich results where the schema supports them. An hreflang cluster that Search Console validates without warnings. These are not growth hacks; they are the floor a content strategy stands on.

What you receive

The findings ordered by what they cost you, the fixes as pull requests, and the checks that stop them returning. Canonical and sitemap derived from one source, hreflang read from the files instead of a list, and a crawl in CI that fails on a linked 404.

Plus the before and after: pages indexed, the ones Search Console was refusing and the reason it gave, and what changed once the fix had time to be recrawled. That last number arrives weeks after the work and we send it anyway.

Scope and terms

Engagement model
Fixed scope, agreed in writing before work starts. Not a day rate against an open backlog.
Price and timeline
Both are set per project, once the scope is. Quoted together, before anything is built.
What we need from you
One person who can approve decisions, and access to your repository and issue tracker.
Not included
Anything outside the agreed scope. It becomes its own scope rather than a variation order.
Third-party costs
Hosting, licences, API fees and SaaS subscriptions are contracted and paid by you.
Invoicing
Codefacture Yazılım A.Ş., Türkiye. EUR, USD or GBP by bank transfer, with no Turkish VAT on exported services.

Frequently asked questions

Is this content marketing?
No. This is the engineering half of SEO - what the crawler receives, how routes resolve, whether your canonicals agree with your sitemap, whether your structured data validates. We work alongside your content team, not instead of it.
Our pages render client-side. Is that a problem?
Usually yes, though rarely fatally. Google renders JavaScript, but on a delay and with a budget, and other crawlers are far less capable. Moving critical content and metadata into the server render is typically the highest-leverage change available.
Do you handle multilingual sites?
Yes, and it is where most Next.js implementations break. Partial translations pointed at by hreflang, x-default omitted, canonical URLs disagreeing with the locale prefix - we fix the generation rather than the symptoms.
How long before we see a change in rankings?
Indexation changes are usually visible within weeks; ranking changes are not ours alone to promise. What we can state precisely is the technical outcome: which URLs are indexable, which canonicals resolve correctly, which structured data validates. If your content deserves to rank and a technical fault is preventing it, fixing the fault is what allows the content to work - it is not a substitute for it.
Do you do link building?
No, and we would be suspicious of a technical team that did. They are separate disciplines with separate risks, and bundling them usually means one of them is being done badly.
Can you work with our existing agency?
Yes. The common split is that they own strategy, keywords and content, and we own what the crawler receives. That works well as long as one document says which decisions belong to whom - we write it at the start if nobody has.
Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page