pagetrace

Your deploy dropped a canonical from 400 pages. Nothing told you.

pagetrace records your site's SEO and AEO surface as a committed lockfile, then diffs every build against it. Plenty of tools score a page's current state. This one tells you what this deploy changed — and fails the build over it.

$ npm i -D pagetrace
Check a page now Try the playground
npx pagetrace check --dir ./out
(site-wide)
  error GPTBot is now blocked.    aeo.crawler.newly_blocked

/pricing
  error Canonical was removed.    canonical.removed
  error Page became noindex.      robots.noindex.added
  warn  Links to /plans-old.      link.broken.added

/blog/launch
  error Article entity removed.   jsonld.entity.removed

Failing: 4 error, 1 warning.
exit 1

Why a diff

A page can be perfect and still be a regression

Every auditor answers "how is this page doing?" — a score, out of context, on a day you happened to look. That question cannot see the thing that actually hurts: a template edit that silently changed 400 pages between Tuesday and Wednesday.

State-based tools

"This page scores 82."

True yesterday, true today, true after the canonical disappeared — because the score was never compared against anything. You find out from the traffic graph, six weeks later.

pagetrace

"This deploy removed the canonical."

Severity comes from the transition, not the state. A reworded title is info. A removed canonical is error, and the build stops. Routine content churn stays quiet, which is the only reason anyone leaves the gate switched on.

Playground · no install

Run the real rule engine, right here

This is not a demo of the tool — it is the tool. extract, audit and diff are pure functions with no I/O, so the exact code that ships on npm is compiled into this page. Nothing you paste leaves your browser.

Page HTML edit freely — findings update as you type
Rendered HTML

Browsers cannot read another site directly, so this route goes through a public CORS proxy — your URL is visible to that service. Paste the HTML instead for anything private.

0 error 0 warning 0 info exit 0
Fingerprint — what it records

What the browser cannot do, the CLI does: dead internal and external links, redirect drift, sitemap health, duplicate titles across a site, hreflang reciprocity. Those need a crawl — npx pagetrace audit --url https://your-site.com.

The CLI

Seven commands, one question each

Every crawling command takes --dir <build> or --url <origin>. Exit codes are the same everywhere: 0 clean, 1 findings at or above --fail-on, 2 the run itself broke — so CI can tell a regression from an outage.

CommandAnswersCrawls
initGet me set upOnce, to write the first lockfile
snapshotRecord what the site looks like nowWhole site
checkWhat did this deploy change?Whole site
auditWhat is wrong with this site?Whole site
linksAre any links dead?Whole site
page <url>Is this one page sound?That URL alone
updateAm I on the latest pagetrace?Nothing

Useful flags: --external checks outbound links, --verify-all adds assets like PDFs, --ignore-robots crawls a staging origin that disallows everything, and --format takes pretty, json, markdown, github or sarif.

Finding codes

What it catches

Codes are the public contract — integrations key on canonical.removed, never on the prose. A selection; the full set covers hreflang, AEO signals, structured data and llms.txt.

CodeSeverityFires when
canonical.removederrorA page lost its canonical tag
robots.noindex.addederrorA page became noindex
jsonld.entity.removederrorA structured data entity disappeared
jsonld.property.removederrorAn entity lost a property it used to have
content.droppederrorWord count fell by more than half — usually a render failure
link.broken.addederrorA page started linking to a URL that does not exist
sitemap.deaderrorThe sitemap lists a URL that answers 404
aeo.crawler.newly_blockederrorrobots.txt started blocking an AI crawler
redirect.addedwarnA route that used to answer directly now redirects
canonical.redirectswarnA canonical points at a URL that redirects
link.external.deadwarnAn outbound link answers 404
title.changedinfoOrdinary copy edit — never fails a build

Continuous integration

Where it earns its keep

The GitHub Action diffs each pull request against the lockfile committed on your default branch and leaves the result as a comment, updating that same comment on every push instead of stacking new ones. Feature branches carry no lockfile, so there is no churn to review.

- uses: actions/checkout@v5
- run: npm ci && npm run build
- uses: shyamexe/pagetrace@v1
  with:
    dir: ./out
    baseline-branch: main

Prefer the Security tab? --format sarif piped into github/codeql-action/upload-sarif turns findings into pull request annotations that outlive any comment.

Who makes this

Built and maintained by Shyam

$_

I write and maintain pagetrace — the CLI, the GitHub Action, the rule tables, and this page. It exists because I shipped a template change that quietly dropped canonicals across a site and found out from analytics, weeks after the deploy that caused it.

It is MIT licensed, has three small dependencies on purpose, and publishes with npm provenance, so every release traces back to the tagged commit and the workflow that built it.