Skip to main content

Hreflang validator

Crawls all stores' product / category / CMS catalogs (in-database — no HTTP requests) and reports hreflang health issues.

What it checks

CodeSeverityWhat it detects
missing_reciprocalwarningEntity exists in stores A + B but not in C → hreflang chain incomplete
no_pair_foundwarningEntity exists in only one store → no cross-store hreflang at all
missing_x_defaultwarningx-default enabled but no x-default store selected
duplicate_hreflangwarningTwo stores produce the same hreflang locale → Google picks one arbitrarily
invalid_localeerrorStore's locale config produces something Google can't parse

CLI

bin/magento seosuite:hreflang:validate

Output:

+---------+--------------------+----------+-------+--------+----------------------------------------------------+
| Severity| Code | Entity | Store | Target | Message |
+---------+--------------------+----------+-------+--------+----------------------------------------------------+
| warning | missing_reciprocal | product | 1 | 1234 | Product "AWP-001" missing in store(s) 3 — chain… |
| warning | duplicate_hreflang | store | 2 | - | Stores 1 and 2 emit the same hreflang locale "en"… |
| error | invalid_locale | store | 4 | - | Store "fr_misconfigured" produces invalid locale " " |
+---------+--------------------+----------+-------+--------+----------------------------------------------------+

Total: 3 issue(s) — errors: 1, warnings: 2.

Options

bin/magento seosuite:hreflang:validate
[-l <limit>] # Inspect at most N entities per type per store
[-f <format>] # table (default) | json

JSON output for CI

bin/magento seosuite:hreflang:validate --format json
{
"errors": 1,
"warnings": 2,
"issues": [
{
"severity": "warning",
"code": "missing_reciprocal",
"entity_type": "product",
"store_id": 1,
"target_id": 1234,
"message": "Product \"AWP-001\" missing in store(s) 3 — hreflang chain is incomplete."
}
]
}

Exit code is 1 when any errors are detected, 0 otherwise — useful as a gate in deploy pipelines.

Admin grid

Same data, persisted: Marketing → SEO Suite → Hreflang Health.

Click Run Scan in the toolbar → results land in byte8_seosuite_hreflang_issue and the grid renders. Each scan replaces the previous, so the grid always reflects current state.

Filter by severity, code, entity type, or store. Per-row actions:

  • Auto-Match (only on missing_reciprocal / no_pair_found for product/category) — runs the auto-matcher and marks the row resolved
  • Mass-dismiss — bulk mark resolved without action (for known-acceptable warnings)

Nightly cron

Off by default. Enable in Stores → Configuration → SEO Suite → Admin Dashboard → Enable nightly Hreflang scan (cron).

The job byte8_seosuite_hreflang_scan runs at 30 2 * * * daily. If it finds errors AND notify_on_errors = Yes, an entry lands in the admin bell-icon inbox.

Limitations

  • No HTTP crawling — the validator inspects database state, not actual rendered pages. If a third-party module overrides hreflang rendering, the validator won't catch the divergence.
  • Doesn't check Magento's URL Rewrite table for product/category URL key changes that broke pre-existing hreflang chains. Use the Index Budget Audit for those.

Next

  • Auto-matcher — discover and persist cross-store hreflang pairs