# Changelog of Technical SEO Audit & Monitor: Broken Links, Redirects (`succinct_glider/technical-seo-audit`) Actor

- **URL**: https://apify.com/succinct\_glider/technical-seo-audit/changelog.md
- **Full Actor documentation**: https://apify.com/succinct\_glider/technical-seo-audit.md

## Changelog

All notable changes to this Actor are documented here. The output fields are a contract: no field is
renamed, removed or retyped outside a major version.

### \[Unreleased]

#### Store page (2026-09-18)

- Icon uploaded (the console asks to confirm the crop before the form can be saved), third category fixed to
  `AUTOMATION` (`MARKETING` does not exist in the Store and was dropped silently).
- README: what happens during a run, the fields returned for every page, an example run summary, and two
  questions on staging sites and on run duration and compute cost.

#### Changed (2026-09-17, build 0.1.5)

- `maxPagesPerSite` is capped at 2,000 (was 10,000): 1,000 pages were measured at 618 MB on the platform, and
  larger audits were not verified within the default 1 GB.

#### Fixed (2026-09-17, build 0.1.4, tag `beta`)

- A crawl cut short by the maximum cost per run now says so (run message, site detail, `budgetReached` in
  `SUMMARY`) instead of reporting that the site had more pages than the page limit. Verified on the platform
  with a $0.05 limit: 10 pages saved and charged, then a clean stop.

#### Fixed (2026-09-17, build 0.1.3, tag `beta`, private)

- Dual-stack sites could fail on the platform with an empty `ETIMEDOUT` (robotstxt.org): Node gave each
  IPv6/IPv4 connection attempt 250 ms, and the platform has no IPv6 route. Attempts now get 2.5 s, for page
  requests, robots.txt and sitemaps alike.
- A network error with an empty message is now reported with its code (`fetchError`, run summary).

#### Fixed (2026-09-17, build 0.1.2, tag `beta`, private)

- Memory: build 0.1.1 ran out of 1 GB after 240 pages. With the Cheerio crawler, the crawling context held
  each page's DOM, and the timers the request queue starts during a request kept that context alive under
  Node 24. The crawl now uses a plain `BasicCrawler` that streams each response: the HTML lives only in the
  handler, non-HTML bodies are not downloaded, HTML is capped at 5 MB, and each page is parsed once instead
  of twice. Measured locally: heap flat at about 57 MB over 120 pages, instead of about 1.5 MB more per page.

#### Added (2026-09-17, version 0.1, not published yet)

- HTTP crawl of one or more websites from a start URL, without following redirects, within the site's host
  (`www.` and the bare domain are one site; subdomains on request), robots.txt always respected, identified
  as `TechnicalSeoAuditBot`.
- Sitemap discovery from robots.txt, or `/sitemap.xml`; sitemap-only pages are audited after the link crawl.
- One item per URL: status, redirect, response time, indexability and reason, title, meta description, H1,
  canonical, robots meta and `X-Robots-Tag`, `lang`, hreflang, JSON-LD types, word count, link counts,
  broken internal links, inlinks, sitemap presence, issues with severity, score.
- 37 issue codes, including site-wide checks: duplicate titles and descriptions, orphan pages, sitemap
  entries that are not indexable, pages missing from the sitemap.
- Change tracking between runs (`trackChanges`, `onlyChanges`): new, changed, unchanged and removed pages,
  with changed fields, previous values, new and fixed issues. Removed pages are only reported after a
  complete crawl.
- `SUMMARY` record per run: per-site status (`ok`, `unreachable`, `disallowed`, `redirected_away`,
  `not_reached`), average score, top issues. Blocked or disallowed sites are not charged and do not fail the
  run; the run fails only if most HTML pages come back with no title and no link (parser check).
- Pay-per-event ready: the cost limit is checked before every saved item.
