Description
Broken links cost you readers, rankings and trust. Most link checkers either hammer your server and the sites you link to, or leave you with a spreadsheet and no way to fix anything. Waymender does three things, and does them gently:
1. Scan. Links and images in your posts, pages, custom post types, custom fields, custom-link menu items, Block, Text and Custom HTML widgets, term descriptions and page-builder content (Elementor, Bricks, Beaver Builder, Divi, WPBakery) are collected and checked in the background, in small batches with a politeness delay between link checks on the same domain, so no host is hammered and your own site never waits on a check. Menu items that point to a page, post or category are not scanned. Known anti-bot sites (LinkedIn, Instagram, Amazon…) are never requested; they are listed for manual review instead. A failure has to happen twice, at least six hours apart, before a link is called broken, so a hiccup never wakes you up. The exception is “Recheck now” on a link that has already failed once: that check confirms it immediately, so if it fails again the link is marked broken straight away.
2. Fix. From the Links screen you can:
- Edit the URL (the new one is checked right away, or its last result shown if Waymender already knows it)
- Unlink, keeping the text
- Remove or replace a broken image from the media library
- Use the closest Wayback Machine copy of a dead page
- Update every occurrence of a redirecting link to its final destination in one go (for this and “Fix everywhere”, a summary shows how many places were fixed, how many were not, and each distinct reason or note)
- Create a redirect for broken internal links
The editor sidebar lists the problem links in the post you are editing and offers Unlink and Remove right there; its “More options” link opens the Links screen for the other fixes. In the classic editor, a “Waymender: link problems” box links to the Links screen filtered to that post.
Fixes to post content and excerpts are saved through WordPress, so they create a normal post revision when the post type supports revisions. Menus, widgets, term descriptions, comments, custom fields and page-builder data have no revisions. For every fix, wherever the link is, Waymender’s fix log (the waymender_fix_log database table) records the old URL, the new URL (empty for Unlink and Remove), the action, the ID of the user who made it and the time, plus the revision ID when a revision was created. The log is only stored in the database: there is no screen for it and no undo. A menu item cannot be unlinked (edit or remove it under Appearance Menus). A custom field that holds nothing but the URL gets the new URL, or is emptied when you unlink or remove it (you are told when that happens); an ACF link field keeps its title and target when its URL is replaced.
When an archived copy replaces a link, rel=”nofollow” (on by default) is added to the link’s existing rel value, never duplicated. That applies to HTML links in post content, excerpts, widgets, term descriptions, comments and HTML custom fields; menu items, custom fields that hold only a URL, and page-builder data keep their rel unchanged.
3. 404 log and redirects. Pages visitors could not find are logged with hit counts, referrers and a suggested target (fuzzy slug matching, date-prefix and case rules). One click turns an entry into a 301/302/307/410 rule. Wildcards, CSV import/export, and automatic hand-off when the Redirection plugin is active. Hit counts are sampled: each rule counts at most one hit per minute. To keep a flood of random URLs from filling the database, the 404 log records at most 120 hits per clock minute across the whole site (filterable with waymender_404_writes_per_minute); further 404s in that minute are not logged or counted.
Built to be light
- Custom tables, no post meta bloat, automatic pruning
- Action Scheduler queue with WP-Cron fallback
- Adaptive batch size, per-host throttling, Retry-After respected
- Detects blocked outbound HTTP and says so instead of reporting everything as broken
- WP-CLI:
wp waymender scan,wp waymender links,wp waymender fix(run it with--user=<administrator>; it refuses to run without a user, and the fix is logged under that user),wp waymender 404,wp waymender redirect
Hooks for developers
waymender_http_args, `waymender_excluded_hosts`, `waymender_antibot_hosts`, `waymender_extract_sources`, `waymender_extracted_links`, `waymender_status_for_response`, `waymender_before_fix`, `waymender_after_fix`, `waymender_404_ignore`, `waymender_suggestions`, `waymender_scan_started`, `waymender_scan_complete`, `waymender_url_checked`, `waymender_capability`, `waymender_404_writes_per_minute`, `waymender_redirection_active`.
External services
Waymender runs entirely on your own server. It uses no third-party link-checking service and sends nothing to the plugin author. It does make the following outbound requests.
1. The websites you link to
To find out whether a link works, Waymender requests it from your server the way a browser would: a HEAD request first, then a GET when the site does not answer HEAD properly. Waymender sends the URL being checked with three headers: a User-Agent that identifies the plugin and your site address, Mozilla/5.0 (compatible; Waymender/<version>; +https://your-site/), so that site owners can see who is checking and why; Accept: text/html,application/xhtml+xml,*/*;q=0.8; and Accept-Language: en-US,en;q=0.8, so that sites answer as they would a browser. No cookies, referrer, visitor data or content from your site are sent.
Link checks are spaced out per domain: after one link on a domain is checked, the next link on that domain waits 2 seconds by default (configurable; at most 1 second for a few large sites that handle it easily: wikipedia.org, github.com, youtube.com, youtu.be, wordpress.org and google.com, subdomains included). Within a single check, the HEAD request, the GET fallback and any redirects it follows go out back to back. A 429 (Too Many Requests) or 503 (Service Unavailable) answer pauses checks of that domain for its Retry-After time (at most 7 days), or 1 hour when it sends none. Working links are cached for 7 days, and domains you list as excluded or anti-bot are never requested. Waymender does not read robots.txt. Checks happen in the background after you start a scan, in an hourly re-check of links that failed once or were rate limited, and, if you enable it in Settings, in a weekly automatic scan. Links pointing to your own site are resolved locally where possible and otherwise requested from your own server in the same way.
2. WordPress.org, once
If a link check fails with a DNS error, Waymender sends a single HEAD request to https://api.wordpress.org/core/version-check/1.7/ to find out whether your host blocks outbound connections altogether, so it can tell you instead of marking every link broken. It carries the same three headers as above. This happens once per site, and once more each time you tick the re-test option under Settings Advanced (shown after outbound requests were found blocked). Privacy: https://wordpress.org/about/privacy/
3. Internet Archive, only when you ask
When you click “Use archived copy” on a broken link, Waymender asks the Wayback Machine availability API at https://archive.org/wayback/available for the closest snapshot of that URL. The broken URL is sent with a User-Agent naming the plugin; the archived URL and its date come back and are cached for 24 hours. If you then click “Use this copy”, the link in your content is rewritten to that web.archive.org address (with rel=”nofollow” by default, see Fix above) and the new address is checked like any other link: a HEAD request to web.archive.org, a GET when HEAD is not answered properly, and redirects followed up to five times. No page content is downloaded from the archive or inserted into your posts. Terms of use and privacy policy (the Internet Archive publishes both on one page): https://archive.org/about/terms
4. Email
If you enable the weekly report under Settings Notifications (off by default), Waymender sends one email every Monday, around 08:00 in your site’s timezone, through your site’s normal wp_mail() to the addresses you enter, or to the site admin email. It contains counts plus the top broken links and 404 paths, and is skipped when there is nothing to report.
Privacy
The 404 log is on by default and records, for each page path visitors could not find: the path, a hit counter, first and last time seen, the domain name (not the full URL) of up to five referring sites, and a coarse browser family such as “chrome” or “bot”. It does not store IP addresses, full user-agent strings, cookies, or which logged-in user made the request. Query strings are dropped unless you turn on “Keep query strings”, in which case anything in the query string, including tokens or email addresses if your site puts them there, is stored as part of the path. Requests that look like bots are logged too, flagged as bots, and hidden on the 404 log screen until you tick “Include bots” (untick “Hide bot traffic by default” under Waymender Settings 404 log to show them from the start). An entry is deleted automatically once its path has not been requested for 30 days (configurable), and the log is capped at 5,000 paths (configurable), dropping the least recently seen first; both rules cover ignored entries too. You can turn the log off or add ignore patterns under Waymender Settings 404 log, and delete every entry, ignored ones included, with “Clear log” on the Waymender 404 log screen.
Fixes and redirects record the ID of the user who made them, like any other WordPress edit. The plugin registers a suggested paragraph under Settings Privacy Policy Guide. Deleting the plugin removes all of its tables and options unless “Keep data” is enabled.
Screenshots






Installation
- Upload the plugin to
/wp-content/plugins/waymenderor install it from the Plugins screen. - Activate it.
- Open Waymender Links and click Scan now. The 404 log starts recording on activation.
FAQ
-
Will scanning slow down my site?
-
No. Scans run in the background in small batches with a delay between link checks on the same domain, and the batch size adapts to how fast your server answers. Working links are cached for seven days and not re-requested.
-
Why is a link “blocked” instead of “broken”?
-
The destination refuses automated requests (LinkedIn, Instagram, Cloudflare challenges…). Waymender does not pretend to know; it lists these separately so you can check them by hand.
A link that answers 429 (rate limited) or 503 (temporarily unavailable) is listed as blocked too, but it is checked again automatically: the hourly re-check picks it up once the site’s Retry-After time has passed (never sooner than 5 minutes or later than 7 days), or after 3 hours when the site sends no Retry-After. Its status line says when, for example “HTTP 429 (rate limited, rechecks after 3h)”.
-
Does it work with page builders?
-
Yes. Elementor, Bricks and Beaver Builder data is read from post meta (Settings What to scan “Page builder data stored in post meta”). Divi and WPBakery shortcodes live in the post content and are read with it: every attribute whose name ends in
url,src,image,link,hreforlogo, plus Divi’ssrc_webm,audio,background_video_mp4andbackground_video_webmand WPBakery’scustom_links(a comma- or newline-separated list, also when WPBakery stores it#E-8_-encoded). WPBakery’s encoded link format (url:…|title:…) is read too. Numeric image attributes are attachment IDs, not URLs, and are not checked. Divi’s_et_pb_old_contentbackup of the pre-builder content is not scanned, because the page does not show it.For Elementor, Bricks and Beaver Builder, fixes are written into the stored builder data: Edit URL, Use archived copy and Replace image put the new address in place of the old one wherever it appears in that page’s builder data, and Unlink and Remove empty it there. For Divi and WPBakery, Edit URL, Use archived copy and Replace image rewrite the URL inside that one shortcode attribute (WPBakery links keep their title and target; in a
custom_linkslist only that entry changes, and an encoded list stays encoded); Unlink and Remove are refused with a message, because taking a link or image out of a builder element has to be done in the page builder. Page-builder links keep their rel attribute; no nofollow is added.After a fix, the builder’s generated CSS/asset cache is cleared for Elementor, Beaver Builder and Divi through their own functions. Waymender does not clear Bricks’ generated files.
-
What about the Redirection plugin?
-
If Redirection is active and Settings Redirects Redirect engine is on “Automatic” (the default), every redirect you create, edit, switch off or delete in Waymender is written to a Redirection group called “Waymender”, and Waymender stops serving redirects itself, so each rule runs exactly once. Rules you made before Redirection was activated can be copied across with one button on the Redirects screen. Wildcard rules become Redirection regular-expression rules. Choose “Always on” to serve redirects from Waymender instead, or “Off” to switch its redirects off entirely. When you switch from “Automatic” to “Always on” or “Off” while Redirection is active, Waymender deletes the redirects it wrote to Redirection (rules you made in Redirection itself are not touched), so no rule is served twice or left behind there. Switch back to “Automatic” and the Redirects screen shows the “Copy N existing redirects to Redirection” button again, N being the number of rules waiting to be copied.
-
No. Waymender has no server of its own and sends no usage statistics or telemetry. It contacts nothing until you start a scan, and then only the addresses listed under “External services” above: the sites your own content links to, one WordPress.org request if a check fails with a DNS error, and the Internet Archive when you ask for an archived replacement.
-
Does the bundled Action Scheduler conflict with other plugins?
-
No. Waymender loads Action Scheduler 3.9.3 from
lib/action-scheduler/. Action Scheduler is built for this: each copy registers its version withActionScheduler_Versionsbehindfunction_exists()andclass_exists()guards, and only the newest copy on the site boots. WooCommerce and other plugins that bundle it share the same mechanism. -
Where is the JavaScript source?
-
The admin app and the editor integration ship un-minified in
assets/src/; the files inassets/build/are produced from them withnpm install && npm run build(thepackage.jsonis included). The bundled Action Scheduler library inlib/is unmodified upstream code under its own GPL licence. Nothing else is compiled or obfuscated. -
Can editors fix links?
-
Anyone who can edit a post can fix the links in that post’s content and excerpt (Edit URL, Use archived copy, Replace image, Unlink and Remove) and dismiss them. The editor sidebar lists the post’s problem links and offers Unlink and Remove; the plugin’s REST route for a single fix (
POST /wp-json/waymender/v1/fix/<id>) accepts the other fixes from the same users. Fixing links anywhere else (custom fields, page-builder data, menus, widgets, term descriptions, comments), fixing every occurrence of a URL at once, creating a redirect, and the Links, 404 log and Redirects screens need themanage_optionscapability (administrators by default). Every one of these checks goes through thewaymender_capabilityfilter, which receives a context:restfor the fix and other REST routes,redirectsfor creating redirects and the Redirects screen, andmenufor the admin menu.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Waymender – Broken Link Checker, 404 Monitor & Redirects” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Waymender – Broken Link Checker, 404 Monitor & Redirects” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
1.0.0
- Initial release.
