Site Linkcheck is a configurable Playwright link checker. It crawls internal pages, validates internal and external links, and writes JSON/CSV reports.
Use the published npm package:
npm install -g site-linkcheck
linkcheck --versionOr run it without installing globally:
npx site-linkcheck --versionFor local development from source:
nvm use
npm install
npx playwright install chromiumnpm run config:validate
npm run checkRun any website directly:
npx tsx src/run.ts crawl https://example.com --max-depth 1 --max-links 100 --reports-dir reportsRun from configuration:
npx tsx src/run.ts crawl --config linkcheck.config.json --target examplelinkcheck crawl <url>
linkcheck crawl --config linkcheck.config.json --target example
linkcheck config validate --config linkcheck.config.json
linkcheck reports merge reports
linkcheck notify --provider slack --report reports/_merged-file.json
linkcheck notify --provider telegram --report reports/_merged-file.jsonUseful crawl options:
--entrypoint <path>repeatable entrypoint override.--max-depth <number>crawl depth.--max-requests <number>max pages per crawl.--max-links <number>max checked links per crawl (0in config means unlimited).--concurrency <number>parallel browser work.--timeout <ms>navigation timeout.--exclude <pattern>paths to check but not crawl recursively.--ignore-extension <ext>URL extensions to skip.--storage-state <path>Playwright storageState file.--header <name:value>custom HTTP header.--skip-from-reportsincremental mode.--fail-on-brokenexit with code2when broken links are found.--jsonmachine-readable command output.
The default config lives in linkcheck.config.json and is described by
schemas/linkcheck.schema.json.
{
"$schema": "./schemas/linkcheck.schema.json",
"targets": {
"example": {
"baseUrl": "https://example.com",
"entrypoints": ["/"],
"crawl": {
"maxDepth": 1,
"maxRequestsPerCrawl": 50,
"maxLinksToCheckPerCrawl": 0,
"concurrency": 2
}
}
},
"reports": {
"directory": "./reports",
"formats": ["json", "csv"]
},
"notifications": []
}Authentication is optional. For authenticated checks, generate a Playwright storage state yourself and reference it:
{
"targets": {
"private-docs": {
"baseUrl": "https://docs.example.com",
"auth": {
"storageState": "./secrets/docs.storage.json",
"headers": {
"x-linkcheck-run": "ci"
}
}
}
}
}Do not store secrets in config. Use environment variables or CI secrets.
Slack is optional:
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
npx tsx src/run.ts notify --provider slack --report reports/_merged-file.jsonTelegram is optional:
export TELEGRAM_BOT_TOKEN="..."
export TELEGRAM_CHAT_ID="..."
npx tsx src/run.ts notify --provider telegram --report reports/_merged-file.jsonThis repository includes both .github/workflows/ci.yml and .gitlab-ci.yml.
Both run the same project commands:
npm ci
npx playwright install chromium
npm run typecheck
npm test
npm run test:coverage
npm run config:validateScheduled crawl jobs should call npm run check or a target-specific
linkcheck crawl --config ... --target ... command.
0: command completed.1: runtime error.2: broken links were found with--fail-on-broken.3: invalid arguments or configuration.4: required notification failed.
nvm use
npm run typecheck
npm test
npm run test:coverage