I wasn’t trying to do anything particularly clever or experimental — I was simply trying to increase my Google AdSense revenue on a few content-heavy websites I run, most of which are built with modern frameworks like Next.js and optimized heavily for SEO, performance, and long-tail traffic acquisition.
These sites include small but very real projects like markkit.dev, a developer-focused tool site, and whatstype.org, a personality and test-based content website, both of which rely heavily on internal navigation and indexed subpages to generate traffic and revenue.
No viral growth tricks. No redesign. No traffic spikes.
Just the assumption that if ads were configured correctly, they should load consistently on every page.
That assumption turned out to be wrong.
The First Symptom: Ads Missing on Pages That “Should” Work
At first, everything looked fine.
On the homepage, ads loaded exactly as expected, and on some articles and landing pages everything appeared completely normal.
But on other pages — often deep-linked SEO pages reached through internal navigation on sites like markkit.dev and whatstype.org — ads simply didn’t show up at all, despite the content being indexed, receiving traffic, and meeting all AdSense policy requirements.
There were no layout shifts, no obvious broken elements, and no warnings inside the AdSense dashboard itself, which made the issue even more confusing.
These pages were real, production pages with users and pageviews — the kind of pages that should have been earning money.
So I opened DevTools.
Two Types of Errors That Didn’t Point to an Obvious Cause
What I found was inconsistent, but repeatable.
1. A Console Error That Didn’t Fully Explain the Problem
On some pages, the console showed:
Error: no_div
at adsbygoogle.js
This error implies that AdSense failed to find the expected <ins class="adsbygoogle"> container, even though the element was clearly rendered in the DOM when inspected manually.
That immediately suggested a timing or lifecycle issue, not a missing element.
2. Ad Requests Marked as “Canceled”
On other pages, there was no JavaScript error at all.
Instead, in the Network tab, several AdSense-related requests appeared briefly and then ended with a status of canceled, which usually indicates that the browser terminated the request before it could complete.
No 4xx errors. No 5xx errors. No retries.
Just silent failure.
At this point, it was clear that AdSense itself wasn’t broken — something in my application flow was interfering with it.
The Common Factor: Client-Side Navigation in Next.js
All of these sites are built with Next.js (App Router), and like most modern Next.js projects, internal navigation relies heavily on client-side routing via next/link, which is great for perceived performance but introduces a more complex and less predictable page lifecycle.
This works beautifully for UX:
- Faster transitions
- No full page reloads
- Better Core Web Vitals
But AdSense doesn’t really behave like a modern SPA-friendly script.
What AdSense Still Assumes About the Web
After digging through old GitHub issues, forum threads, and my own experiments, one thing became increasingly clear:
Google AdSense still implicitly assumes a traditional, full page load navigation model.
It expects:
- A complete page lifecycle
- A stable DOM that doesn’t get torn down mid-initialization
- No interrupted network requests during setup
Client-side navigation breaks those assumptions in subtle ways — and when it does, AdSense doesn’t always fail loudly.
Sometimes it just doesn’t render.
The Test That Felt Wrong (But Worked)
As an experiment, I replaced some internal links — especially those leading to high-traffic content pages — from next/link to plain HTML anchor tags.
From this:
<Link href="/article/seo-tips">Read more</Link>
To this:
<a href="/article/seo-tips">Read more</a>
This change forces a full page reload, which goes against most modern Next.js best practices and slightly slows down navigation, but it also restores a predictable and complete page lifecycle.
After deploying this change:
- Ads began loading consistently on all pages
no_diverrors disappeared entirely- Previously canceled AdSense requests completed normally
- Ad impressions and revenue increased noticeably over the following days
The Trade-Off I Accepted
Yes, this approach has downsides:
- Slower navigation
- Less “SPA-like” behavior
- Slightly worse Lighthouse performance scores
But in practice, a site that is marginally slower and consistently monetized performs better than a fast site that silently fails to show ads.
Final Thought
Next.js optimizes aggressively for developer experience and performance.
Google AdSense optimizes for a web model that still assumes full page loads.
When those two worlds collide, the failure mode is rarely obvious — you don’t always get a clear error message.
Sometimes, you just get less revenue.
And that’s the hardest bug to notice.
