etechflow / module-seo-audit

etechflow/module-seo-audit

On-demand SEO health audit + score for Magento 2: scans products, categories and CMS for meta/content/link/schema issues and links each to the fix. Part of the Etechflow SEO Suite.

magento2-module Compatibility: 2.4.7-2.4.8 Code Quality: Fail Tests: N/A Security: Pass proprietary

Etechflow_SeoAudit

On-demand SEO health audit + score for Magento 2. Scans your products, categories and CMS pages for SEO problems, gives the store a 0-100 health score, and lists every issue in an admin grid — each one tagged with the suite module that fixes it. Part of the Etechflow SEO Suite.

What it checks

Area Checks
Meta products/categories/CMS missing meta title or description, duplicate meta titles or descriptions, meta titles/descriptions too short/long
Content thin or missing product descriptions, products with no base image, and (rendered) pages whose main image has no alt text or with a missing/duplicate H1
Links logged 404s and redirect chains (via Etechflow_RedirectManager — soft dependency)
Canonical rendered-HTML check on a sample of product pages: missing canonical, duplicate canonical tags, or a canonical that points to a URL which redirects (301/302) or 404s — the kind of render-time fault data-only checks can't see
Indexability rendered-HTML checks for pages quietly lost from Google: live (200) pages returning noindex (robots meta or X-Robots-Tag), live catalogue URLs blocked by robots.txt, and dead/redirecting URLs listed in the XML sitemap (plus a sitemap not referenced in robots.txt)
Social rendered-HTML check: product pages missing Open Graph / Twitter Card tags (how links look when shared), or an og:url on a different domain than the store (catches dev/staging-domain leakage after a domain swap)
Schema rendered-HTML check: product pages with no Product JSON-LD structured data (Google's preferred format for rich results — price, availability, ratings). Handles @graph and arrays

Each check is a small class implementing Api\CheckInterface, registered into the scanner pool in etc/di.xml — so you can add your own checks without touching core.

How it works

  • Scanner runs every registered check (most are fast, SQL-backed; the canonical and indexability checks fetch a sample of rendered pages over HTTP via the shared Service\HtmlFetcher), replaces the issue table with fresh findings, and stores a summary (score + counts) via FlagManager.
  • Rendered-HTML checks read live pages, so for origins behind Varnish / basic-auth / an edge gate they can fetch an internal endpoint instead of the public URL. Configure once under Stores → Config → Etechflow → SEO Audit → Page Fetch (sample size, optional fetch base URL + basic auth; the store domain is sent as the Host header). Each rendered group (Canonical, Indexability) has its own enable toggle.
  • ScoreCalculator turns issue counts into a transparent 0-100 score: penalty = critical×3 + warning×1 + notice×0.3, normalised against the number of products + categories + CMS pages.
  • Admin dashboard (Content → SEO Audit) shows the score, a severity/area breakdown, a Run SEO Scan Now button, and the full issue grid. Each row links to the entity and names the Fix with module.
  • CLI: bin/magento etechflow:seoaudit:scan.

The suite hook

The audit is the finder; the rest of the Etechflow SEO Suite is the fixer. Findings point at the tool that resolves them:

  • Missing / duplicate / poor meta → Etechflow_MetaTemplates or Etechflow_AiSeo
  • 404s & redirect chains → Etechflow_RedirectManager
  • Canonical pointing at a redirect / duplicate / missing → Etechflow_CanonicalHreflang
  • Pages hidden from Google (noindex / robots.txt) → review robots directives; sitemap hygiene → core sitemap config
  • (Structured-data gaps → Etechflow_RichSnippets)

Install

composer require etechflow/module-seo-audit
bin/magento module:enable Etechflow_SeoAudit
bin/magento setup:upgrade
bin/magento setup:di:compile     # production

Configure

Stores → Configuration → Etechflow → SEO Audit — tune the meta-title/description length thresholds and the thin-description cutoff. Then Content → SEO Audit → Run SEO Scan Now.

License

Proprietary — © eTechFlow.

Changelog

All notable changes to this module are documented here.

v1.5.0 — 2026-06-08

Two dashboard improvements so findings are actionable:

  • Score impact per check — the scan summary now carries a by_check breakdown with the exact score points each check would recover if fixed (ScoreCalculator::pointsFor()), and the admin dashboard renders a "Fix priority" table sorted by recoverable points. You can see at a glance that, e.g., fixing meta-title lengths is worth +20 and social tags +1.
  • Open each issue on the live site — every finding now stores a resolved frontend_url (new column), and the issue grid adds a "View on site" action next to "Edit". Product/category URLs are batch-resolved from url_rewrite; rendered-check findings use their path. So a merchant can jump from any finding straight to the live page and see the problem.

v1.4.1 — 2026-06-08

Fixed a false-positive: the image-alt check now reads rendered HTML instead of the image_label DB attribute. The old check (product_missing_image_alt) flagged every product with an empty image_label, but most themes (Hyvä, Luma) fall back to the product name for the <img alt>, so an empty label rarely means a truly missing alt — it over-reported badly (e.g. ~2,900 false notices on a Hyvä store). Replaced with content_image_alt: it samples product pages and flags a page only when a product image is present but neither a gallery caption/label nor an <img alt> supplies alt text (gated by the same on-page/page-fetch settings as the H1 check).

v1.4.0 — 2026-06-08

Added duplication & on-page checks:

  • product_duplicate_meta_description (warning) — products sharing an identical meta description.
  • product_meta_description_length (notice) — meta descriptions outside the configured length range.
  • product_missing_image_alt (notice) — visible products with a base image but no alt text (image label).
  • onpage_h1 (warning, rendered) — product pages with a missing or duplicate H1.

v1.3.0 — 2026-06-08

Added visibility rendered-HTML checks:

  • social_open_graph (warning) — product pages missing Open Graph / Twitter Card tags, or an og:url whose domain differs from the store domain (catches dev/staging-domain leakage after a base-URL/domain swap).
  • schema_product_jsonld (warning) — product pages with no Product JSON-LD structured data. Walks @graph containers and arrays to find a Product @type.

v1.2.0 — 2026-06-08

Added indexability checks (the "hidden from Google" catchers) and refactored the HTTP fetching into a shared Service\HtmlFetcher:

  • indexability_noindex (critical) — live pages (HTTP 200) returning noindex via robots meta or X-Robots-Tag header, across sampled product + category pages.
  • indexability_robots_blocked (critical) — live catalogue URLs blocked from crawling by robots.txt (parses the User-agent: * Disallow/Allow rules and tests real product/category/home paths).
  • indexability_sitemap_health (warning) — XML sitemap missing, not referenced in robots.txt, or listing URLs that 404 / redirect (follows one level of sitemap-index, samples URLs evenly).

Config reorganised: the shared Page Fetch group (etechflow_seoaudit/fetch/* — sample size, base URL, basic auth) now drives all rendered-HTML checks, each with its own enable toggle (Canonical, Indexability).

v1.1.0 — 2026-06-08

Added a canonical health check (product_canonical_health) — the first check that reads rendered HTML over HTTP rather than catalog data at rest. On a configurable sample of product pages it flags a missing canonical, more than one canonical tag, or a canonical whose target redirects (301/302/…) or 404s (a canonical must resolve to a live 200 URL). New config group etechflow_seoaudit/canonical/* (enable, sample size, optional fetch base URL + basic auth) so the check works against origins behind Varnish / basic-auth / an edge gate.

v1.0.0 — 2026-06-05

Initial public release.

On-demand SEO health audit + 0-100 score. Scans products/categories/CMS for meta/content/link issues, links each finding to the fixing module. CLI scan, admin grid, pluggable checks.

Versions
Version Stability QA Status Compatibility Released
1.6.1 stable Fail Magento 2.4.7-2.4.8 Details 2026-06-22 09:29:12
1.6.0 stable Not tested Not yet tested Details 2026-06-19 14:17:48
1.0.0 stable Not tested Not yet tested Details 2026-06-05 10:27:43

Requires 6

Package Constraint
magento/framework >=103.0
magento/module-backend >=102.0
magento/module-catalog >=104.0
magento/module-cms >=104.0
magento/module-store >=101.0
php ~8.1.0||~8.2.0||~8.3.0||~8.4.0

Compatibility

Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.

Compatibility matrix (Magento × PHP)
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 Pass Pass
2.4.8 Pass Pass
2.4.9 Pass not tested

Code Quality

Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge — a phpcs finding can't make a module incompatible.

Static analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

Static analysis results
Tool Status Findings Summary
PHPCS Fail 487 5 errors, 482 warnings (ruleset: Magento2) — 349 auto-fixable with phpcbf
PHPMD Warning 27 27 rule violations (CyclomaticComplexity:6, NPathComplexity:6, MissingImport:5, UnusedFormalParameter:2, CountInLoopExpression:2)
Cpd Warning 2 2 duplicated chunks spanning 49 total lines (min-lines=5, min-tokens=70)
Composer validate Info 6 valid; 6 advisory notes (composer validate --strict)

PHPStan

Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases. Cell → details modal.

PHPStan results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 11 11
2.4.8 11 11
2.4.9 11 N/A

Tests

Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.

Unit tests

Unit tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Integration tests

Integration tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Security

Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.

Security results
Tool Status Findings Summary
Composer audit Pass 0
Malware scan Pass 0
License
proprietary

More from etechflow

View vendor
Make it pay

Turn an existing module into recurring revenue.

If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.