Guide Published 21 August 2026 13 min read

E-commerce SEO Audit: Triage, Not a Checklist

A store with 10,000 products doesn't have 10,000 URLs — it has a few million. Filters, sorts, pagination and parameters multiply out into a URL space Botify once measured, under 200,000 products, at over half a billion crawlable pages. Almost none should be indexed. That gap is the whole subject of an e-commerce audit — and the thing a normal audit never looks at.

Roman Makuev
Last updated

A store with 10,000 products doesn’t have 10,000 URLs. It has a few million. Twenty filters, three sort orders, pagination, session parameters — multiply them out and a mid-sized catalog generates a URL space Botify once measured, on a site with under 200,000 products, at more than half a billion pages a crawler could reach. Almost none of them should exist in Google’s index. That gap — between what a store can generate and what deserves to rank — is the whole subject of an e-commerce audit, and it’s the thing a normal audit never looks at.

Here’s the distinction that decides everything after it. A normal SEO audit asks what’s broken on a page: titles, speed, a redirect chain. An e-commerce audit asks something the page-level view can’t see. Across the millions of URLs a store spins up, which ones should Google crawl, which deserve an independent place in the index, and where is authority leaking between them into pages that will never sell anything.

One boundary before the checks, because it keeps coming up. This is how I find the damage. Fixing it — the rebuild, the URL architecture, the routing rules — is its own discipline, and I’ll mark where a finding turns into a build decision rather than blur the two. An audit that mixes them ends up a 60-page document nobody acts on. The job here is diagnosis, prioritized.

What an e-commerce audit actually triages

I’m not going to define “SEO audit.” If you’re reading this you know, and the ranking pages have that ground covered to death. The only thing worth stating is the delta — what changes when the site is a store.

A normal audit checks a website. An e-commerce audit checks a system with four moving parts a content site doesn’t have: a taxonomy that branches into categories, subcategories and attributes; a crawl-control layer deciding what bots reach; an index-control layer deciding what survives to rank; and underneath all of it, commercial intent — whether a given page maps to something a person searches for with a wallet open. A blog has pages. A store has all of that, and the audit is mostly about the seams where the four disagree: the category that’s crawlable but shouldn’t be indexed, the product that’s indexed but reachable by no link, the filter that matches real demand but was blocked by a rule written for a different filter.

So the checks below aren’t a checklist walked top to bottom. They’re the places those four layers tear, ordered by how much revenue usually leaks through each.

The index decision, not the crawl question

Every ranking guide for this term audits the same thing: can Google crawl your pages. That’s the wrong question, or rather it’s the easy third of the real one. Crawling is whether Googlebot can reach a URL. Indexing is whether that URL earns an independent place in the results. The gap between them is where e-commerce sites quietly rot, and no “can we crawl it” checklist reads the gap.

So the lens I run every URL class through isn’t “is this crawlable.” It’s “does this deserve to be in the index at all.” Take the classes one at a time — top-level categories, subcategories, product listing pages, product pages, then the machinery underneath: variant URLs, facet combinations, sort parameters, pagination, internal search results. Each lands in one of five buckets: crawl and index it, canonicalize it to a parent, noindex it, block it outright, or leave it a pure UX state Google never sees. The audit’s job is to find every place the site answered that question wrong — indexing what should stay hidden, hiding what should rank.

Bloat is the answer most stores get wrong, and it runs one direction far more often than the other. Color crossed with size crossed with brand becomes forty thousand thin, near-identical pages, every one indexable, every one competing with its own parent category for the same query. The reverse failure is rarer and more expensive: a genuinely valuable page — a facet matching real demand, “waterproof hiking boots,” a legitimate collection — sitting behind a noindex someone applied with a broad brush, invisible in the index it earned a place in.

To read this at all I have to confirm what’s actually in the index, class by class — not what the site intends, what Google holds. So I run a bulk index check across Google and Bing, URL template by URL template, reading real index status rather than a site: guess, so the picture is “of this class of page, here’s the share that’s really indexed,” set against what the site thinks it published.

Bulk index check across Google and Bing — real index status, HTTP codes and flags per URL
Crawl ≠ index — real Google and Bing status per URL, with the flag that explains each gap: a category behind a broad-brush noindex, a form that only 301s, a facet whose canonical points elsewhere.

The trap I flag on nearly every audit. Block a URL in robots.txt and Googlebot can’t crawl it — which means it can’t read the noindex tag you also put on it. A page that’s already indexed can stay in the index, uncrawlable, unremovable by the tag meant to remove it: the exact opposite of what you wanted. One signal per URL. Block or noindex, chosen by whether you’re protecting crawl budget or clearing something already indexed — never both on the same page.

The crawl-budget leak, read from the logs

“Millions of URLs” is an abstraction until you watch where Googlebot spends its day, and then it turns into money. Google’s own guidance puts the threshold plainly: crawl budget starts to matter past roughly 10,000 frequently-updated URLs, or when Search Console shows a swelling pile of “Discovered — currently not indexed.” Every store I audit crosses that line the moment faceted filters switch on. The catalog is 5,000 products; the URL space the bots see is five million.

The number that lands with clients

Screaming Frog’s analysis puts about 35% of a typical e-commerce site’s crawl budget on faceted URLs that return no SEO value — a third of everything Google will spend on you, poured into pages you’d never want ranked. I read that split by segmenting the crawl with regex by URL type — /c/ categories, /p/ products, ?filter= facets, sort and pagination parameters — then setting that against the server logs to see where Googlebot’s hits actually land per type. The pattern is almost always the same: the crawler grinding through facet grids and sort permutations and deep pagination while genuinely new products wait weeks to be seen.

There’s a newer cost on top of the old one. AI crawlers now make up a real share of the bots hitting your site — Cloudflare put it around 22% of bot traffic in early 2026 — and they’re far less efficient than Googlebot about it, some crawling tens of thousands of pages for every referral they send back. The facet grid wasting one company’s crawl budget is now wasting several. That doesn’t change the diagnosis. It raises the price of leaving it unfixed.

There’s a related leak the crawl view surfaces: orphan products. A product page reachable by no internal link is invisible to the crawler’s sense of importance, because nothing on the site votes for it — it sits there technically indexable and never ranked. Orphans come in two shapes. The obvious one is a product dropped from its category or never linked at launch. The quieter one is a pagination failure: a category running on infinite scroll or lazy-load with no real HTML pagination underneath — no <a href> links a crawler can follow to page two and beyond. The visitor scrolls and JavaScript fetches more products; Googlebot doesn’t scroll, so it sees the first screen of the listing and stops. Everything in the catalog tail behind that scroll is orphaned at once. This one shows up plainly in a crawl: Screaming Frog reaches the first page of the listing, finds no href to page two, and stops — so the products it found come back far short of the catalog count the store thinks is linked. The gap between the two numbers is the tail that’s invisible because the only path to it runs through JavaScript the crawler never executes. I read the internal-link graph for both shapes: the products nothing points at, and the deep listings nothing reaches because the pagination isn’t really there.

Out-of-stock and discontinued: where equity quietly leaks

This is e-commerce-specific and the ranking pages barely touch it, which is strange, because it’s one of the most common ways a store bleeds authority without anyone noticing. Products go out of stock. Products get discontinued. Both are inventory events, and on most stores both are handled by whoever built the platform, with no thought to what happens to a page’s accumulated ranking equity when the product behind it vanishes.

The failures have a shape. A discontinued product’s URL starts returning a hard 404, and every link that pointed at it — internal, external, the ranking history baked in — dead-ends. Or the platform’s “helpful” default kicks in and every dead product 301-redirects to the homepage, which Google reads as a soft 404 and ignores, so the equity evaporates the same way, just more politely. Or the quiet, worst version: a “temporarily out of stock” page for a product discontinued a year ago, still returning 200, still indexed, still pulling a click that lands on nothing anyone can buy.

What the audit does is separate the temporary from the permanent, because they route differently and the site almost always treats them the same. A genuine temporary stockout isn’t an indexation problem — the page should stay, the equity should hold. A permanent discontinuation is a routing decision. The audit finds the leak: how many dead products, returning what status codes, bleeding equity where. What the correct routing is for each one — replacement model, parent category, or a clean 410 — is a build decision, and it lives in the rebuild, not the diagnosis.

Variants and facets: one product or ninety-six URLs?

One product in twelve colors and eight sizes can, if the platform is naïve, become ninety-six URLs — every color-size pair its own crawlable, indexable page, all near-identical, all competing with each other and the parent product for one query. Facets do the same a level up: a store with 1,000 products and five filter dimensions can generate over 100,000 URLs, most of them thin, some accidentally competing with the very category they filter.

The decision each one needs isn’t “is it duplicate” — it’s whether it earns an independent place in the index, and the dividing line is search demand. A filter combination people actually search — “black maxi dresses,” “women’s trail running shoes” — has its own intent, enough products and a clean landing, so it deserves its own indexable page. A combination nobody searches — a random three-filter stack, a temporary stock state, a sort order, a session parameter — earns nothing, and left indexable it just splits signal and drains crawl budget. So the audit sorts every URL class into the same three buckets: index it (real demand, distinct intent), canonicalize it to the parent (it overlaps an existing page), or noindex and block it (no demand, thin, or a pure UX state). That verdict, class by class, is the finding; wiring the canonical and robots rules is the build.

The reason this matters more than it used to is what Google now does with pages it can’t tell apart. It doesn’t match text word-for-word — it reads a page as a position in meaning-space, and two pages built from the same template land almost on top of each other there even when the visible words differ. It collapses them, or picks one and buries the rest. Google’s September 2025 spam update, powered by an upgrade to its SpamBrain system, leaned hard into exactly this: scaled, templated pages that differ only by a token — the classic being location pages identical but for the city name — lost visibility sharply, because Google couldn’t meaningfully tell them apart. A faceted grid churning out near-identical filter pages is the same pattern wearing a different hat. So I’m not eyeballing duplicate text; I’m looking for the clusters of URLs too close in meaning to justify separate pages, and reading the mismatches between what’s canonicalized and what’s actually indexed — the pages a site thinks it’s hiding but isn’t. The self-competing pairs are the tell: a parent category and one of its own filtered states both ranking, badly, for one term.

The content problem a scanner reads wrong

Everyone agrees e-commerce has a thin-content problem, and almost everyone is wrong about what it is. The reflex is: product pages run the manufacturer’s boilerplate, identical across every store selling the same SKU, so that’s duplicate content and Google penalizes it. There is no such penalty — Google’s own John Mueller has said it plainly, and Google’s documentation treats ordinary duplication as normal, not a spam violation. What Google actually does is quieter and worse for you: it deduplicates. It groups the pages carrying that same paragraph — the manufacturer, a big marketplace, your store — and shows one, usually the most established source. Your copied page isn’t punished. It just never ranks. “No penalty” and “no rankings” look identical from where you’re standing, which is exactly why this one hides.

So the audit question on a product page isn’t “is the text duplicate” — it’s “does this page deserve original treatment at all,” and that turns on demand. A long-tail product nobody searches doesn’t need rewriting; canonicalize it and spend nothing on it. A product with real search demand, where you’re losing the canonical to a marketplace carrying the same supplier text, is where original content earns its cost — and “content” here isn’t a longer paragraph. A product page in 2026 ranks on the completeness of the product entity: variants declared properly, real images and video, specifications, genuine reviews and Q&A, shipping and return terms that read like a real business rather than a legal template. That completeness is also what gets a product cited in AI shopping answers — attribute-rich structured data (real GTIN, MPN, brand, ratings, full offers) shows up in AI product recommendations several times more often than the bare minimum. A 150-word page that answers what a buyer needs to know beats a 600-word wall of supplier prose.

Category pages fail differently, and they matter more — a category typically pulls several times the organic revenue of any single product page, because it catches the broad, high-volume search before the shopper has picked a SKU. A category is thin not when it’s short but when it’s just a product grid with a title, or a grid with a wall of keyword text dumped underneath to hit a word count, which Google reads as noise and grows less sure what the page is even about. What a strong category needs is editorial context a shopper actually uses and the right assortment on the shelf: a category that reads well but lists the wrong products is thin in a way no word count catches. Below the head category runs the demand ladder — subcategory, then the filter and tag pages that each catch a slice of long-tail intent (“waterproof,” “under $100,” “for wide feet”). Each rung that matches real search demand is a page worth having; each one that doesn’t is a page to canonicalize away. Finding which rungs have demand and no page, and which pages exist with no demand behind them, is the audit.

Does every way people shop have a shelf?

The last differentiator isn’t technical — it’s demand-side, and it asks a question a crawler can’t. For every way a person shops your category — by attribute, by use case, by comparison, by the problem they’re solving — is there a page built to catch that intent, indexable and ranking? Or is the demand landing somewhere it shouldn’t, or nowhere?

The findings are consistent across stores. A high-value intent with real search volume and no page targeting it — money on the floor. An informational blog post ranking where a category page should be, catching the visitor in the wrong context to sell to. Two pages splitting one intent, each too weak to win because the store cannibalized itself. What surfaces those is mapping real demand against the existing URL set — and the demand side of that map isn’t one keyword tool. I pull it from marketplaces, on-site search logs, autocomplete: the places people express intent that Ahrefs and Semrush don’t fully see.

There’s an internal-links dimension the intent map exposes that most audits miss. Even when the right category page exists, the site often fails to point at it — a strong commercial page starved of internal links while the blog hoards the equity everyone links to by habit. So the map isn’t only “which intents have no page.” It’s also “which pages exist but nothing votes for.” How to rebuild the link structure — the megamenu, contextual hubs, the click-depth rules — is the build. Finding where structure fights demand is the audit.

The feed is a second index

There’s a place your products live that isn’t your website, and most audits never open it. For AI shopping, and increasingly for Google’s own shopping surfaces, the product data that gets recommended doesn’t come off your page. It comes from your feed.

Where the recommendations come from

A study by Tom Wells this year mapped where the products in ChatGPT’s shopping carousel originate: across more than 43,000 products, 83% matched Google’s top-40 organic Shopping results. The page isn’t the source. The Merchant Center feed is, and it now feeds a whole ecosystem — Google’s shopping panels, AI Overviews, ChatGPT’s carousel, Perplexity’s product answers — all reading from the same structured file most stores haven’t touched since they set up paid Shopping.

That makes the feed an index in its own right, with its own version of every failure the website has. So I audit it like one, by hand — this part isn’t a tool run, it’s me opening the feed and reading it against the site. Does the feed’s picture of a product match the page’s — same price, same availability — or have they drifted, which quietly disqualifies the product from the surfaces that check? Are the attributes complete on the SKUs that matter, or are titles truncated and identifiers missing on your highest-revenue products, the way one feed audit found 85% of titles too short for AI systems to place them? Can the AI crawlers even reach the catalog, or did a robots.txt rule written years ago lock them out of the data they now need? None of this shows up in a page-level audit. All of it decides whether your products appear where a growing share of buying now starts.

The fast technical pass

Everything above is where I spend the audit, because it’s where stores differ and where the money is. The standard technical layer still gets checked, but the top ten cover it well and I rarely find surprises, so I move fast.

Rendering: are the products in the DOM, or does the page ship an empty shell that only fills after JavaScript hydrates — because if it’s the latter, the crawler may be indexing a blank page. Core Web Vitals read per template, not one site-wide score, because a PDP and a PLP fail differently and the average hides both. Speed here isn’t only a UX number — a slow response means fewer pages crawled per visit, so on a million-URL store it feeds straight back into the crawl-budget leak, and third-party scripts and tag managers are usually where the time goes. Product schema — Product, Offer, AggregateRating, real GTIN and MPN — present and valid, since it’s what makes a product eligible for rich results at all. Canonical hygiene across the URL space. Mobile, which for most stores is simply the primary version now. Two or three checks each — what I verify quickly and why it rarely surprises me.

None of this is where the audit is won. The seven sections above it are.

What the deliverable actually says

A flat list of 137 issues sorted by severity is a technical export, not an audit, and it’s worse than useless because it launders a crawler’s sense of “critical” into yours. A tool flags a facet-bloat warning on a dead category as critical and an indexation gap on your best-selling category as medium, and the list hands you the dead category first — it has no idea which page touches revenue.

So the output inverts that. Severity gets weighted by commercial value: a medium problem on the page that drives revenue outranks a critical one on a page nobody should reach. Findings sort by impact against effort, so the store knows what to do Monday, not just what’s wrong. And every finding names its owner — facet rules are engineering, duplicate content is content, equity routing belongs to whoever owns redirects. Leave that off and nobody knows whose desk it lands on, so it lands on none. The issue count was never the point. Which three things, done first, move revenue — that’s the point.

Within a year I’d expect feed-to-site sync to be a standard line on every serious audit, sitting next to canonical hygiene, because it stopped being a paid-media concern and became a ranking surface. The stores that read their own systems this way — index decisions, crawl allocation, the feed as its own index — are the ones still visible when the next surface opens. If you’d rather I run this on your store than run it yourself, that’s our e-commerce SEO audit.