Postmortem

We Deindexed Our Own Site With One Line of Code

One line in the wrong file told Google that every page on this site was really the homepage. Google believed us.

· 6 min read

We build an app for reading Google Search Console. So there is a particular flavour of embarrassment in opening our own Search Console and finding that Google had indexed exactly one page of our website.

Not one page *this week*. One page, total. The Coverage report listed the rest under a status that sounds almost reassuring if you do not know what it means: Alternate page with proper canonical tag.

What that status actually means

It means Google found the page, read its canonical tag, saw that the tag pointed at a *different* URL, and concluded the page was a duplicate of that other URL. So it did not index it. That is not a bug in Google. That is Google doing exactly what it was told.

The word proper in the status name is the tell. Google is not complaining. It is saying: *your canonical tag was valid, we followed it, here we are.* The report reads like a status update because from Google's side, that is all it is.

The line

Here is the offending code, in src/app/layout.tsx:

export const metadata: Metadata = {
  metadataBase: new URL("https://googlesearchconsole.app"),
  title: "Search Console Mobile App",
  // ...
  alternates: {
    canonical: "/",   // <- this one
  },
};

It looks harmless. It looks, honestly, like good practice — you are supposed to set a canonical URL, and the homepage's canonical is /. Every SEO checklist tells you to do this.

The problem is the file it is in. layout.tsx is the root layout, and in the Next.js App Router, metadata declared in a layout is inherited by every route beneath it. Any page that does not explicitly override alternates.canonical gets the parent's value.

So /privacy-policy rendered this:

<link rel="canonical" href="https://googlesearchconsole.app/"/>

Which, in plain English, is that page saying: *I am not the real page. The homepage is the real version of me. Please index that instead.*

Every page on the site said this. Every page said it about the same URL. Google, quite reasonably, indexed the homepage and dropped the rest.

Why it took us so long to notice

Because nothing broke. That is the whole point, and it is why this class of bug is worth writing about.

  • The build passed. It is valid code producing a valid tag.
  • The pages worked. You could visit them. They rendered. They looked fine.
  • Nothing appeared in analytics — because pages that are not indexed generate no search traffic, and a page with no traffic is indistinguishable from a page nobody happened to visit.
  • No error, anywhere. Google does not email you to say it has stopped indexing your site. It just quietly stops.

That is the shape of nearly every serious SEO bug: it is invisible in every tool you normally look at, and visible in exactly one place — the Page indexing report. Which is precisely why we keep telling people to check it weekly, and precisely why we then went eight weeks without checking our own.

The fix

Remove it from the root layout. Set it per-page instead:

// src/app/page.tsx
export const metadata: Metadata = {
  alternates: { canonical: "/" },
};

// src/app/privacy-policy/page.tsx
export const metadata: Metadata = {
  alternates: { canonical: "/privacy-policy" },
};

Tedious, and there is no clever abstraction that makes it safe to centralize — the tediousness *is* the safety. Every page states its own identity, and no page can accidentally speak for another.

Check yours in ten seconds

Pick any page on your site that is not the homepage, and run:

curl -s https://yoursite.com/some-page | grep -i canonical

The href should be that page's own URL. If it is your homepage, or if it is missing entirely while your homepage has one, you have this bug, and you have had it for as long as that code has been deployed.

What it cost

Not much, in our case, because the site was young and had little to lose. On an established site the same line would be genuinely expensive: pages drop out of the index over weeks, not hours, so you lose traffic gradually enough that it looks like a slow season rather than a bug. By the time it is obvious, you have lost months — and recovery is not instant either, because Google has to re-crawl everything to learn you have changed your mind.

The general lesson is not about canonical tags. It is that SEO bugs do not announce themselves. They pass CI, they render fine, they throw nothing, and the only place they surface is a report most people open twice a year. Open it more often than that. We are taking our own advice now.

Referenced guides

Keep reading