DEV Community

Cover image for I Gave My SEO Agent a Real Site. It Found Bugs I'd Missed for Weeks.
Daniel Nwaneri
Daniel Nwaneri

Posted on

I Gave My SEO Agent a Real Site. It Found Bugs I'd Missed for Weeks.

does twitch pay nigerians — position 9.5 in Google Search Console, 29 impressions, 0 clicks.

Position 9.5 is close. One honest title rewrite from page one. But the CTR was 0. Nothing. The title Google was showing users didn't match the query at all.

I'd built that page myself. I just couldn't see it until the tool told me.

That's the thing about auditing your own content. You know what you meant. The tool only knows what's there.


What the agent was before

I've written about this SEO agent on FCC and dev.to over the past few months. The baseline version: scrape a URL, check title length, meta description, H1 match, keyword density, Core Web Vitals, schema markup. Standard on-page audit. Useful. Not smart.

It told you what was there. Didn't tell you what was costing you rankings.

Four modules later, it does.

Backlink Qualifier — scores referring domains on niche relevance (0–100), traffic quality (0–100), spam score (0–100, inverted). Weighted average: niche * 0.50 + traffic * 0.30 - spam * 0.20. Tiers: Insert Worthy ≥80, Good ≥60, Review ≥40, Avoid <40. Takes a list of backlink URLs, fetches each one via the real browser, sends summaries to Claude Haiku for scoring. Resumable — cached to a flat JSON file so a crash at URL 47 doesn't restart from zero.

GSC Insights — parses a Google Search Console export CSV, deterministically flags quick wins (position 4–20, impressions ≥50, CTR <5%), then sends the top 50 rows to Haiku for cannibalisation detection and cluster gap analysis. The prompt asks specifically for queries where two pages are competing. That's the one you can't see just by sorting the spreadsheet.

Relevance Scorer — given a target page and a list of candidates, scores each as a potential internal link source: topical alignment (0–100), anchor opportunity (0–100), link equity (0–100). Same weighted approach. Tiers: Strong Link ≥75, Good Link ≥55, Weak Link ≥35, Skip <35. Before scoring, it checks whether the candidate already links to the target — deterministically, from the raw links in the page snapshot — so it never recommends a link that already exists.

Cluster Audit — builds a full internal link graph across the site, computes incoming link counts per page, then sends the whole picture to Haiku to map topic clusters, identify orphan pages, flag missing hub pages, and suggest cross-cluster links.

All four: Claude Haiku for cost efficiency, flat JSON for resumable state, markdown reports in the project directory.

The code is on GitHub. The prompts are in /prompts. The modules are in /modules. dannwaneri.com/seo-automation has the links.


naija-vpn.com — what the agent found

I run a small site for Nigerian creators trying to get paid internationally. Five pages at the time of the audit: homepage, Cleva vs Geegpay comparison, Twitch payments Nigeria guide, Carter Efe case study, Data Saver app landing page.

I'd built these pages, deployed them to Cloudflare Pages, checked them manually. They looked fine.

GSC Insights found this:

does twitch pay nigerians — 29 impressions, position 9.5, 0% CTR.

The Twitch guide page was ranking for that exact query. But the title was: "How to Receive Twitch Payments in Nigeria (2026 Guide)"

Nobody types "how to receive twitch payments." They type "does twitch pay nigerians" — the doubt query, the "wait, is this even possible?" moment. The title was answering a question nobody asked.

The fix was a one-line change: "Does Twitch Pay Nigerians? Yes — Here's Exactly How (2026)"

That's the query, with the answer embedded. A user scanning results at position 9.5 now sees confirmation in the title itself.

GSC Insights also found this:

cleva vs geegpay — position 5.25, also 0% CTR.

The comparison page title was: "Cleva vs Geegpay: Best Choice for Nigerian Creators?"

Ending a title with a question when the user is asking a decision query creates friction. They're not looking for a question. They're looking for someone who already did the test. New title: "Cleva vs Geegpay: Which Is Better for Nigerian Freelancers?" Plus a description that actually answers it: "We tested both. Cleva wins for direct bank wires, Geegpay for Upwork/Fiverr. Full fee breakdown, transfer speeds, and which to use based on how your clients pay."

Then the cannibalisation.

The Carter Efe case study — a page about how Africa's highest-earning Twitch streamer receives his payments in Nigeria — had this title: "NaijaVPN - Get Paid Internationally in Nigeria"

That's the homepage title. Copy-pasted verbatim.

Google was indexing two pages with identical titles and descriptions. When it can't distinguish between two pages, it picks one and effectively buries the other. The case study was fighting the homepage for clicks on the same queries — and losing.

New title: "How Carter Efe Gets Paid from Twitch in Nigeria ($50K/Month)". The $50K/Month is in the GSC data, it's real, and it makes the page about one specific person instead of a generic payment guide.

The Relevance Scorer found two missing internal links.

The Carter Efe page never linked to the Cleva vs Geegpay comparison — even though it spent three paragraphs naming both services. The Twitch guide had the same gap. Both pages were talking about a comparison that existed on the same site and never pointing to it.

The scorer flagged both as Strong Link (≥75). Both links added.

The Cluster Audit found an orphan.

The Data Saver app page — /data-saver — had zero internal links pointing to it. Not from the homepage. Not from any other page. It existed as a standalone page with no connection to anything else on the site.

The report flagged a missing hub: "How to Save Mobile Data on Nigerian Networks: Tools, Tips & Strategies" at /save-mobile-data-nigeria. That hub connects the Data Saver app to the broader Nigerian mobile user context, and cross-links to the payment content where data usage overlaps. I built it the same week. The audit told me exactly what to build next — I didn't have to guess.


What changed after

Three title rewrites. Two internal links added. One orphan fixed — the hub page built and linked. Deployed to Cloudflare Pages.

The position 9.5 query has 21 days to show movement before the reindex settles. I'm checking on 2026-05-25.

What I have now: a site that was structurally broken in ways I couldn't see manually. A page cannibalising its own homepage. A ranking query with no matching title. Two pages talking about a comparison they never linked to. One completely isolated page with no internal path to it.

None of these showed up in the basic on-page audit. They're not "is your title too long" problems. They're structural — the site was working against itself at the architecture level.


The actual point

I didn't build these modules because I needed them for a single site.

I built them because I offer SEO as a service. The basic auditor told clients what was there. These tell clients what's costing them.

The difference is whether the tool earns the conversation. A checklist of "your meta description is 143 characters" doesn't. "You're at position 9.5 on a high-intent query with 0% CTR because your title doesn't answer the question" does.

The code is open source because the tool is the delivery mechanism, not the product. The product is the analysis. Someone can clone this and run it — but knowing which findings matter, what to fix first, and how to communicate that to a client who doesn't know what cannibalisation means is where the service is.

That gap doesn't shrink when you open-source the code.

It widens.


All four modules are open source. Full implementation details and the service page are at dannwaneri.com/seo-automation. If you want the agent run on your site and a prioritised fix list delivered, that's available too.

Top comments (2)

Collapse
 
leob profile image
leob

Expert stuff - I didn't realize that SEO is this "deep" and subtle ...

Collapse
 
dannwaneri profile image
Daniel Nwaneri

The subtle part is that most of it is invisible until something external names it . you know what you meant, so you see what you meant.