Why Magento 2 category pages stall in search while product pages rank
An audit checklist for Magento 2.4.x category pages stuck on page two: layered navigation, canonicals, sort parameters, templates, and what to check after that.
- Magento 2
- SEO
- Operations

You search your head term and find your own product pages at positions 6 to 8. The category page that holds all of those products, plus the buying guide someone spent weeks writing, sits at 22. It has been there for two years. Shops with a dozen products and copied manufacturer text rank above it.
A recent Magento Stack Exchange question describes this case exactly. The store runs Magento 2.4.7 with about 15,000 products and 420 commercial categories. The median category position is 18 to 20, and the category page gets most of the impressions for its query cluster, so the problem is not two URLs splitting the traffic. The post is useful because the author had already done the standard audit and the problem was still there. Below is the checklist in the order we work through it, followed by the harder part: what to look at when every item on it comes back clean.
Layered navigation is the first place to look
Every filter option in Magento's layered navigation is a plain <a href>. Out of the box, each one is a crawlable URL with a query string, and multi-select extensions multiply those URLs with every combination. In the Stack Exchange case, a multi-select bug in a layered-navigation extension produced more than a million URLs, and Googlebot crawled 142,000 filter URLs in a single week.
Check these:
- The Search Console page indexing report. Look for category URLs with parameters in the index. Every indexed facet URL competes with its own parent category.
- Server logs. Check them for Googlebot requests to filter parameters, and confirm the bot with reverse DNS. Crawls spent on facets are crawls not spent on categories.
- The order of the fix. Add
noindexfirst, wait until Google has recrawled and dropped the URLs, then block them in robots.txt. If you block first, Google can never see thenoindex, and the URLs stay listed as "Indexed, though blocked by robots.txt". The merchant got this order right:noindexfrom March 2026, then a robots block from September.
Robots rules are set under Content > Design > Configuration > (store view) > Search Engine Robots. Write one Disallow rule per filter attribute code. A blanket Disallow: /*? also blocks ?p= and cuts Google off from the products on deeper pages.
Blocking does not stop the template linking to those URLs. A category page with 80 crawlable filter links sends most of its internal link signal to URLs Google can't fetch. For combinations you never want indexed, we prefer rendering the filter without a crawlable href. That is a template change, not an admin setting.
Canonical settings that undercut the category
The settings are under Stores > Configuration > Catalog > Catalog > Search Engine Optimization.
- Use Canonical Link Meta Tag For Categories. Set it to Yes, then check what your build actually outputs on
?p=2. Core points the canonical at the bare category URL, which tells Google that page 2 is a copy of page 1 and hides the products listed there. The merchant switched paginated pages to self-referencing canonicals, and that is the right setting. - Use Canonical Link Meta Tag For Products. Set it to Yes, especially if Use Categories Path for Product URLs is also Yes. With category paths on, one product can be reached at several URLs, and the canonical has to pick one.
- Exactly one canonical and one robots meta in the rendered
<head>. Porto and most SEO extensions output their own tags. The merchant lost two months to a theme robots plugin that appliednoindexby mistake. Check a sample of categories after every extension or theme update, using the rendered HTML rather than the admin settings.
Sort, limit and pagination parameters
product_list_order, product_list_dir, product_list_limit and product_list_mode create near-duplicate versions of every category. A correct canonical consolidates them, but Google still crawls them. None of them should ever be indexed, so block them in robots.txt and leave p crawlable.
Request ?p=999 on a real category. If it returns 200 with an empty product grid, you have an endless supply of thin pages. Return a 404 or redirect to the last real page instead. The merchant fixed this one as well.
Thin templates and weak internal links
Check these in the rendered HTML:
- The category description. Find out where it actually renders. Many themes truncate it behind a "read more" toggle, move it below the product grid, or skip it entirely when Display Mode is set to Products only.
- The H1 and meta title. Each category should have its own H1 and its own meta title, not the default pattern.
- Links back to the category. Check whether product pages link to their main category in static HTML. On many 2.4 builds the breadcrumb depends on how the visitor arrived, so a crawler that lands directly on a product page sees Home > Product.
- The mega-menu. A mega-menu links every category from every page with equal weight, which tells Google nothing about which categories matter. Contextual links from related categories and from buying guides carry more information.
When the technical layer checks out clean
This is where the Stack Exchange case gets interesting. The merchant checked 30 days of Cloudflare logs and found zero mitigated requests from Google. Googlebot, Chrome and the origin server all received identical HTML. Googlebot made a steady 5,000 to 7,000 requests a day and got no 5xx errors. A control category on the same template ranks at positions 5 to 9, which rules out the theme.
In two years, one change moved a category: adding 183 products took it from position 35 to 19. Take that seriously. For a category query, Google is judging whether the listing satisfies the search. Range, depth and how well the assortment matches the query count for as much as the copy does. So compare the category that ranks with the ones that don't, and look at what differs: the number of in-stock products, price spread, brand coverage, and how well the filters fit the query.
The merchant's other open question is whether a long period of index inflation leaves a lasting cap on rankings after cleanup. Google still knows about 881,000 blocked URLs. We have no data we can publish on recovery times, and anyone who gives you a confident timeline is guessing. The pattern of losses is worth noting, though: one large drop at the October 2023 core update, then a slow decline. That shape points to a site-wide quality judgment rather than a bug in one template. Site-wide judgments change slowly, and in this case technical fixes alone have not reversed it.
What to do next
Run the checklist against logs and rendered HTML, not admin screens. Write down the date of every fix so you can match it against Search Console data later. If everything comes back clean, stop changing things across the whole site. Pick a few stuck categories, change one thing in each (assortment depth, the position of the description, contextual internal links), and give each change enough time to show up before you judge it.
If you want a second pair of eyes on a 2.4.x store, see our Magento 2 practice or get in touch. Have the log exports and a dated list of changes ready.
Need this done on a real stack?
Magento 2, Adobe Commerce, migrations to Medusa.js or Vendure, enterprise Next.js, WordPress, and AI automation.
Contact us