sitemap-validator

n8n node to load a sitemap and validate every URL inside it: 404 links, 5xx errors, redirect chains, timeouts, and missing lastmod. Can output an Excel report

Package Information

Released: 2 mo ago
Downloads: 0 weeklyΒ /Β 0 monthly
Latest Version: 0.2.1

Documentation

πŸ—ΊοΈ n8n Sitemap Validator

A custom n8n Community Node that loads your sitemap and smoke-tests every single URL inside it β€” before your users do.

Catch broken links, server errors, redirect loops, and timeouts in one pass, and turn the results into a ready-to-use report in your workflow.

npm version
License: MIT
Node
n8n


✨ The problem it solves

Sitemaps are your source of truth for what your site should be serving β€” and they rot silently. Pages get deleted, routes change, certificates expire, and a 404 hides behind a redirect. Your crawlers might even pick up URLs that should never have been published in the first place.

Most people find out from Google Search Console β€” weeks later. This node runs the check now, on demand, as part of your automation:

  • πŸ” Schedule a weekly SEO health-check workflow.
  • ⚠️ Pipe the output into Slack / Email / n8n-formatted-notification the moment a broken link appears.
  • 🧹 Run it before a site migration or relaunch to verify nothing breaks.
  • πŸ“Š Store results in a database and track link-health over time.

Give it a sitemap URL, get back one item per URL with its status, redirect chain, and a rollup summary β€” nothing to configure, everything to filter on.


βœ… What it catches

Issue How it's flagged
πŸ”΄ Broken links Any URL returning 404 Not Found
🟠 Server errors 5xx responses (500, 502, 503, …)
🟠 Client errors Other 4xx responses (401, 403, 410, …)
πŸ” Redirect chains Every hop recorded (from β†’ to β†’ status), so nothing is hidden
β›” Redirect loops A chain that points back at itself β€” detected before it hangs
πŸ“ Too many redirects Chains exceeding your configured hop limit
⏱️ Timeouts URLs that don't answer within the configured window
πŸ“… Missing lastmod Optional β€” flag URLs published without a <lastmod> element
🌐 Network errors DNS failures, TLS issues, connection refused, aborted requests

Plus: it resolves sitemap indexes, nested sub-sitemaps, and gzip-compressed .xml.gz files automatically β€” no extra steps.


πŸ“¦ Installation

Prerequisites: Node.js β‰₯ 18.10

There are two ways to install: automatic (recommended β€” a few clicks) and manual (copy the package into the folder where n8n loads custom nodes). Either way, restart n8n afterwards so the node shows up in the editor.

πŸ€– Automatic install

Method 1 β€” Install from inside n8n (recommended)

The easiest way; straight from the n8n UI:

  1. Open your n8n admin panel and go to Settings β†’ Community Nodes.
  2. Click Install.
  3. Search for and install the package n8n-nodes-sitemap-validator.
  4. Restart n8n.

After the restart, the Sitemap Validator node appears in the editor under Transform.

Method 2 β€” Global install via npm

If you have shell access, install the package once on the system and it becomes available to every n8n instance on that machine:

npm install -g n8n-nodes-sitemap-validator

Then restart n8n. (Thanks to the n8n-community-node-package keyword in package.json, n8n picks it up automatically.)

πŸ–οΈ Manual install

If you want exact control over which version gets installed, or there's no UI option available:

Method 3 β€” Copy into the custom-nodes folder

Obtain the package (e.g. build it from the repo with npm pack ., or download it from npm), then place it in n8n's standard custom-nodes folder:

mkdir -p ~/.n8n/nodes
cp -R ./n8n-nodes-sitemap-validator ~/.n8n/nodes/

And restart n8n.

Method 4 β€” Upload the package in n8n

Package it as an archive file (npm pack . β†’ .tgz), then:

  1. Go to Settings β†’ Community Nodes.
  2. Click Install and choose Upload package.
  3. Select the archive, install it, and restart n8n.

βœ… For the npm route, the n8n-community-node-package keyword and the n8n block in package.json are already in place β€” just like official n8n community nodes.


🧭 Usage in a workflow

Connect the node to any trigger and tell it what to check. The Input Format dropdown decides how the Sitemap URL / XML / URLs field is read β€” including from incoming data via an expression, e.g. ={{ $json.sitemapUrl }}:

Input Format What goes in the field
Sitemap URL (default) The URL of a sitemap β€” index files, nested sub-sitemaps and .xml.gz are all handled
Raw XML Paste a <urlset> or <sitemapindex> document directly
URL List A newline- or comma-separated list of URLs to check directly
Option Default Description
Max URLs to Check 0 (all) Check only the first N URLs β€” set 20 for a quick preview that returns fast
Concurrency 20 Max URLs checked in parallel (1–100)
Timeout (ms) 10000 Per-request timeout before a URL is flagged
Max Redirects 5 Max hops to follow (also catches loops)
Request Method HEAD HEAD is fast & cheap; switch to GET if a server misbehaves on HEAD
Check lastmod on Flag URLs missing a <lastmod> element
User Agent (default) Custom User-Agent for sites sensitive to bot-blocking
Only Show Status (all) Keep only results whose status is one of the chosen values
Only Show Status Codes (all) Keep only results with these HTTP codes, e.g. 200 for healthy pages
Only Show URLs with Issues off Keep only rows that have at least one issue (the broken ones)
Attach Excel Report off Attach a real .xlsx report as binary data on the first output item
Excel File Name sitemap-report.xlsx File name of the attached Excel report
Show Progress on Report checked/total progress in the run messages and n8n logs while validating

πŸ’‘ Tip: point it at a live sitemap index (e.g. https://example.com/sitemap.xml) that links to sub-sitemaps β€” the node follows the whole tree and validates every URL across all of them.

βš™οΈ Filtering the output

The output fields (statusCode, status, isValid, issues, …) are fully filterable by n8n's built-in Filter node, but you can also filter inside this node with the Options β†’ Only Show … settings. For example:

  • Only healthy pages β†’ Only Show Status Codes: 200
  • Only what broke β†’ Only Show URLs with Issues: on
  • Only redirects & server errors β†’ Only Show Status: redirect, server_error

The report/summary on every item always reflects the whole run, before filtering.

πŸ“Š Excel report

Turn Attach Excel Report on and the first output item carries a real .xlsx file as binary.data β€” no external library involved. The sheet ships with a frozen header row and column filters, so you can filter the report right inside Excel. Download it with a Write Binary File to Disk node, or email it with the Email / Send Email nodes:

Sitemap Validator ──► Write Binary File to Disk   (binaryPropertyName: data, fileName: sitemap-report.xlsx)

πŸ“€ Output

The node emits one item per URL, each carrying the full validation result plus the sitemap-wide summary:

{
  "url": "https://example.com/page",
  "lastmod": "2024-01-01",
  "hasLastmod": true,
  "statusCode": 200,
  "finalUrl": "https://example.com/page",
  "redirectCount": 0,
  "redirectChain": [],
  "error": null,
  "issues": [],
  "isValid": true,
  "status": "ok",
  "summary": {
    "sitemapUrl": "https://example.com/sitemap.xml",
    "inputFormat": "url",
    "totalUrls": 50,
    "checkedUrls": 50,
    "valid": 40,
    "validCount": 40,
    "issueCount": 10,
    "successRate": 80,
    "limited": false,
    "limit": null,
    "statusCodes": { "200": 39, "301": 5, "404": 3, "500": 1, "timeout": 2 },
    "issues": {
      "broken_link_404": 2,
      "client_error_4xx": 0,
      "server_error_5xx": 1,
      "redirect": 3,
      "redirect_loop": 0,
      "max_redirects": 0,
      "timeout": 1,
      "missing_lastmod": 2,
      "network_error": 0
    },
    "hasErrors": true,
    "durationMs": 12345
  }
}

The summary doubles as the final analysis report: successRate, validCount vs issueCount, the statusCodes histogram, the per-issue issues breakdown, and how long the run took (durationMs). When Max URLs to Check trimmed the run, limited is true and limit holds the number that was checked β€” the summary then reflects only what was actually validated.

status values

ok Β· broken Β· client_error Β· server_error Β· redirect Β· timeout Β· missing_lastmod Β· error Β· redirect_loop Β· max_redirects

issues (a URL can carry several)

broken_link_404 Β· client_error_4xx Β· server_error_5xx Β· redirect Β· redirect_loop Β· max_redirects Β· timeout Β· missing_lastmod Β· network_error

Handy expressions for downstream nodes

  • Only broken links: ={{ $json.issues.includes('broken_link_404') }}
  • Everything unhealthy: ={{ !$json.isValid }}
  • Abort the run if anything is wrong: ={{ $json.summary.hasErrors }}

πŸ§ͺ Testing

npm test

Spins up a local HTTP fixture server, loads a nested sitemap index + a gzip sitemap, and asserts that every issue type is detected β€” including redirect loops and redirect chains that exceed the hop limit.


πŸ”§ Development

npm run build          # compile TypeScript once
npm run build:watch    # recompile continuously while you hack
npm run lint           # type-check only (no output files written)
npm test               # build + integration tests + node smoke test

Architecture notes:

  • Manual redirect handling (redirect: 'manual') instead of auto-following β€” so the entire chain is recorded and loops are detectable.
  • AbortSignal.timeout() per request for precise timeout detection.
  • Fixed-size worker pool (mapWithConcurrency) keeps parallel requests under control and preserves input order.
  • Gzip detected by magic bytes (0x1f 0x8b), so it works even without a Content-Encoding header.

🀝 Contributing

Found a bug, or have an idea? Feel free to open an issue or a pull request. Keep it small, test it, and make sure npm test passes.

πŸ“„ License

MIT Β© Mehrdad Ashtari


πŸ’Ό Need a custom n8n workflow?

Need a custom n8n workflow?
Get professional n8n development & automation support at

https://tally.so/r/q4q1L9

Discussion