
How to Tell If Your Developer Broke Your SEO: The 2026 Guide
Published: October 29, 2026
The call usually comes two or three months after a launch. The site looks better than the old one. The owner has watched the enquiries thin out, opened Search Console once, seen a wall of red and closed the tab. The question is always the same: did the developer break it?
Most of the time the answer is in that report, in a place nobody explained. On a local plumbing site I audited this month, Google knew about 23 URLs and had indexed 11. The other 12 sat in three buckets, ten of them marked "Discovered, currently not indexed" with no crawl date at all. The site had been live for months.
These are the seven checks I run before I quote a rescue. You can run them on your own property in an afternoon, with a laptop and read access to Search Console. By check six you will know whether the problem sits in the code, in the copy, or in something that was never the developer's job.
Check 1: ask the site who it is, four times
A site has four addresses whether or not anyone planned it: http, https, with www and without.
curl -I http://example.com/
curl -I https://example.com/
curl -I http://www.example.com/
curl -I https://www.example.com/Correct output: three of them answer 301 with a Location header pointing at the fourth, and the fourth answers 200 with strict-transport-security present. That is one address with three redirects in front of it.
Broken output: all four answer 200 with the same HTML. Google crawls what it finds, sees four copies of the homepage and picks one for you. Its choice appears in the report as "Alternate page with proper canonical tag", which sounds harmless until you notice the same service page competing with itself under two protocols.
On the plumbing site the plain HTTP homepage answered 200 while every page carried a canonical pointing at HTTPS. Google crawled the HTTP version, followed the canonical, filed the page as an alternate and moved on. Two service pages had already been indexed under http://, so they were fighting their own HTTPS twins for the same query.
The fix belongs at the edge, in a redirect rule. On Cloudflare it took about ten minutes. No application code changed.
Check 2: open the page indexing report and count buckets
Search Console, Indexing, Pages. Ignore the graph. Read the two lists, Indexed and Not indexed, and which bucket each URL landed in.
Four buckets describe work a developer should have done:
- Alternate page with proper canonical tag. Two URLs, one page. Usually a protocol or host duplicate from check 1.
- Discovered, currently not indexed. Google knows the URL exists and has never fetched it. There is no real crawl path into it.
- Crawled, currently not indexed. Google fetched the page and chose not to keep it. Thin copy and near-duplicates end up here.
- Soft 404. The page returns 200 and shows nothing useful.
One more bucket means a decision: Excluded by noindex tag. A staging configuration shipped to production, or a plugin that noindexes everything by default.
Two numbers together tell you the size of the problem: URLs Google knows about, and URLs it indexed. On the plumbing site that was 23 against 11.
One caution about reading the other direction: indexed does not mean ranked. Search Console's own help text says a page can be indexed and still not appear in results, because results depend on the query, the location and the user. Use this report to answer the developer question. Use the Performance report to answer the ranking question.
Check 3: does your text exist without JavaScript?
Take a sentence you can see on the homepage, then fetch the raw HTML and search for it:
curl -s https://example.com/ | grep -o "your sentence here"No output means the words arrive only after a JavaScript render. Google can render JavaScript, and it does that on a second pass with its own queue and its own budget. When the second pass is slow or never happens, you have a page with a title and no content. That is a code architecture problem, and it usually comes from a starter template where every component runs on the client.
I have seen the extreme version of this: a site live for months where every page served an empty shell, with no metadata, no sitemap and no canonical tags. I wrote about that takeover in I Took Over a Project After a Vibe Coder. The ten-second version is this check.
Check 4: one canonical and one title per page
View the source of three different page types, not one. You are looking for two lines in each:
<link rel="canonical" href="https://example.com/services/drain-cleaning">
<title>Drain Cleaning in Your City | Company Name</title>The canonical should be the page's own address, with the full origin and no query string. The title should be specific to that page.
Common failures:
- No canonical at all. In Next.js that usually means
metadataBasewas never set, so relative canonical values cannot resolve to an absolute URL. - Every page canonicalising to the homepage. A template default nobody checked. It tells Google that all 20 pages are copies of the homepage.
- The same title on every page. Usually the starter template's title, left in place for two years.
This check catches more inherited damage than any paid tool.
Check 5: read the sitemap like a developer
Open /sitemap.xml and read the first twenty lines as text.
Google wants fully qualified absolute URLs, and it will crawl exactly what you list. It ignores <changefreq> and <priority> completely. It uses <lastmod> only when the value matches real page changes, which its documentation states plainly:
Google uses the
<lastmod>value if it's consistently and verifiably (for example by comparing to the last modification of the page) accurate.
Three patterns in that file show up on most sites:
<loc>without a scheme, built from a request header. Google cannot use those entries.- A request-time date, as in
lastmod: new Date(). Every crawl sees every page as changed seconds ago. After the second crawl Google stops trusting the value for that site. - Duplicates, typically
/homelisted next to/, or the same service under two slugs.
The plumbing sitemap had two of the three. Fixing it took an hour, and the dates now come from the CMS _updatedAt field, which is a real edit timestamp. If the site runs on Sanity, that is the field to use, and the setup is the same one I described in What Is a Headless CMS?.
Check 6: count the clicks to your most profitable page
Start at the homepage. How many clicks and how many separate paths reach your best service page?
On the plumbing site the answer was one path, from the homepage, listed once. Each service page linked back to the homepage and to anchor links, never to another service. The services index returned 404, so seventeen pages had no parent.
Google crawled a sample, indexed nine of seventeen, then queued the rest. Its crawl budget documentation explains the mechanism. A budget is crawl capacity plus crawl demand, and the factor a site owner controls is inventory:
If many of these URLs are duplicates, or you don't want them crawled for some other reason, this wastes a lot of Google crawling time on your site.
Read that as permission to sample. Pages with one path in, pages that look like each other, get crawled first or not at all. The fix is a hub page that lists every service with a descriptive link, breadcrumbs on every service page and a related-services block linking sideways. Each page ends up with three or four paths. That was half a day of work, and it is the change that moved the site out of the "Discovered" queue.
Check 7: request a page that does not exist
Ask for a URL you know is wrong, for example /this-page-should-not-exist-9281.
The correct answer is 404. A common answer is 200 with an empty template. Google files that as a Soft 404, and in the worst case it indexes an empty page. In Next.js the cause is a dynamic route that renders a fallback instead of calling notFound().
While you are in the index report, look for URLs that should never be pages: favicon files, feed URLs, tag archives, staging subdomains. The plumbing site had a favicon variant in the Indexed list, which does nothing for rankings and is easy to silence with a response header. Watch where that header goes. If the site runs on Cloudflare Workers with OpenNext, the headers option in next.config never reaches static assets, because the worker does not sit in front of them. The framework's docs say so directly, and the fix is a header rule at the edge.
The plumbing site: five causes and the order I fixed them
The report said 23 known, 11 indexed. Five causes, each with a different price:
- Protocol duplicates. One edge redirect, ten minutes.
- No crawl path. Services index, breadcrumbs, related links, half a day.
- Sitemap signals. Absolute URLs and real dates, an hour.
- Soft 404s and junk.
notFound(), a/homeredirect, an English template post unpublished, an hour. - Interchangeable pages. 238 to 332 words, identical structure, four FAQs each, a similarity score of 0.34 between two different services. Days.
Order matters more than any single fix. The redirect goes first because it removes a whole duplicate set and closes a bucket without touching content. The crawl path goes second so Google has somewhere to go. Sitemap honesty goes third so a recrawl request means something. The copy goes last, because that is the only change that alters what Google reads.
I left the seven indexed pages untouched during this work. No new titles, no price edits, no body rewrites on pages that already worked. Change working pages in the same week and you lose the ability to read which fix did what.
The redirects deployed on 28 October. The report updates within days and a validation cycle runs about two weeks, sometimes longer. The eight thin service pages still need 600 to 800 words each with their own FAQs. Until that copy ships, the index count will not move, and no canonical tag will move it. Owners underestimate this part: a technical fix makes a site eligible, and the copy is what makes it worth crawling.
When it is not the developer
Run these before you hire anyone, including me.
- An algorithm update. Compare the drop date against Google's published update list. A cliff on a documented rollout date suggests the algorithm.
- Seasonality. Compare year over year, month over month lies. A plumber loses traffic in July because nobody thinks about heating.
- Business Profile problems. A suspended or re-categorised profile removes the map result while the site keeps ranking organically.
- Lost citations or a domain change. NAP mismatches and old links pointing at a dead URL hurt local results.
- A manual action. The Security and Manual Actions report states it in plain language.
- Content decay. Pages nobody updated for three years lose positions on their own.
- A tracking change. A consent banner or a tag rewrite can halve reported traffic while the phone keeps ringing.
A senior developer will tell you when the code is fine, because saying so costs them the job. Treat that as the first test of whether you are talking to one.
Six questions with answers that should worry you
- Which URLs are excluded and in which bucket? Worry at "SEO is not really my area". The report is free and public.
- Where is
metadataBaseset and what is the canonical strategy? Worry at silence, or at "Next.js handles that". - Where does sitemap
lastmodcome from? Worry at "it updates automatically". Ask what it updates from. - How many paths reach a service page from the homepage? Worry at "the menu links to everything". One menu link is one path.
- What does a missing URL return? Worry at "I think there is a 404 page". Ask them to test it while you watch.
- Paste me the four curl responses for http, https, www and non-www. Worry at never having seen them.
That last question is the cheapest interview in this business. Any developer who has worked on search visibility can produce those four responses in a minute.
What a fix costs
For a 20-page service site the technical layer is half a day to two days of work: redirects, canonicals, sitemap, 404 handling, a hub page and internal links. The copy is the expensive part, because it is writing, and a week of it is normal for eight to seventeen pages.
A monthly retainer does not add a hub page. If the first proposal you receive is a link-building package before anyone has read the four URL responses, the sequence is wrong and you will pay twice.
Run the checks before you book anything
Three pages and no services section? You need a services section, which is a build. A site with seventeen thin service pages stuck in the queue needs the copy and the crawl path together, roughly a week. A site on a closed platform will fail some of these checks for reasons nobody can fix from inside it.
Bring three things to any call: an export of the page indexing report, the four curl outputs and one service page address with the phrase it should rank for. Anyone competent will read those before quoting.
Conclusion
Seven checks, one afternoon and three possible answers. The code broke it, the copy was never good enough, or the drop has nothing to do with the site. Owners usually pay for the third answer last, after two agencies and a link package, which is why running the checks first saves money, time and a fair amount of arguing.
If your report looks like the one I described, with more excluded URLs than indexed ones, I take these projects on: redirects, canonical strategy, crawl paths, CMS integration and index coverage. Book a free 30-minute assessment and bring the indexing export. I will tell you which of the three answers you are in before you spend anything.
Dominik Gronkiewicz builds and rescues Next.js sites from Częstochowa, Poland, and runs the Agentic Architect Lab community. More at dominikgronkiewicz.com.
Sources
- Google Search Central, Build and submit a sitemap: https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap
- Google Search Central, Managing crawl budget for large sites: https://developers.google.com/search/docs/crawling-indexing/large-site-managing-crawl-budget
- Google Search Central, Consolidate duplicate URLs: https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls
- Search Console Help, Page indexing report: https://support.google.com/webmasters/answer/7440203?hl=en
- Search Console Help, URL Inspection tool: https://support.google.com/webmasters/answer/9012289?hl=en
- Next.js docs, generateMetadata: https://nextjs.org/docs/app/api-reference/functions/generate-metadata
- OpenNext Cloudflare docs, Caching: https://opennext.js.org/cloudflare/caching
- Cloudflare docs, Workers static assets headers: https://developers.cloudflare.com/workers/static-assets/headers/
Building with AI beyond this article?
I run The Agentic Architect Lab, live builds, agent workflows, and a playbook for technical founders shipping solo. No toy demos.
Join the Lab