# Changelog of SEO Audit Crawler (`humble-echidna/seo-audit`) Actor

- **URL**: https://apify.com/humble-echidna/seo-audit/changelog.md
- **Full Actor documentation**: https://apify.com/humble-echidna/seo-audit.md

## Changelog

Versions follow MAJOR.MINOR.PATCH (`src/version.py`); Apify shows MAJOR.MINOR from `.actor/actor.json`.
Every run logs its version and records it in the `RUN_STATS` key-value record.

### 1.0.1 (2026-09-24)

- The link-check scheduling (hosts take turns, at most 2 checks at a time each; a host that answers 429 is left
  unchecked for the rest of the run) moved to the shared `common/mms_linkcheck`, so Bulk URL & Broken Link Checker
  uses it too. Same results; one difference in timing: a worker no longer waits for a busy host while another
  host's link is ready.

### 1.0.0 (2026-09-24)

First release.

- Audits the on-page SEO of a site the user gives it: pages are found by crawling same-site links from start URLs,
  or from the site's sitemaps (robots.txt `Sitemap:` lines, else /sitemap.xml; the same discovery as Sitemap URL
  Extractor), up to a crawl depth and a max pages per run.
- Per page: HTTP status, redirect chain, response time, content type and size, title and its length, meta
  description and its length, H1 count and text, canonical URL, robots meta and X-Robots-Tag, indexable,
  `<html lang>`, hreflang alternates, Open Graph and Twitter tags present, JSON-LD `@type` values (types only),
  image count and alt coverage, internal/external link counts, word count, broken links, and a list of issues with a
  severity (error, warning, notice).
- Broken links: every distinct link on the audited pages is checked once per run with the same checker as Bulk URL &
  Broken Link Checker (HEAD first, GET when HEAD answers an error); links to pages the crawl reads reuse that
  answer. Optional, with a per-run cap and an on/off switch for other sites' links. Hosts take turns (at most 2
  checks at a time each), and a host that answers 429 is left unchecked for the rest of the run, so one
  rate-limiting site can't stall the run.
- A site summary in the `SUMMARY` key-value record (not charged): status codes, issue totals per severity and per
  issue, worst pages, duplicate titles and meta descriptions, every broken link with the pages it's on, slowest
  pages, averages, structured data types, and the pages that were never requested.
- robots.txt respected on every request and redirect hop (a disallowed page is never requested and not charged);
  Crawl-delay honoured; at most 2 requests at a time per site; public addresses on ports 80 and 443 only.
- No third-party SEO data (no rankings, backlinks or traffic estimates): only what the site itself serves.
- Charged per page audited, through Apify's standard `apify-default-dataset-item` event. Max pages per run and the
  maximum cost per run are honoured before a page is requested.
- Failure isolation: a page that can't be read, or a start URL that fails, only affects itself.
