Category Page vs. Product Page: How I Fixed Keyword Cannibalization on a Dubai E-commerce Site
Every developer who has built an online store has seen this at least once: you search for an exact product name, and Google shows the category page instead of the product page you wanted to rank. That is what happened o
Every developer who has built an online store has seen this at least once: you search for an exact product name, and Google shows the category page instead of the product page you wanted to rank.
That is what happened on a Dubai e-commerce store I work on. For one specific product keyword, the product page was nowhere to be found. The best-performing URL on the site was the broader category page, and even that sat around position #47.
This post covers how I diagnosed the problem, the rules I applied to fix it, and a checklist you can reuse on WooCommerce or any custom stack.
The Problem: Two Pages Competing for One Keyword
Keyword cannibalization happens when two or more URLs on the same site target the same query. Google has to pick one, and it often picks the wrong one, or it splits signals so that neither page ranks well.
In this case:
| Page | Intended target | What actually happened |
|---|---|---|
| Product page | The exact product keyword | Barely visible |
| Category page | Broad category terms | Ranked around #47 for the product keyword |
The category page named individual products repeatedly across its sections. That told Google the page was relevant to product-level queries, so it competed with the page that should have owned them.
Step 1: Confirm Which URL Google Prefers
Before changing anything, confirm the problem with data:
- Search Console β Performance β Queries. Filter by the exact keyword, then switch to the Pages tab. If the category URL shows impressions and the product URL shows none, that is your answer.
- Live SERP check. Search the keyword in an incognito window with the right country and language settings. Note which of your URLs appears, if any.
-
site:operator. Searchsite:yourdomain.com "product name"to see every page Google associates with that term.
In my case, all three checks pointed the same way: the category page was the only URL surfacing for the product keyword.
Step 2: Find Where the Category Page Overlaps
I audited the category page and counted every mention of every product name. The same products were named several times across different sections, which sent strong product-level signals to the wrong URL.
A quick way to audit this yourself:
# Count how often a product name appears on a page
curl -s https://example.com/category/your-category \
| sed 's/<[^>]*>//g' \
| grep -oi "your product name" \
| wc -l
If a product appears more than once on a category page, it is a candidate for cleanup.
Step 3: Apply Copy and Linking Rules to the Category Page
I rewrote the category copy using four rules:
- Each product is named once on the page. Repeat mentions are what pulled the category into product-level queries.
- No links in the intro. The opening section stays focused on the category's topic.
- Links start from the second section. This keeps the early content from diluting its own focus.
- Each link is used only once. No repeated links to the same destination.
The goal is for the category page to be a clear, broad page for category-level searches, and to let the product page own the product-level keyword.
Step 4: Strengthen the Product Page
With the category page cleaned up, I turned to the product page. The aim was to cover what competing pages don't, not just match what they already cover.
I opened every page ranking for the target keyword and compared them on:
- Which specs and details they cover, and which they skip
- Whether they include FAQs and practical usage information
- How they handle schema markup
Opening the actual pages matters here. A gap analysis built only from SERP snippets misses most of what is on the page.
Here is a minimal Product schema example:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Your Product Name",
"description": "Short product description",
"brand": { "@type": "Brand", "name": "Brand Name" },
"offers": {
"@type": "Offer",
"priceCurrency": "AED",
"price": "99.00",
"availability": "https://schema.org/InStock",
"url": "https://example.com/product/your-product"
}
}
Validate it with Google's Rich Results Test before shipping.
Step 5: Fix the Internal Link Signals
Internal links tell Google which page matters for which topic. I made sure that:
- The category page links to the product page once, with descriptive anchor text.
- Other relevant pages link to the product page using the product name as the anchor.
- The product page links back up to its parent category.
What Changed and What I'm Tracking
Here is what changed on the site:
- The category page now names each product once and has no links in its intro.
- Every link on the category page is unique.
- The product page was rebuilt around the gaps I found in the pages currently ranking.
Rankings take time to reflect changes, because Google has to recrawl and reprocess both URLs. So I'm tracking three things in Search Console rather than declaring victory early:
- Which URL appears for the target keyword (the goal is the product page, not the category).
- Average position for that keyword over a 28-day window.
- Whether the category page still picks up impressions for product-level queries.
If you run this experiment yourself, track the same three signals before and after.
What I'd Do Differently
- Check for cannibalization at launch. It is far easier to set copy rules when a category page is first written than to untangle it later.
- Set a naming rule for category pages from day one. One mention per product, decided up front, prevents the problem entirely.
- Audit competitors by opening their pages. Snippets hide the details that actually create an advantage.
Reusable Checklist
- [ ] Confirm the wrong URL ranks (Search Console, Pages tab)
- [ ] Count product-name mentions on the category page
- [ ] Reduce each product to one mention on the category page
- [ ] Remove links from the intro section
- [ ] Use each link only once
- [ ] Open and audit the pages currently ranking, and find what they miss
- [ ] Add that missing information to the product page
- [ ] Add and validate Product schema
- [ ] Add one clear internal link from category to product
- [ ] Re-check rankings after recrawl
Wrap-Up
Cannibalization is easy to create by accident, especially on e-commerce sites where category copy naturally mentions the products inside it. The fix isn't complicated, but it does need data first and discipline afterward.
You can see the category page I applied these rules to here: RELX Pods Pro on podx.ae.
Have you run into this on your own store? Let me know what worked for you in the comments.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.