SEO Suite for Magento 2
A single module covering the technical SEO surface a serious Magento store needs —
canonical URL control, hreflang for multi-store setups, an in-admin robots.txt editor,
a 301/302 redirect manager with exact / prefix / regex matching, automatic 404
tracking, and machine-readable /llms.txt files for visibility in AI
answer engines. Every setting is store-view-scopeable. Built for Magento 2.4.x and
PHP 8.1–8.4.
rel="alternate" hreflang tags for every active store view, plus x-default, using each store's own product and category URLs.$1 back-references), a full admin grid, per-rule hit counter, and store-view scoping./llms.txt and /llms-full.txt built live from your catalogue, following the llmstxt.org format, so AI engines can read and cite your store.Requirements
| Dependency | Version | Notes |
|---|---|---|
| Magento Open Source / Adobe Commerce | 2.4.x | Open Source and Commerce both supported |
| PHP | 8.1 – 8.4 | ^8.1 || ^8.2 || ^8.3 || ^8.4 |
| magento/framework | ~103.0 || ~104.0 | Installed via Composer |
| Magento_Backend | ~102.0 – ~104.0 | Admin grids and configuration |
| Magento_Catalog | ~104.0 || ~105.0 | Product / category canonicals and llms.txt |
| Magento_Cms | ~104.0 || ~105.0 | CMS-page canonicals and llms.txt |
| Magento_Store | ~101.0 || ~102.0 | Store-view scoping |
| Magento_Robots | ~100.4 || ~101.0 | The robots.txt editor plugs into this module's controller |
Installation
Install via Composer after configuring your credentials. Your license key is on your Ayasoftware dashboard.
composer config repositories.ayasoftware composer https://www.ayasoftware.com/repo
composer config --global http-basic.www.ayasoftware.com your@email.com YOUR_LICENSE_KEY
composer require ayasoftware/seo-suite
bin/magento module:enable Ayasoftware_SeoSuite
bin/magento setup:upgrade
bin/magento cache:clean
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento cache:flush
setup:upgrade creates two tables — ayasoftware_seo_redirect (redirect rules) and ayasoftware_seo_404_log (not-found log) — and registers the admin menu under Marketing → SEO Suite. No attribute-set or catalog changes are made.Verify the installation
bin/magento module:status Ayasoftware_SeoSuite
Then confirm Marketing → SEO Suite appears in the admin menu with Redirects, Robots.txt, and 404 Log underneath it, and that Stores → Configuration → Ayasoftware → SEO Suite loads.
Configuration
All settings live under Stores → Configuration → Ayasoftware → SEO Suite and can be set at Default, Website, or Store View scope. Access to the section is gated by the Ayasoftware_SeoSuite::config ACL resource.
Canonical URLs
| Setting | Default | Effect |
|---|---|---|
| Add canonical tag to product pages | Yes | Disables Magento's native product canonical (removed via layout) and emits SEO Suite's instead. |
| Add canonical tag to category pages | Yes | Emits a canonical on category listing pages. |
| Add canonical tag to CMS pages | Yes | Emits a canonical on CMS pages, including the home page, scoped per store view. |
| Strip layered navigation parameters from category canonical | Yes | Removes pagination/sort/filter query parameters so /category?color=blue&size=M canonicalises to /category. |
| Canonical for configurable product variants | Parent | Parent — a simple product that belongs to a configurable canonicalises to the parent URL. Self — keep the simple product URL. |
| Pagination canonical strategy | Canonical to page 1 | page 1 — pages 2+ point at the unpaginated URL. Self-referencing — each page points at itself (?p=N). rel=prev/next — legacy; canonical stays self-referencing. |
| Trailing slash in canonical URLs | Remove | Remove / Always add / Do not normalise. The domain root always keeps its slash. |
Hreflang
| Setting | Default | Effect |
|---|---|---|
| Enable hreflang tags | No | Off by default. Enable only on multi-store installs — see Hreflang. |
| x-default store ID | 0 | Store view ID used for the x-default entry. 0 uses the default store view. Default scope only. |
Redirects & 404 Tracking
| Setting | Default | Effect |
|---|---|---|
| Log 404 not-found requests | Yes | Records every 404 with hit count, referrer, and timestamps. |
| Maximum 404 log rows | 10000 | When the log reaches this size, the oldest resolved rows are pruned first (then oldest unresolved if still over). Minimum enforced value is 100. |
Generative Engine Optimisation (GEO)
| Setting | Default | Effect |
|---|---|---|
| Enable /llms.txt | Yes | Serves the concise index file. When off, /llms.txt returns 404. |
| Enable /llms-full.txt | Yes | Serves the full-catalogue file. Requires Enable /llms.txt to also be on. |
| Store description (shown to AI) | (blank) | 2–4 plain-English sentences about the store. Rendered near the top of both files. Fill this in. |
| Support email (shown in llms.txt) | (blank) | Falls back to trans_email/ident_support/email when blank. |
| Products shown in /llms.txt | 100 | Product count in the index file. Minimum enforced value is 10. |
| Products shown in /llms-full.txt | 1000 | Product count in the full file. Minimum enforced value is 10. |
Canonical URLs
SEO Suite adds one <link rel="canonical"> per page for product, category, and CMS page types. The tag is injected into the correct <head> position through Magento's page-config asset API, and Magento's own product canonical template is removed by layout so the two never both appear on a product page.
Product pages
- Emitted when Add canonical tag to product pages is on and a product is being viewed.
- If Configurable canonical is set to Parent and the viewed product is a
simplethat belongs to a configurable, the canonical points at the parent configurable's URL. If the product has no configurable parent, it falls back to its own URL. - The resulting URL is passed through trailing-slash normalisation.
Category pages
- Emitted when Add canonical tag to category pages is on.
- When Strip layered navigation parameters is on, these query parameters are removed:
p,product_list_order,product_list_dir,product_list_mode,product_list_limit,amshopby,shopbyAjax, plus any parameter whose name is all lowercase letters/underscores (Magento attribute filter params such ascolor,size) —qandpageare preserved. - Pagination (
?p=2and higher) is handled per the Pagination canonical strategy setting.
CMS pages
- Emitted when Add canonical tag to CMS pages is on.
- The canonical is the store base URL plus the page identifier, normalised for trailing slash.
Hreflang
When Enable hreflang tags is on, SEO Suite renders a block into head.additional on every page that outputs one <link rel="alternate" hreflang="…"> per active store view, followed by an x-default entry.
- Iterates every active store view in the installation.
hreflangvalue is the store'sgeneral/locale/codeconverted from Magento format to BCP-47 (en_US→en-US).- On a product or category page, each entry uses that product/category's URL in the target store's context — not just the base URL. Other page types fall back to the store base URL plus the current request path.
- The
x-defaulthref is the default store view's URL, or the store whose ID matches x-default store ID when that is set to a non-zero value.
x-default, which adds no value and can look like a misconfiguration to auditors.Robots.txt Editor
Under Marketing → SEO Suite → Robots.txt. A store-view switcher at the top of the page selects which scope you are editing — Default Config or a specific store view.
How it works
- Content is stored in Magento config at
ayasoftware_seo/robots/contentfor the chosen scope. - A plugin on Magento's robots.txt controller replaces the entire response with your saved content whenever the current store view has non-blank content. Leave it blank to fall back to Magento's built-in generation.
- Saving flushes the
configcache automatically, so changes are live immediately — no deploy or manual cache flush. - The ↩ Load Magento defaults button fills the editor with Magento's current generated robots.txt for the selected store view (via store emulation) as a starting point. If the box already has text, it asks for confirmation first.
AI crawler control
Because the editor replaces the whole file, you can add explicit User-agent blocks for AI crawlers — GPTBot, ClaudeBot, PerplexityBot, Google-Extended, and others — to allow or block them per store view:
User-agent: GPTBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Google-Extended
Allow: /
User-agent, Disallow, Allow, Sitemap. Remember to include your Sitemap: line — Magento's default output adds it, but your custom content fully replaces that default.Redirect Manager
A 301/302 redirect engine with a full admin grid under Marketing → SEO Suite → Redirects. The redirect router runs early in Magento's request pipeline (sort order 21, before the CMS router at 60), so a matched redirect is resolved before any page rendering begins. Only active rules for the current store — plus global rules — are loaded per request.
Rule fields
| Field | Notes |
|---|---|
| Source Path | The path to match from. For exact/prefix use a path like /old-page.html; for regex use a full PHP pattern like /^\/old\/(.*)/. |
| Target Path / URL | Where to send the request. A path (/new-page.html) or a full URL. For regex, $1, $2… back-references are substituted. |
| Redirect Type | 301 Permanent (recommended for SEO) or 302 Temporary. |
| Match Type | Exact, Prefix, or Regex — see below. |
| Store View | A specific store view, or All Store Views to apply globally (store_id = 0). |
| Active | Yes/No toggle to disable a rule without deleting it. |
Match types
- Exact — the request path equals the source path (trailing slashes ignored on both sides). Best for migrating individual pages.
- Prefix — the request path starts with the source path; whatever follows the prefix is appended to the target. One rule moves an entire old subtree, e.g.
/catalog/old-cat/→/new-cat/. - Regex — the source is a full PHP regular expression tested against the request path; the target is produced with
preg_replace, so$1-style back-references work. An invalid pattern simply never matches.
Admin grid
- Columns: ID, Source Path, Target Path, Type, Match, Store, Hits, Active, Updated.
- Filter and sort on every column; Add New Redirect and per-row Edit / Delete.
- Delete mass action for removing several rules at once.
- The Hits counter increments each time a rule fires in production (best-effort — a counter write failure never blocks the redirect itself).
404 Log
When Log 404 not-found requests is on, an observer on Magento's controller_action_noroute event records every 404 into ayasoftware_seo_404_log. View it under Marketing → SEO Suite → 404 Log.
- Each row stores request path, HTTP referrer, store view, hit count, and first-seen / last-seen timestamps.
- Entries are de-duplicated by request path + store view — a repeat hit increments
hit_countand updateslast_seenandrefererinstead of adding a row. - Grid columns: ID, Request Path, Referer, Store, Hits, Resolved, First Seen, Last Seen. All are filterable.
- Row actions: Create Redirect — opens the new-redirect form with Source Path pre-filled from the logged path — and Delete. A Delete mass action is also available.
- Resolved is a flag on each row. Pruning (see below) removes resolved rows first, so marking handled 404s as resolved keeps the useful ones in the log longer.
Automatic pruning
Before inserting a new row, if the table has reached Maximum 404 log rows, the oldest resolved entries (by last_seen) are deleted to make room; if that is not enough, the oldest unresolved entries are removed too. The log therefore stays bounded regardless of crawl volume.
GEO — /llms.txt
SEO Suite serves two plain-text files, generated live from catalogue data, that AI answer engines can read to understand and cite your store. A frontend router maps the two fixed paths to the generator.
| URL | Contents | Response headers |
|---|---|---|
/llms.txt |
Store name, welcome tagline, your store description, up to 50 active categories (level ≥ 2) with short descriptions, up to Products shown in /llms.txt visible products with short description and price, up to 30 active CMS pages, and a contact block. | Content-Type: text/plain; charset=UTF-8Cache-Control: public, max-age=3600 (1 hour) |
/llms-full.txt |
Same structure, but with full (longer, truncated at ~300 chars) product descriptions and up to Products shown in /llms-full.txt products. | Content-Type: text/plain; charset=UTF-8Cache-Control: public, max-age=21600 (6 hours) |
/llms.txtreturns 404 when Enable /llms.txt is off./llms-full.txtreturns 404 unless both Enable /llms.txt and Enable /llms-full.txt are on.- Output is scoped to the store view resolved from the request URL, so a multi-store install serves a different file per domain / store.
- Files carry a public
Cache-Controlmax-age so a CDN or the browser can cache them; there is no server-side generated-file cache, so a request that reaches Magento always reflects current catalogue data.
Troubleshooting
A page has two canonical tags
Another source is still emitting one. SEO Suite removes only Magento's native product canonical. For categories/CMS, disable Magento's own canonical options under Stores → Configuration → Catalog → Catalog → Search Engine Optimization, and check your theme and any other SEO module.
Canonical still shows layered-nav parameters
Confirm Strip layered navigation parameters is on for that store view. Note the stripper removes parameters whose name is all lowercase letters/underscores; a filter parameter containing digits or uppercase in its key (unusual) would be kept.
Configurable canonical still points at the simple product
- Canonical for configurable product variants must be set to Parent.
- The child must be a genuine
simpleproduct actually assigned to a configurable — standalone simples have no parent and correctly self-canonicalise.
Redirect isn't firing
- Rule must be Active and scoped to All Store Views or the current store view.
- For Exact, the path must match apart from a trailing slash. For Regex, test the pattern — an invalid regex silently never matches.
- An earlier rule may have matched first. The first match wins; reorder so specific rules precede broad prefix/regex rules.
- Full-page cache can serve a cached 200 for a URL you just added a rule for — flush FPC or wait for it to age out.
Custom robots.txt isn't being served
- Content is scoped per store view — make sure you saved it against the right scope in the store switcher, and that you are requesting the matching domain.
- A blank editor falls back to Magento's default output by design.
- If a CDN or web server serves a static
robots.txtfile before the request reaches Magento, that file wins — remove it.
/llms.txt or /llms-full.txt returns 404
/llms.txt needs Enable /llms.txt on. /llms-full.txt needs both GEO toggles on. After changing config, run bin/magento cache:flush.
“Front controller reached 100 router match iterations” on /llms.txt
Fixed in 1.0.1 — update to the current release.
Admin menu items missing after install/update
In production mode Magento compiles the list of valid admin controller actions. Run bin/magento setup:di:compile (and setup:upgrade) after installing or updating so the new routes are recognised.
Changelog
Fixes & Improvements
- FixRobots.txt editor blank-screen fix — replaced the generic admin block with a dedicated
Block\Adminhtml\Robots\Editclass and removed a broken store-switcher instantiation and a deprecated helper call that crashed the page before it could render. - FeatNew ↩ Load Magento defaults button above the textarea loads Magento's current per-store-view robots.txt output (via store emulation) as an editable starting point, with a confirmation prompt if the box already has content.
- Impr
composer.jsonversion bumped to1.0.2.
Fixes
- FixResolved a “Front controller reached 100 router match iterations” error when requesting
/llms.txtor/llms-full.txt. The custom router now exits immediately once Magento has forwarded to the module, preventing the infinite dispatch loop. - Impr
composer.jsonversion updated to1.0.1.
Initial release
- FeatCanonical URL Control — per-type canonicals for product, category, and CMS pages, with layered-nav parameter stripping, configurable-parent routing, pagination strategy, and trailing-slash normalisation.
- FeatHreflang — auto-generated alternate tags for multi-store setups with
x-defaultsupport. - FeatRobots.txt Editor — per-store-view robots.txt editing in the admin; fully replaces the default output when content is set.
- FeatRedirect Manager — 301/302 rules with exact, prefix, and regex matching; admin grid with hit counter and store-view scoping.
- Feat404 Log — tracks every 404 with hit count, referrer, and first/last seen timestamps, with one-click redirect creation.
- FeatGEO / LLM sitemaps — generates
/llms.txtand/llms-full.txtfollowing the llmstxt.org format for visibility in AI answer engines.