Skip to content
Back to Blog
SEONext.jsGoogle Analyticstechnical SEOlessons learnedNext.js SEO mistakeswebsite not showing up on google

We Built 3 Websites. None of Them Ranked.

Joshua R. Gutierrez9 min read

We launched three products. Three websites, all built on Next.js, all statically exported, all described in our own internal notes as optimized for SEO. None of them ranked. Here is what was actually wrong, what we fixed, what we got wrong about why, and the part that took us longest to accept.

1. Our entire site was invisible to crawlers

Next.js has a file called loading.tsx. Drop it into the app directory and it shows a loading state while the page hydrates. It also wraps all page content in a Suspense boundary in the static HTML export.

The consequence was that the HTML we shipped contained a spinner and not much else. Homepage, service pages, blog posts, all of them. We spent days on heading hierarchy, anchor text, and meta descriptions while the crawlable HTML was empty.

The fix was deleting one file. The lesson is that we should never have been reading our source code to answer a question about our output. We now build the site, open the generated HTML, count the words, and check for the spinner before anything ships.

2. Analytics reported a healthy tag and collected nothing

Google's tag assistant told us the tag was installed. Two weeks later we had zero events. Not low traffic. Zero.

The cause was Google Consent Mode v2. Our cookie banner defaulted analytics_storage to denied and only granted it when someone clicked Accept. Most people click nothing.

The tag test checks whether the script is present. It does not check whether consent mode is suppressing collection. We fixed the default, and we now open the Realtime report after every deploy instead of trusting a green checkmark. We are not lawyers and consent obligations depend on where your users are, so get that part right on its own terms. The measurement lesson stands regardless: a tag that loads is not a tag that reports.

3. Five H1 tags, and we were wrong about why that mattered

Our homepage had an H1 in a server-rendered article, another in a client component, and more inside service cards. Our own audit tool flagged it as an error, and this post originally said Google would not know which heading mattered.

That claim was wrong and we have since corrected the tool. Multiple H1 tags are not an SEO failure. Google has said as much. Our rule was too strict, it was inflating the error count on our own reports, and it is now a warning.

There was a real problem underneath, and it was duller than the one we invented: our headings did not describe the page. The document structure was an accident of how the components were assembled rather than a description of the content. Fixing that is worth doing because it makes the page comprehensible to a person using a screen reader, and because it forced us to decide what each page was actually about.

4. Every link on the site said "Learn more"

Twelve service cards, twelve identical anchors, twelve different destinations. Anchor text is one of the ways a link describes its target, so we replaced them with anchors that name the destination. It took twenty minutes.

We cannot show you that it moved a ranking. We can tell you the site is easier to use, and that we no longer have twelve links claiming to be about nothing in particular.

5. Client components erased our server-rendered content

A single usePathname() call turns a component into a client component. Ours were client components for no better reason than highlighting the active nav item, and that pulled our content shell and footer out of the static HTML.

We moved the pathname logic into a small client child and left the parents on the server. The HTML then contained content instead of empty divs waiting for hydration.

This is the same failure as number one, wearing a different hat, and it is the one we now check for first on any React site. It is also the failure we later went and measured across other people's sites: of 368 business websites we analyzed, 92 lost at least one answer-critical element between the rendered page and the raw HTML. We did not find that pattern because we are clever. We found it because we shipped it.

6. Our privacy page listed the wrong analytics ID

We changed Google Analytics properties and updated the tag, but the measurement ID was also hardcoded in the text of our privacy policy. Anyone checking what we track would have found a different ID than the one running.

Not an SEO issue. It is a document claiming something untrue about our own site, on the page whose entire job is being accurate.

7. Our sitemap dates were fiction

Our sitemap generated lastmod values with new Date() at build time, on a CI server with a clock that was slightly off, which meant the dates described a build, not a change to the content. Google treats lastmod as a hint and ignores it when it looks unreliable, which ours did. We hardcoded real dates. We do not claim this changed anything. We would rather our sitemap not assert things that are false.

8. Seventy-eight images with no metadata

Compressed, WebP, correctly sized, and carrying no IPTC or XMP fields at all. We wrote exiftool scripts and tagged all seventy-eight with titles, descriptions, keywords, author, and copyright. It took an hour.

Honest accounting: image metadata has documented uses in image licensing and it establishes provenance if someone reuses your work. We added it for those reasons. We cannot show that it changed a ranking, and we are not going to imply that it did.

9. The old brand name was still in five places

We built from a template and rebranded. Five instances of the old name survived, along with two old email addresses and a hero section still carrying template copy, all of it hiding in secondary pages, JSON-LD, and error states. Find and replace across the whole codebase, then do it again.

The part that took longest to accept

We fixed all of it. One of the three sites now scores 98 on Lighthouse. It generated no leads.

A technically clean site does not rank on being clean. Nothing on the list above creates demand for what you sell, provides evidence that you can do the work, or gets your name in front of anyone. Our three sites had none of those three things. They were correct and unwanted, and correctness is not a substitute.

What the list above does is remove the reasons a page cannot compete. Crawlability, content that exists in the HTML, accurate data, comprehensible structure. Get them wrong and nothing else you do can work. Get them right and you have earned the ability to start, which is not the same as having started.

Where we are now: the technical failures are fixed and documented, and the slower work of having something worth finding is still in front of us. We built DeepAudit to catch the mistakes in this post, because we made every one of them. It will find them on your site in about sixty seconds, free, without an email address. It will not tell you whether anyone wants what you sell. We had to learn that part the other way.

Joshua R. Gutierrez, SEO Engineer, Axion Deep Digital

Written by

Joshua R. Gutierrez

SEO Engineer, Axion Deep Digital

SEO strategist and full-stack engineer who builds the audit tooling, then does the work. Technical SEO, Core Web Vitals, and content systems for SaaS and B2B.

View full profile & credentials →

Ready to build a website that performs?

Let us audit your current site, identify the biggest opportunities, and build a plan to grow your traffic and leads.