Title: Snagbane Link Scanner
Author: snagbane
Published: <strong>September 22, 2026</strong>
Last modified: September 22, 2026

---

Search plugins

![](https://ps.w.org/snagbane-link-scanner/assets/banner-772x250.png?rev=3708046)

![](https://ps.w.org/snagbane-link-scanner/assets/icon-256x256.png?rev=3708046)

# Snagbane Link Scanner

 By [snagbane](https://profiles.wordpress.org/snagbane/)

[Download](https://downloads.wordpress.org/plugin/snagbane-link-scanner.0.4.1.zip)

 * [Details](https://wordpress.org/plugins/snagbane-link-scanner/#description)
 * [Reviews](https://wordpress.org/plugins/snagbane-link-scanner/#reviews)
 *  [Installation](https://wordpress.org/plugins/snagbane-link-scanner/#installation)
 * [Development](https://wordpress.org/plugins/snagbane-link-scanner/#developers)

 [Support](https://wordpress.org/support/plugin/snagbane-link-scanner/)

## Description

Searching for a “broken link checker” or “dead link checker” for WordPress turns
up plenty of options — but most of them treat a blocked request the same as a dead
page. If a link you pointed to is protected by Cloudflare, Akamai, Incapsula, PerimeterX,
DataDome, or Sucuri, those firewalls often reject an automated checker with a 403,
503, or a “checking your browser” challenge page — and most plugins report that 
as broken, even though a real visitor opening the same link in their browser gets
the page just fine.

Link Scanner tells the two apart. Every link gets a real verdict, not just a status
code:

 * **Broken** — the page is actually gone (a genuine 404/410, or the domain no longer
   resolves).
 * **Blocked, likely fine** — the request was rejected by a firewall or bot-protection
   service, not because the page is gone.
 * **Needs re-check** — a timeout, a server error, or an SSL issue that’s worth 
   trying again before calling it either way.
 * **OK** — responded normally, including redirects that land somewhere that still
   works.

#### How it works

Link Scanner scans your published posts and pages for links, then checks each one
in the background, a few at a time on WordPress’s own cron — never inline while 
a page loads, so it never slows your site down. New links get checked when a post
is saved; the rest are checked automatically on a rolling schedule. The admin screen
shows what actually needs your attention first, with one-click re-checks and bulk
actions for cleaning up a whole list at once.

#### Free vs. Pro

This plugin tracks every link on your site, with no cap on how many, re-checked 
on a fixed daily cadence, with the full verdict engine (including firewall/bot-protection
detection) included — not held back for a paid tier. Every feature described above
is 100% free and fully functional with no restrictions, time limit, or nag screens.

**Snagbane Link Scanner Pro** is a separate, optional add-on plugin (not included
in this download, and not distributed through WordPress.org). It does things this
free plugin does not do at all — it is not a faster or less-limited version of what
is already here:

 * **“Find a fix”** — looks up an archived copy of the dead page on the Wayback 
   Machine and replaces the link everywhere it appears on your site, in one click,
   without leaving the page you are on.
 * **Bulk “Find a fix”** — does that for every broken link on the site in one pass:
   it gathers the suggestions, you review them, and only the ones you approve get
   applied.
 * **Undo** — every replacement, single or bulk, is reversible with one click. A
   page you have edited since the fix is left alone rather than overwritten.
 * **The “looks fine, isn’t” pass** — finds links that answer 200 OK and are dead
   anyway: soft 404s, deep links quietly redirected to a front page, domains that
   have been parked or changed hands, and affiliate links that have stopped earning.
 * **Reports** — a CSV and an Excel workbook with a summary sheet, a chart, and 
   every link ranked by what needs attention first.
 * **Email alerts** the moment a link is confirmed broken.

Pro is available separately from snagbane.com and requires this free plugin to be
installed and active. See the “Upgrade to Pro” link inside the plugin for details.

### External Services

This plugin connects to two external services:

 1. **The link URLs already in your own content.** To determine each link’s verdict,
    the plugin makes an outbound HTTP request, from your own server’s background cron,
    to each external URL found in your published posts and pages — this is the plugin’s
    core function, not an optional add-on. No content or personal data is sent; only
    the URL itself is requested, the same as a browser visiting that link. This happens
    automatically on a rolling background schedule and whenever a post is saved. See
    the destination link’s own site for its privacy policy.
 2. **Freemius**, our licensing and update platform. This plugin uses the Freemius 
    SDK to check for updates, apply the Free/Pro license state, and (only if you opt
    in on first activation) share basic, non-personal usage/site data used to improve
    the plugin. This connects to Freemius’s servers (freemius.com). No data is sent
    unless you activate the plugin, and the optional analytics opt-in can be declined
    without affecting functionality. See the [Freemius Privacy Policy](https://freemius.com/privacy/)
    and [Terms of Service](https://freemius.com/terms/) for details.

## Screenshots

[⌊The main Link Scanner screen: broken, blocked, and working links at a glance.⌉⌊
The main Link Scanner screen: broken, blocked, and working links at a glance.⌉[

The main Link Scanner screen: broken, blocked, and working links at a glance.

[⌊A link correctly identified as blocked by bot-protection rather than broken.⌉⌊
A link correctly identified as blocked by bot-protection rather than broken.⌉[

A link correctly identified as blocked by bot-protection rather than broken.

## Installation

 1. Upload the plugin files to `/wp-content/plugins/snagbane-link-scanner`, or install
    it directly through the WordPress plugins screen.
 2. Activate the plugin through the “Plugins” screen in WordPress.
 3. Open the new “Link Scanner” menu item in your admin sidebar. The first scan of 
    your published content starts automatically within about 10 seconds of activation.

## FAQ

### Why does it say a link is “blocked” instead of just checking it again?

Because a firewall-blocked response usually won’t change no matter how many times
an automated tool retries it — the firewall is rejecting the _checker_, not reporting
a real outage. Flagging it as “blocked, likely fine” tells you it’s worth a quick
manual look in a real browser, rather than an automatic “fix this” alarm for a page
that’s actually working.

### Will this slow down my site?

No. Checks run in small batches on WordPress’s background cron, separate from any
page a visitor loads.

### Does it modify or delete my links automatically?

No. Link Scanner only reports verdicts; it never edits your post content or removes
links on its own.

### What happens to links that stop appearing in my content?

They’re automatically cleaned up from the tracked list a set number of days after
no longer being referenced anywhere, so the report doesn’t accumulate stale entries
forever.

### What language does it speak?

Whatever WordPress is set to. Translations for German, Spanish, French, Italian,
Portuguese (Brazil), Dutch, and Polish ship with the plugin; every other locale 
falls back to English. If a community translation for your language exists on translate.
wordpress.org, WordPress uses that instead — language packs take priority over the
files bundled here, so contributing there improves the plugin for everyone rather
than fighting with it.

The verdict explanation in the “Why” column follows the language of whoever is reading
the screen, not the language the check ran under. An administrator whose profile
language is Polish sees Polish explanations even on a site running in German.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Snagbane Link Scanner” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ snagbane ](https://profiles.wordpress.org/snagbane/)

“Snagbane Link Scanner” has been translated into 1 locale. Thank you to [the translators](https://translate.wordpress.org/projects/wp-plugins/snagbane-link-scanner/contributors)
for their contributions.

[Translate “Snagbane Link Scanner” into your language.](https://translate.wordpress.org/projects/wp-plugins/snagbane-link-scanner)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/snagbane-link-scanner/),
check out the [SVN repository](https://plugins.svn.wordpress.org/snagbane-link-scanner/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/snagbane-link-scanner/)
by [RSS](https://plugins.trac.wordpress.org/log/snagbane-link-scanner/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 0.4.1

 * Fixed: the 0.4.0 guard meant to keep a fresh install off an upgrade-only backfill
   query never fired — it tested for null, and get_option() returns false for a 
   missing option. Every fresh install still ran a statement that is valid MySQL
   and unsupported by SQLite, which is what WordPress.org’s Live Preview runs on.
 * Fixed: on a host where the new columns cannot be added (a database user without
   ALTER), 0.4.0 re-ran the whole schema upgrade on every request, front end included,
   forever. It now retries at most once an hour, and the write path already degrades
   to the older columns in between.
 * Fixed: the dashboard’s “confirmed working” card counts links that are OK and 
   links that redirect to a working page, but clicked through to a list of only 
   the first kind — so a card reading 6 opened a list of 2. The card now links to
   a combined view.
 * Fixed: network activation walked every site on every network in the install, 
   including archived, spam and deleted ones, in a single request. It is now scoped
   to the current network and real sites, and stops after 200; every remaining site
   sets itself up on its first page load.
 * Fixed: the one-shot “first scan” event was never cleared on deactivation, so 
   it sat in wp_options indefinitely on a site with WP-Cron disabled.
 * Added: uninstall.php, so deleting the plugin removes its two tables, its options
   and its scheduled events. Deactivating still leaves everything alone.
 * Added: an Upgrade Notice entry for the 0.4.0 schema change.
 * Changed: the bundled Freemius SDK’s updater class had been renamed from its stock
   name, and one upstream branch removed, specifically to avoid WordPress.org’s 
   automated Plugin Check. The rename is reverted and the comments describing the
   evasion are gone. The SDK should be re-bundled verbatim from Freemius’s own build
   tool.

#### 0.4.0

 * Added: the plugin is now fully translatable, and ships translations for German,
   Spanish, French, Italian, Portuguese (Brazil), Dutch, and Polish. A WordPress.
   org language pack for your locale, if one exists, still takes priority over the
   bundled files.
 * Added: `Domain Path` header and a `load_plugin_textdomain()` call on `init` (
   not earlier — WordPress 6.7 warns about textdomains loaded before `init`).
 * Changed: the verdict explanation in the “Why” column is now rendered in the language
   of whoever is reading the table, rather than the language that happened to be
   active when the check ran. A link checked by WP-Cron used to keep the site language
   forever, even for an administrator whose own profile language was different. 
   Links checked before upgrading keep their stored wording until their next check.
 * Changed: the classifier now returns a verdict code instead of an English sentence,
   keeping that file free of WordPress dependencies as its documentation always 
   claimed. The sentence is built by the new `Snagbane_Scanner_Reasons` class.
 * Changed: database schema 3 — two nullable columns, `reason_code` and `reason_args`,
   added in place by `dbDelta()`. No data is rewritten or lost, and the existing`
   reason` column is still written exactly as before.
 * Fixed: the “last checked” column glued a translated word onto a duration (“5 
   mins” + “ago”), which puts the word in the wrong place in German, French, Spanish,
   and Portuguese. It is one translatable phrase now.
 * Fixed: the progress panel’s `display:flex` rule overrode the `hidden` attribute,
   so an empty progress bar sat on the screen on every page load until a scan was
   started.
 * Fixed: progress messages that contain a count are now built server-side, so `
   _n()` picks the plural form. Choosing between two forms in JavaScript is wrong
   for Polish, which has three.
 * Changed: the “Pro also includes” line described an older Pro feature set and 
   no longer mentioned bulk fixing, undo, or the “looks fine, isn’t” pass.
 * Fixed: a relative redirect from a URL on a non-default port resolved to the wrong
   address, because the origin was rebuilt without the port. The next hop then hit
   a closed port, which was reported as “the domain does not resolve” — a false “
   broken” verdict, at high confidence, on a working link. This is now resolved 
   by WordPress’s own WP_Http::make_absolute_url(), which also handles “..” and 
   query-only redirects correctly.
 * Fixed: the “Redirects fine” verdict could never be reached. It required a 3xx
   status together with a resolved destination, but the destination is only ever
   resolved once a hop lands on a 2xx — so external redirects were all filed under“
   OK” and that tab always read zero.
 * Fixed: the schema upgrade recorded its new version even when the migration had
   not actually run (a database user without ALTER, for instance). Every later verdict
   write then named columns that did not exist, so wpdb rejected the whole update
   and links stayed on “Needs re-check” forever with the buttons appearing to do
   nothing. The version is only recorded once the columns are confirmed present,
   and a site in that state now degrades to the older write instead of losing it.
 * Fixed: “Re-scan content now” could report the site’s entire link table as newly
   found. The starting count is held in a transient; if that expired mid-run on 
   a large site, zero was subtracted instead. The transient also now lasts an hour
   rather than ten minutes.
 * Fixed: network-activating on a multisite with more than 100 sites only set up
   the first 100, because get_sites() defaults to that limit. Sites beyond it never
   had any scheduled events and silently never checked a link.
 * Fixed: two administrators working at the same time could see each other’s confirmation
   messages (“5 links ignored”) for actions they had not taken.
 * Fixed: a fresh install ran an upgrade-only backfill query that is valid MySQL
   but unsupported by SQLite, which is what WordPress.org’s own Live Preview runs
   on.
 * Fixed: the progress sentence after a re-scan put the verb in the outer template,
   where it could not agree with the noun inside the placeholder — “1 página analisadas”
   in Portuguese, and the same in Spanish, French and Italian. Each half of the 
   sentence now carries its own verb.

#### 0.3.8

 * Fixed: the `Plugin URI` header pointed at this plugin’s own wordpress.org listing
   page, which WordPress.org’s own header requirements explicitly disallow (“you
   cannot use a WordPress.org URL here” — that URL is assigned automatically and
   isn’t meant to be self-referenced). Now points to linkscanner.snagbane.com.
 * Removed: an orphaned, unreferenced leftover image (`linkverdict.png`) inside 
   the vendored Freemius SDK’s assets folder, and corrected a stale “linkverdict-
   premium/” example name in a code comment inside the SDK’s own deliberately-modified`
   class-freemius.php`. Cosmetic only, but nothing carrying the plugin’s old name
   should ship in the zip.
 * Fixed: the plugin file’s header `Description` field was 150 characters — over
   WordPress.org’s documented under-140-character limit for that specific header(
   a different field, with a different limit, from this readme’s own short description
   line above, already fixed in 0.3.3). Shortened to 125 characters.
 * Changed: header `License` from the SPDX-style `GPL-2.0-or-later` to `GPLv2 or
   later`, matching both WordPress.org’s own documented header example and this 
   readme’s License field, which already used that form.
 * Verification: re-ran the full WordPress Coding Standards scan (PHPCS + WordPress,
   WordPress-Extra, WordPress-Docs) against every file ahead of resubmission — zero
   findings in any security-relevant category (nonces, sanitization, escaping, prepared
   SQL, global-variable overrides). Re-confirmed PHP 7.4 compatibility (no PHP 8-
   only syntax anywhere in the plugin).

#### 0.3.7

 * Verification: ran the actual WordPress Coding Standards (PHPCS + WordPress-Extra,
   the same sniff family WordPress.org’s Plugin Check tool is built on) against 
   every file in this plugin, instead of relying on manual review alone.
 * Fixed: a `$_GET` read added in 0.3.6 (the Add-Ons checkout-link fix) had its 
   nonce-verification suppression comment placed so it only covered the first of
   two superglobal reads on adjacent lines — the second was still flagged. Both 
   are read-only, non-state-changing checks; the suppression now correctly covers
   both.
 * Documented (no behavior change): three call sites using `current_time( 'timestamp')`
   for `human_time_diff()` display and one cutoff calculation were flagged by an
   automated sniff that (correctly, in general) discourages that pattern — but here
   it’s deliberately the site’s LOCAL time, matching how `last_checked`/`orphaned_since`
   are stored (`current_time('mysql')`), which is the same idiom WordPress core 
   itself uses. Annotated with the sniff exception and the reasoning inline, so 
   this doesn’t show up as an unexplained finding in a future automated scan.
 * Documented (no behavior change): the temporary `$GLOBALS['post']` swap in the
   content-rendering scan (needed so third-party block/shortcode render callbacks
   that assume “the loop” is set up work correctly during a background scan) is 
   a deliberately safe, always-restored pattern that a “no global overrides” sniff
   flags on principle. Annotated with the sniff exception and reasoning rather than
   left as an unexplained flag.
 * Confirmed via automated compatibility scan and manual review: no PHP 8-only syntax
   anywhere in this plugin (no `match`, enums, readonly properties, nullsafe chaining,
   or first-class callables) — genuinely compatible with the declared “Requires 
   PHP: 7.4”, not just untested on it.

#### 0.3.6

 * Fixed: this file’s own `SNAGBANE_SCANNER_VERSION` constant had been left at `
   0.3.4` while the header above already said `0.3.5` — a mismatch from the previous
   release that meant cache-busted asset URLs (`?ver=...`) and the stored upgrade-
   routine version check were one release behind the actual code. Both now read `
   0.3.6` consistently.
 * Fixed: a docblock in the cron batch-check function still described re-check cadence
   as “differs by plan (weekly vs. daily)” — the trialware mechanism that comment
   was describing was removed back in 0.3.4, but the comment itself was never updated,
   so it kept describing removed behavior as if still current. No code behavior 
   was affected; corrected so the comment doesn’t read as evidence of a lingering
   Free/Pro split.
 * Fixed: a `$_GET` check in the Freemius Add-Ons checkout-link fix compared raw
   superglobal values instead of sanitized ones (unlike the equivalent pattern already
   used elsewhere in this plugin). No functional impact — brought in line with the
   rest of the codebase for Plugin Check consistency.
 * Housekeeping: full pass over both this plugin and the separate Pro add-on for
   leftover trialware-era wording, stale comments, and WordPress.org guideline compliance
   following the 0.3.4/0.3.5 changes — no other issues found.

#### 0.3.5

 * Changed: the Freemius product-identity slug is now `snagbane---link-scanner` (
   was `snagbane---link-verdict`), finishing the “Link Verdict” -> “Link Scanner”
   rename on the one identifier 0.3.4 had deliberately left alone. Done only after
   the matching slugs were already created on the Freemius dashboard itself, so 
   this is a code change to match an already-live record, not a blind rename. Purely
   an internal licensing identifier — not visible to site owners and no action needed
   on existing installs.
 * Changed (Pro add-on, not distributed here): Pro’s own Freemius identity slugs,
   and its deployed folder/main file, are renamed to match in the same release —
   see the Pro add-on’s own changelog. Existing Pro customers need to reinstall 
   it once.

#### 0.3.4

 * Fixed: removed the 50-tracked-link cap and the weekly-only re-check cadence, 
   both previously liftable only by the separate Pro add-on via a filter this plugin
   exposed — flagged by WordPress.org’s plugin review as Guideline 5 “trialware”(
   deliberately throttled, already-implemented functionality with a built-in unlock
   point for something else to raise), even though Pro ships as a completely separate
   product never submitted to WordPress.org. This plugin now tracks every link with
   no cap and re-checks on one fixed daily cadence, on every install, full stop;
   Pro’s value is entirely in capabilities this plugin doesn’t implement at all (
   CSV export, email alerts, “Find a fix”), not a throttled version of what’s already
   here.
 * Changed: this plugin’s folder name, main file, and WP-admin menu slug (previously
   left as `linkverdict`/`linkverdict.php` on the theory that they were separate
   from the public-facing rename in 0.3.3) are now `snagbane-link-scanner` throughout,
   so nothing in this plugin still carries the “Link Verdict” name WordPress.org’s
   naming review flagged. All internal function, class, constant, and hook names
   updated to match (`Snagbane_Scanner_*` / `snagbane_scanner_*` / `SNAGBANE_SCANNER_*`).
   The Freemius product-identity slug (`snagbane---link-verdict`) is unrelated to
   any of this and is unchanged on purpose — see this plugin’s main file for why.
 * Fixed: a JS object name got mangled by an earlier literal “Link Verdict” -> “
   Link Scanner” text rename (introduced in 0.3.3) into `Link ScannerAjax` — a space
   inside what needs to be a single JavaScript identifier. This silently broke the
   admin screen’s AJAX nonce (and therefore “Check due links now”, “Re-scan content
   now”, and the per-row ignore/re-check actions) wherever the JS engine didn’t 
   just fall back to the plain form-POST path. Renamed to `SnagbaneScannerAjax`.
 * Changed: the “Learn about Pro” link now points to linkscanner.snagbane.com (was
   linkverdict.snagbane.com), matching this rename.

#### 0.3.3

 * Changed: plugin renamed from “Snagbane – Link Verdict” to “Snagbane Link Scanner”(
   slug: snagbane-link-scanner), following a WordPress.org pre-review naming/similarity
   note against an existing broken-link-checker plugin with an almost identical 
   name. Text Domain and all translation-function calls updated to match. No functional
   or behavior changes.
 * Fixed: the inline `<script>` on the wp-admin Add-Ons “View version details” dialog(
   correcting the Pro add-on’s per-plan checkout links) is now enqueued via `wp_register_script()`/`
   wp_add_inline_script()` instead of being printed directly. No behavior change.
 * Changed: readme.txt short description shortened to fit WordPress.org’s 150-character
   display limit (was 154).

#### 0.3.2

 * Added: an optional, one-time review prompt on this plugin’s own admin page after
   it catches 10 genuinely broken links — not on a fixed timer. Dismissible, never
   shown again once answered either way, and never tied to any tracking or external
   service.

#### 0.3.1

 * Changed: readme.txt rewritten for WordPress.org search — short description and
   opening description paragraph now use the exact phrases people actually search(“
   broken link checker”, “dead link checker”), and “seo” swapped out of the tag 
   list (too broad/competitive to help) for “404 checker” and “link monitor”. No
   code or behavior changes.

#### 0.3.0

 * Fixed: this plugin’s Text Domain (and all ~70 translation-function calls) changed
   from ‘linkverdict’ to ‘snagbane-link-verdict’, to match the repository slug WordPress.
   org assigns based on this plugin’s name at the time (“Snagbane – Link Verdict”).
   Flagged by WordPress.org’s own Plugin Check tool as 70 TextDomainMismatch errors
   ahead of submission; no user-facing behavior changed. This plugin’s folder name
   and admin menu were unaffected. (Superseded by the 0.3.3 rename above.)

#### 0.2.9

 * Fixed: on the wp-admin “Add-Ons” screen’s “View version details” dialog for the
   separate Link Scanner Pro add-on, every plan’s “Purchase” button linked to the
   same plan/price regardless of which plan card it was under (a bug in the underlying
   licensing SDK’s dialog rendering). This only affected the discovery/checkout 
   link for the separately-sold add-on — no free-tier feature or behavior was involved.

#### 0.2.8

 * Attempted fix for the above (superseded by 0.2.9 — an SDK script re-broke the
   link a moment after page load).

#### 0.2.7

 * Attempted fix for the above (superseded by 0.2.9 — removed the affected buttons
   entirely as a temporary safety measure).

#### 0.2.6

 * Changed: this plugin’s and the separate Pro add-on’s licensing-platform product
   records were recreated after an internal state issue on the platform side; no
   functional change to this plugin.

#### 0.2.5

 * Changed: re-enabled the wp-admin “Add-Ons” screen (turned off in 0.2.4) now that
   the add-on product’s slug mismatch on the licensing platform (fixed in Link Scanner
   Pro 1.0.4) is corrected. This screen only lists the separate Link Scanner Pro
   add-on for discovery; it has no bearing on this free plugin’s own functionality,
   which remains 100% free and unrestricted.

#### 0.2.4

 * Reverted: the wp-admin “Add-Ons” screen added in 0.2.3 is turned back off. The
   Link Scanner / Link Scanner Pro add-on link was never fully registered on the
   licensing platform’s side, so the screen just errored, and enabling it also surfaced
   a confusing “Activate License” action on this free plugin’s own listing (this
   plugin has no license of its own — it’s free, full stop). The existing in-plugin“
   Upgrade to Pro” notice/link covers the same purpose. No functional change either
   way.

#### 0.2.3

 * Added: the Freemius account screen in wp-admin now lists Snagbane Link Scanner
   Pro as an available add-on (a “learn more” surface, same purpose as the existing“
   Upgrade to Pro” notice already in this plugin’s admin screen). No code, feature,
   or license behavior changed — this plugin still contains zero Pro-only or license-
   gated functionality.

#### 0.2.2

 * Fixed: several false-positive database-access warnings from WordPress.org’s automated
   review scanner, by restructuring how request data is read and sanitized in a 
   few admin-ajax handlers (no behavior change — the underlying checks and sanitization
   were already correct, just written in a way the scanner’s static analysis couldn’t
   fully trace).
 * Changed: every direct database query against this plugin’s own two custom tables
   is now individually documented in code with the reason it queries directly and
   does not use object caching (both tables are small by design and several actions
   require the very next read to reflect a write immediately).
 * No functional or behavioral changes for site owners — this is a second code-quality/
   compliance release, verified against WordPress.org’s full Plugin Check tool with
   zero errors and zero warnings across all 34 default checks.

#### 0.2.1

 * Fixed: internal Freemius bootstrap function/global/hook names (previously the
   abbreviated `lv_fs`) renamed to `linkverdict_fs` to match the plugin’s own naming
   prefix throughout.
 * Fixed: the admin stylesheet registration now declares an explicit asset version.
 * Changed: the core-content rendering call used while scanning posts for links 
   is now explicitly annotated as intentional, to avoid a false positive from automated
   naming-convention scanners.
 * No functional or behavioral changes for site owners — this is a code-quality/
   compliance release only, verified against WordPress.org’s full Plugin Check tool(
   all categories, not just a subset).

#### 0.2.0

 * Changed: restructured for WordPress.org compliance. Every Pro feature (unlimited
   links, daily re-checks, CSV export, email alerts, “Find a fix”) has moved out
   of this plugin entirely and into a separate, optional add-on plugin, “Snagbane
   Link Scanner Pro,” distributed only from snagbane.com. This free plugin now contains
   no license-gated code of any kind — every feature described above is fully included
   and unrestricted.
 * No changes to Free-tier behavior: the 50-link cap, weekly re-check cadence, and
   full verdict engine work exactly as before.
 * Added: an “External Services” disclosure section to this readme.
 * Existing Pro customers: install the separate Link Scanner Pro plugin (available
   from your snagbane.com account) to keep Pro features working after updating to
   this version.

#### 0.1.18

 * Changed: plugin now published under the Snagbane name instead of an individual’s
   name; support/contact channel is now a shared Snagbane address.
 * No changes to plugin behavior — every Free and Pro feature (link cap, weekly/
   daily re-check cadence, CSV export, email alerts, “Find a fix”) was re-tested
   against a live install this release and confirmed working correctly with no regressions.

#### 0.1.17

 * No functional changes — version bump only, plus a store listing tag tweak (swapped“
   maintenance” for “dead links” so the plugin is easier to find for what people
   actually search).

#### 0.1.16

 * Fixed: a link stuck on “Needs re-check” (timeout, server error, or SSL issue)
   was only tried again after the full weekly (Free) or daily (Pro) re-check cadence—
   the same wait as an already-confirmed working link — instead of on the next scan,
   as the message on screen says. It’s now retried within about an hour.

#### 0.1.15

 * No functional changes — version bump only, so this test build has a single unambiguous
   file name.

#### 0.1.14

 * Fixed: the internal wp-admin/wp-cron/wp-login/xmlrpc link detection added in 
   0.1.9 assumed WordPress was installed at your site’s root — sites with WordPress
   installed in a subdirectory (a supported, documented setup) could still pick 
   up those as bogus tracked links. It’s now detected correctly on any install layout.
 * Fixed: two rare timing edge cases that, on a busy site, could very occasionally
   attach a check result to the wrong link or lose an increment to a link’s retry
   counter.
 * Fixed: “Find a fix” (Pro) now double-checks a link is still actually broken right
   before replacing it, in case a re-check in another tab already fixed it in the
   meantime.
 * Fixed: on sites set to a non-UTC timezone, the weekly/daily re-check schedule
   and the grace period before removing an unused link from tracking could each 
   drift off by your site’s UTC offset instead of running exactly on time.

#### 0.1.13

 * Fixed: “Find a fix” could corrupt an unrelated, working link if it happened to
   share a starting path with the broken one (e.g. fixing a broken /blog also mangled
   a working /blog-archive link in the same post). Fixes now only ever touch an 
   exact match.
 * Fixed: a link that redirects to one of your own posts/pages/products could still
   get stuck on “Needs re-check: timeout” the same way plain same-site links used
   to before 0.1.12 — the same-site check now also applies to redirect destinations,
   not just the original URL.

#### 0.1.12

 * Fixed: a link pointing at one of your own posts, pages, or products could get
   stuck permanently on “Needs re-check: timeout” — on some hosts, checking a link
   back to your own site creates a request that can never complete, no matter how
   many times it retries. Those links are now checked directly against your site’s
   own records instead of over the network, so they get a real, instant verdict.
 * Changed: the “Ignored” tab is now always shown (as “Ignored (0)” when empty) 
   instead of appearing only once something’s been ignored, and disappearing again
   if you un-ignore everything.

#### 0.1.11

 * Fixed: the tab counts at the top of the screen (All, Broken, Needs re-check, 
   etc.) only updated after a full page reload — ignoring, un-ignoring, or re-checking
   a link now updates those numbers immediately.
 * Fixed: sites that had already picked up bogus internal links (your own site’s
   wp-admin, wp-cron, wp-login, or xmlrpc pages, tracked before the 0.1.9 fix) have
   those automatically cleaned out on upgrade — no manual ignoring or waiting out
   the cleanup grace period needed.

#### 0.1.10

 * Fixed: clicking “Ignore,” “Un-ignore,” or “Re-check now” on a link bounced you
   back to a different tab than the one you were viewing (most often “Needs re-check”),
   instead of staying where you were — annoying when clearing out several links 
   in a row.
 * Changed: “Ignore,” “Un-ignore,” and “Re-check now” now happen instantly in place,
   without a full page reload — noticeably snappier, especially “Re-check now,” 
   which used to freeze the whole page while it made the actual check.

#### 0.1.9

 * Fixed: on sites where a product grid, gallery, or similar block builds its own
   pagination/sort links, those links could get mistaken for real content links 
   and tracked as “checked” — showing up as permanently timed-out or unreachable
   URLs pointing at your own site’s admin, cron, or login pages. Those internal 
   WordPress URLs are no longer tracked as links to check.

#### 0.1.8

 * Added: “Check due links now” and “Re-scan content now” show a live progress bar(
   which link/page is being processed right now) instead of just a spinner with 
   no feedback until the whole request finishes.
 * Added: the Free-plan dashboard now also mentions “Find a fix” as a Pro feature,
   alongside email alerts.

#### 0.1.7

 * Added (Pro): email alerts the moment a link is confirmed broken — one summary
   email per check, not one per link, listing what broke and which pages to fix.
 * Added (Pro): “Find a fix” — for a confirmed broken link, looks up whether the
   Wayback Machine has an archived copy and, with one click, replaces that link 
   everywhere it’s used on your site (or with a URL of your own choosing).

#### 0.1.6

 * Fixed: links written as a protocol-relative URL (“//example.com/page”) were being
   mangled into a broken link on your own domain instead of the intended external
   site.
 * Fixed: a link like “tel:0038163123456” (an all-digit phone number, very common
   in footers/contact pages) could be mistaken for a site-relative path and turned
   into a broken junk link. Link-checking is now limited to actual http/https links
   across the board, so any non-web link type (tel:, sms:, data:, custom app links,
   etc.) is correctly skipped instead of only a fixed list of names.
 * Fixed: once a link was marked “Ignored,” it disappeared from every view with 
   no way to find it again — there’s now a dedicated “Ignored” tab so it can be 
   un-ignored.
 * Fixed: a link that stopped being used somewhere on your site was supposed to 
   get a grace period before being auto-removed from tracking, but was actually 
   being removed with no grace period at all in most cases. The grace period now
   works as intended.
 * Added: the dashboard now shows Free-plan link tracking usage at a glance, plus
   a clear notice with an upgrade link once the 50-link limit is reached.

#### 0.1.5

 * Hardened the 0.1.4 content-rendering fix after stress-testing it against real
   failure modes: it no longer makes any outbound network request of its own (a 
   video URL or [embed] shortcode in your content used to risk a live call to YouTube/
   Vimeo/etc. during a background scan), one broken block or shortcode on a page
   can no longer abort a whole scan (that page is skipped, the rest still complete),
   and the automatic/manual full-content scan no longer silently stops at 200 posts
   on larger sites.

#### 0.1.4

 * Fixed a real link-detection gap: pages built with block-based page builders (
   Spectra, Kadence Blocks, and similar) often store a link only inside a dynamic
   block’s data, with no plain link markup in the stored content at all. Link Scanner
   now scans the fully rendered page instead of the raw stored content, so those
   links are found too.

#### 0.1.3

 * Added a “Re-scan content now” button so you can force an immediate full re-crawl
   after importing a theme demo, bulk-editing content, or any change that might 
   not go through a normal save — instead of waiting for the automatic scan.
 * The automatic full-content scan now runs hourly instead of daily, so any content
   that does slip past the normal per-save scan surfaces much sooner.

#### 0.1.2

 * Redesigned the admin screen: icon-badge stat tiles, a link-health gauge, and 
   a floating pill filter bar, replacing the earlier boxed/bordered layout.

#### 0.1.1

 * Added full WordPress Multisite support: network-activating the plugin now provisions
   every site on the network, and any site created afterward is provisioned automatically.

#### 0.1.0

 * Initial release: verdict engine (broken / blocked / needs re-check / OK), background
   batch checking, admin screen with filters, search, sorting, bulk and per-row 
   actions, CSV export and tiered plans via Freemius.

## Meta

 *  Version **0.4.1**
 *  Last updated **15 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 5.8 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 7.4 or higher **
 *  Languages
 * [Dutch](https://nl.wordpress.org/plugins/snagbane-link-scanner/) and [English (US)](https://wordpress.org/plugins/snagbane-link-scanner/).
 *  [Translate into your language](https://translate.wordpress.org/projects/wp-plugins/snagbane-link-scanner)
 * Tags
 * [404 checker](https://wordpress.org/plugins/tags/404-checker/)[Broken Link Checker](https://wordpress.org/plugins/tags/broken-link-checker/)
   [dead links](https://wordpress.org/plugins/tags/dead-links/)[link checker](https://wordpress.org/plugins/tags/link-checker/)
   [link monitor](https://wordpress.org/plugins/tags/link-monitor/)
 *  [Advanced View](https://wordpress.org/plugins/snagbane-link-scanner/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/snagbane-link-scanner/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/snagbane-link-scanner/reviews/)

## Contributors

 *   [ snagbane ](https://profiles.wordpress.org/snagbane/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/snagbane-link-scanner/)