Where Magento SEO goes wrong first: the attribute record, not the category page
Most Magento SEO advice starts at the category page. The category page is not where the decision is made. Layered navigation is configured on the attribute, at Stores > Attributes > Product > Storefront Properties, and two properties on that record decide whether a filter can exist at all.
Adobe’s documentation is precise about the first one: the Catalog Input Type for Store Owner property must be set to Yes/No, Dropdown, Multiple Select or Price. No other input type can be filtered, whatever the merchandising brief says. The second is Use In Layered Navigation, which must be set to Filterable (with results) or Filterable (no results). Layered navigation then appears only on anchor categories — categories whose Display Settings have Anchor set to Yes.
The consequence people miss is one of scope. Because the switch lives on the attribute record rather than on any category, flipping a single attribute to filterable turns that filter on across every anchor category that carries the attribute, in every store view, in one save. There is no per-category opt-out in the standard configuration. A merchandiser adding a filter for one seasonal category has changed the crawlable surface of the entire catalogue.
Filterable (no results) is the setting that quietly manufactures crawlable dead ends. Adobe documents that it “displays filters for all available attribute values and their product counts, even when products with zero (0) matches exist”. Those are real anchors pointing at real URLs that return a page with nothing on it, and a crawler has no way to know that before requesting them.
Price is a facet with its own algorithm on top. catalog/layered_navigation/price_range_calculation — Price Navigation Step Calculation, store-view scope — is Automatic (equalize price ranges) by default, or Automatic (equalize product counts), or Manual. Under equalised product counts, Adobe documents that price-range splitting stops at the threshold set by Interval Division Limit, whose default value is 9. Under Manual you set Maximum Number of Price Intervals, allowed up to 100. Every interval and sub-interval is an addressable filtered state.
The price facet also misreports configurable products, and this is documented rather than folklore: filtering by price uses the lowest price among a configurable product’s child items, so a configurable appears only in the lowest band of its children even when some children cost several times that. A lowest-band filter page listing a product whose selectable variants all sit far above the band is Adobe Commerce behaving exactly as specified, and it is a merchandising problem before it is an SEO one. All of this is set out in Adobe’s layered navigation documentation.
What happens to the filter URLs, and what you keep
We do not apply one rule to every attribute. An attribute whose values people genuinely search for, and whose result set is stable rather than seasonal, can earn a crawlable address. An attribute that only permutes an existing set does not, and gets handled by one of the mechanisms Google documents for faceted navigation: one of the four Google documents — a robots.txt disallow on the parameter shape, URL fragments, a rel=”canonical” to the unfiltered version, or rel=”nofollow” on the link.
Each of those has a stated limit, and we quote the limits rather than the promises. Google says canonicalising a filtered URL to the unfiltered one “may, over time, decrease the crawl volume of non-canonical versions” — a tendency, not a switch. It says rel="nofollow" works only if every anchor pointing at that URL carries it, which on a Magento storefront means the layered nav, the pagination, the sort links and any CMS block. It says URL fragments are generally not crawled or indexed at all, which makes a fragment-based filter invisible in both directions. Magento’s native layered navigation already uses the & separator Google asks for; what it does not guarantee is a consistent filter order, and inconsistent order is what turns one filtered state into several addresses.
The url_rewrite table is a database, and Magento writes to it while you work
On most platforms the URL structure is a rule. On Adobe Commerce it is a table of rows that the application generates as you edit the catalogue, and almost every duplicate-address problem on a Magento store is a row-generation problem.
Use Categories Path for Product URLs (catalog/seo/product_use_categories, store-view scope) is off by default, and Adobe’s own example shows why turning it on matters: the same product then answers at /women/tops-women/hoodies-and-sweatshirts-women/helena-hooded-fleece.html and at /helena-hooded-fleece.html. Adobe’s configuration reference names the consequence, if cautiously — doing so “can cause multiple URLs to point to the same page, which might impact search rank”. Two addresses per product, multiplied by every category a product sits in.
Create Permanent Redirect for URLs if URL Key Changed (catalog/seo/save_rewrites_history, store-view scope) writes a new rewrite row every time a URL key is edited. Rename a product’s key three times over two years and the table holds three rows, each pointing at the previous address. Nothing removes them. This is the origin of the redirect chains a crawl tool reports on Magento stores, and it is a side effect of a setting most merchants correctly leave enabled.
Generate “category/product” URL Rewrites (catalog/seo/generate_category_product_rewrites) is different in one important way: its scope is global, not store view. Adobe warns that with automatic redirects enabled, saving a category generates all product and category rewrites in real time and “could result in significant performance issues for categories with many assigned products”. Separately, Product URL Rewrite Scope lets rewrites be generated at store-view or website scope, which changes how many rows a single save produces on a multi-site install.
So when a developer reports that saving a category takes minutes, that is not first a hosting question. It is a catalogue-configuration question with a documented cause, and the remedy is a setting — with a consequence we will come back to below.
Two smaller mechanics belong here because they cause avoidable duplication. Product URL Suffix and Category URL Suffix are store-view scoped and Adobe is explicit that the suffix must be entered without a leading period and must never be typed into a URL key, because doing so produces a double suffix. And Apply transliteration for product URL is store-view scoped and defaults to Yes, which is wrong for a store whose catalogue is genuinely non-Latin — Adobe gives a Chinese-language store as the case where it should be set to No.
Canonical tags on Magento are two switches, set once, at store-view scope
Adobe Commerce does not give you a canonical field per page. It gives you catalog/seo/category_canonical_tag (Use Canonical Link Meta Tag for Categories) and catalog/seo/product_canonical_tag (Use Canonical Link Meta Tag for Products), each a Yes/No at store-view scope. Two dropdowns decide the canonical policy for every category and every product in that view.
That combination is what matters, not either switch alone. With the category path in product URLs and the product canonical off, the store publishes several indexable addresses for one product. With the category path on and the product canonical on, the duplicates exist but resolve. The engineering effort is trivial; the decision is not, and it is made once, at a scope, for tens of thousands of URLs at a time. On Shopify the platform makes this choice for you; on WooCommerce a plugin exposes it per post. On Magento it is configuration, and it is invisible from any single page.
One related default is worth checking on every store: product Meta Title auto-generates from {{name}} and Meta Description from {{name}} {{description}}, both at store-view scope. A catalogue nobody has been through by hand is therefore shipping descriptions assembled from the product description field, in every view, including views in languages the description was never written in.
Multi-store views: the store code is global, the base URLs are not
Running several store views is where Magento’s scope model stops being an abstraction. Add Store Code to URLs is a global setting. Adobe’s warning about it is operational, not stylistic: when it is set to Yes “you must include store codes in your browser URLs to ensure that URL rewrites are mapped correctly and all pages are opened successfully. This avoids 404 Page Not Found errors.” One switch reshapes every address on every view simultaneously.
Almost everything around it is scoped the other way. Base URL, Base Link URL, Base URL for Static View Files and Base URL for User Media Files are all store view scoped, as is Use Web Server Rewrites — the setting that keeps index.php out of your paths. A store view can therefore be serving correct HTML from an incorrect media host, or exposing index.php in one language and not another, with nothing in the admin flagging the mismatch.
The trap that produces soft 404s at scale is Auto-redirect to Base URL. Adobe’s guidance is a single sentence and it is unambiguous: “Do not use auto-redirect to base URL for multi-store setups.” Left on, a broken or retired URL redirects to the base URL of the view instead of returning 404 — so every dead address on every view answers 301 or 302 and lands on the base URL rather than returning 404, and the pattern replicates across the estate. Adobe’s General > Web configuration reference carries both settings and their scopes.
Because URL keys, meta titles, meta descriptions and every catalog/seo/* value listed above are store-view scoped, a value set at Default Config silently applies to every view that has not overridden it. Store-view configuration is the platform mechanic. Whether those views should be subdirectories, subdomains or separate domains, and how they should be annotated for language and region, is a strategy question that sits with international SEO rather than with the Magento admin.
Why nothing changed on the live site after you changed it in the admin
This is where Magento engagements most often lose time, because the symptom and the cause sit in different subsystems, and no hosted platform has an equivalent. What you set in the admin, what the index tables contain, and what the cache serves a crawler are three different states, and they can disagree for days.
Adobe defines the two indexer modes plainly: Update on Save (“realtime”) means indexed data is updated when a change is made in the Admin; Update by Schedule (“schedule”) means “data is indexed according to the schedule set by your cron job”. The manual reindex command “reindexes one time only. To keep indexers up to date, you must set up a cron job.” A store with a broken or unconfigured cron in schedule mode looks entirely healthy in the admin and updates nothing.
The indexers that decide what a crawler is served are named, and they are worth knowing by name: catalog_category_product, catalog_product_category, catalog_product_price and catalogsearch_fulltext. bin/magento indexer:status reports each one’s status, its Update On mode and its schedule backlog, so “is this store’s index actually current” is a question with a one-line answer that almost nobody asks. Adobe also documents a failure specific to schedule mode: the database triggers that feed the changelog are added when the mode is set to schedule and removed when it is set to realtime, and if they go missing the documented repair is to set the indexers to realtime and back to schedule again.
Then the cache. Adobe’s own configuration procedures end by telling you to click the Cache Management link in the system message and refresh the invalid cache — the save deliberately leaves the cache invalid rather than purging it. Until that happens, the storefront is still serving the previous HTML, canonical tags and robots directives included.
The working rule that falls out of this is simple and we hold to it: a Magento change is verified against the storefront response, never against the admin field. We do not sign off a canonical, a redirect or an indexation directive from a screenshot of a configuration screen. Adobe’s indexer management guide is the reference your developer will want alongside that.
The commands available to do this depend on your minor version, which is one honest reason version matters: bin/magento indexer:set-status, which can mark indexers invalid, suspended or valid, was introduced in 2.4.7, and the Customer Grid indexer gained Update by Schedule support in 2.4.8.
Where Magento site speed actually goes
“Is it the theme, the server or the images” is the wrong first question on Adobe Commerce, because the platform has failure modes that are neither. Four candidates, and they are distinguishable from each other rather than a matter of opinion.
Index state. A category page assembled while catalog_category_product or catalog_product_price is rebuilding, or sitting on a large schedule backlog, is slow for reasons no front-end audit will surface. The backlog count is visible in indexer:status.
Cache state. Because configuration saves invalidate rather than refresh caches, a store mid-merchandising-cycle can be serving substantially uncached responses to crawlers while every logged-in test in the office feels fine.
The search service. Adobe Commerce’s catalogue search runs against an external engine selected at catalog/search/engine — Elasticsearch or OpenSearch — and fed by the catalogsearch_fulltext indexer. On-site search results, and layered navigation on search-results pages, are only as fresh and as fast as that service and that indexer. This is a component to check, not a theme setting.
Image addressing. Catalog media URL format is a global setting with two options: a unique hash per image variant (legacy mode), or image optimisation driven by query parameters. Changing it changes how every catalogue image on every store view is addressed at once — while the media location itself, Base URL for User Media Files, is store-view scoped. A largest-contentful-paint problem on a Magento category page is frequently an image-variant addressing problem rather than an oversized source file.
Separating these takes server-side and storefront evidence together, per template and per store view. The platform-independent half of that work is covered under technical SEO, and a scoped diagnostic pass is available as a standalone SEO audit.
Adobe Commerce or Magento Open Source — what the edition actually changes
The settings above behave identically on both editions. catalog/seo/*, the url_rewrite table, the indexer model and store-view scope are shared. What the edition changes is what else is in the picture, and two of those materially change what a crawler is served.
Category Permissions is documented by Adobe as available only in Adobe Commerce and not in Magento Open Source. It can restrict category browsing to named customer groups and redirect everyone else to a landing page. An anonymous crawler is “everyone else”, so a permissions rule set for a B2B customer group is also, silently, an indexation rule.
Live Search changes where facets are decided at all. Adobe repeatedly notes that the standard layered navigation described in its own documentation “differs from Live Search filtered navigation with facets”, and that the standard search configuration differs for Live Search. If your store runs Live Search, the attribute-level work described at the top of this page is not where your facets live, and an agency that does not ask which one you are on will configure the wrong system. Adobe also documents an option for SaaS-based price indexing for merchants using Live Search, Catalog Service or Product Recommendations — which moves part of the index state off the install entirely.
Deployment model matters alongside edition: Adobe badges its automatic-redirect documentation as applying to Cloud (Adobe-managed PaaS) and on-premises projects. So the useful opening question is never “which licence do you hold” — it is which of these components are switched on, and where the index and the search service actually run.
The settings we will not change without a decision in writing from you
Every platform has settings that are awkward to reverse. Adobe Commerce has at least one that cannot be reversed at all, and it sits directly in the path of a frequent performance complaint on the platform.
The documented remedy for category saves that generate rewrites in real time is to set Generate “category/product” URL Rewrites to No. Adobe’s warning on that action reads: “Turning off automatic generation of category/products URL rewrites results in permanent removal of all existing category/product type URL rewrites, which cannot be restored.” The admin asks you to confirm in a dialog and then deletes them. There is no undo, no export step offered, and the setting is global, so it applies to the whole installation.
That is a genuine one-way door. It is sometimes still the right call — a store whose category saves take minutes is paying for those rows every working day. But it is a decision with a permanent consequence, taken once, and it is not a decision any agency should make inside a sprint on your behalf. It goes in writing, with the rollback position stated plainly: on this setting the only rollback is a database snapshot taken immediately beforehand, because the application cannot rebuild what it deleted. Adobe’s automatic redirects documentation is where that warning lives, and we will point you at it before we ask you to approve anything.
Three more belong in the same category, for the same reason — global or estate-wide effect, no clean reverse. Turning Add Store Code to URLs on or off rewrites every address on every view. Turning Use Categories Path for Product URLs off after it has been live retires an entire address family that external links and internal blocks may still reference. Changing a URL suffix does the same thing to every category and product in the view.
On execution: for most engagements we specify and your Magento developer or hosting partner applies the change in your release process, because a store that deploys through a pipeline should not be edited around it. Where you would rather we worked in the admin directly, that is arranged separately, with named access at a stated scope and an agreed change window.
What this work cannot promise
No ranking or revenue guarantee, on this platform or any other. Beyond that, four limits specific to Magento work are worth stating before you buy anything.
- We cannot promise that filter URLs currently earning traffic will keep it once they are de-indexed. We record what they earn beforehand and an indexation decision can be reversed — but the traffic returning is not something anyone can guarantee.
- We cannot restore url_rewrite rows that Adobe Commerce has deleted. That is why the setting above needs your written decision rather than our judgement.
- We cannot promise your 2.4.x version is fine to stay on. Some behaviour and some commands differ by minor version, and where an upgrade is the honest prerequisite we will say so rather than bill around it.
- We publish no Magento client counts, migration counts or platform-specific case results, because we have no case study covering this lane. What is on this page is the method and the documentation it rests on. If that is not enough evidence for the decision you are making, it should not be.
And we cannot fix what we cannot reach. Without server logs, admin access at the right scope and someone able to run bin/magento, a meaningful part of this work stalls at diagnosis. Category-level strategy that is not platform-specific — how the catalogue is structured for demand rather than for the admin — sits with ecommerce SEO.
Questions we are asked before a Magento engagement
Is Magento SEO genuinely different from generic ecommerce SEO?
Magento SEO is different from generic ecommerce SEO because the decisions are made at named configuration paths and scopes rather than on pages. Canonical behaviour is two store-view switches (catalog/seo/category_canonical_tag and catalog/seo/product_canonical_tag), duplicate product addressing is governed by catalog/seo/product_use_categories, and filters are enabled on the attribute record rather than the category. A page that names Magento in its headings but never names a setting, a scope or a default is describing generic ecommerce SEO. A useful test when comparing agencies: ask which scope a given setting is at, and what its default is.
Will fixing Magento layered navigation cost me the filter pages that convert?
Fixing Magento layered navigation does not require de-indexing every filter, and the ones that convert are exactly the ones to examine first. We record what each filtered address currently earns before anything changes, keep the attributes with genuine, stable search demand crawlable, and apply robots.txt patterns, canonicals or anchor removal to the rest. Two honest caveats: canonicalisation reduces crawl volume of the non-canonical versions as a tendency over time rather than immediately, per Google’s own wording, and traffic returning after a reversed decision is not something anyone can guarantee.
Is a huge Magento url_rewrite table an SEO problem or a hosting problem?
A huge Magento url_rewrite table is usually a configuration problem that presents as a hosting problem. Adobe documents that with automatic redirects enabled, saving a category regenerates all product and category rewrites in real time, which “could result in significant performance issues for categories with many assigned products”. Row growth also comes from catalog/seo/save_rewrites_history, which writes a new row on every URL-key edit and never removes the old ones — the usual source of redirect chains. Adding server capacity treats the symptom; the causes are settings, and one of the available remedies deletes rewrite data permanently, so it needs a decision rather than a ticket.
How does running several Magento store views change the SEO work?
Running several Magento store views multiplies the verification work but not, usually, the decisions. Most SEO-relevant settings — URL suffixes, canonical switches, the category-path setting, URL keys and meta fields — are store-view scoped, so a value set at Default Config applies to every view that has not overridden it, and each view has to be checked on its own rendered output. A few are global and change everything at once, including Add Store Code to URLs, Generate “category/product” URL Rewrites and Catalog media URL format. Adobe also warns explicitly against using auto-redirect to base URL on multi-store setups, because it converts broken URLs into soft 404s across every view.
Do you work on Adobe Commerce as well as Magento Open Source, and does the edition change the work?
We work on both Adobe Commerce and Magento Open Source, and the core SEO configuration is identical across them — the same catalog/seo/* paths, the same url_rewrite behaviour, the same indexer model. The edition changes what surrounds that. Category Permissions is Adobe Commerce only and can restrict what an anonymous crawler is served. Live Search replaces standard layered navigation with a different faceting system, so the attribute-level configuration no longer applies. Adobe Commerce merchants on Live Search, Catalog Service or Product Recommendations may also be using SaaS-based price indexing. The first questions are therefore which components are enabled, not which licence you hold.
Do I have to upgrade my Magento 2.4.x before SEO work is worth doing?
Upgrading Magento is not a precondition for most SEO work, because the configuration paths, scopes and url_rewrite behaviour described on this page are consistent across 2.4.x. Version does change some operational detail: bin/magento indexer:set-status arrived in 2.4.7, and the Customer Grid indexer gained Update by Schedule support in 2.4.8, so what your team can do about index state depends on where you are. Running an unsupported version is a security decision rather than a ranking one, though the two meet when a compromised store starts publishing injected pages. We will tell you when an upgrade is the honest prerequisite instead of working around it.
Should I migrate from Magento to Shopify rather than fix this?
Migrating from Magento to Shopify is a business decision about operating cost and team capability, not an SEO shortcut, and it should not be sold as one. Migration replaces a controllable problem with a fixed one: on Adobe Commerce you own the layered-navigation, rewrite and canonical configuration and can set it correctly; on a hosted platform you accept its structure and work inside it. A migration also puts every URL in the catalogue at risk in one release, which is a larger indexation event than anything on this page. If the platform genuinely no longer fits, the Shopify and WooCommerce pages describe the work those platforms actually need — the failure modes barely overlap, and we do not run one checklist across all three.