=== PlugUpp Link & Image Health Audit - Broken Link Checker ===
Contributors: plugupp
Tags: broken link checker, broken links, broken images, link checker, ssl
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.4.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Broken link checker that audits your pages' final rendered output - broken links, broken images, mixed content and SSL problems. Local, no quotas.

== Description ==

PlugUpp Link & Image Health Audit is a broken link checker that checks the links and images your visitors actually see. It finds broken links, broken images, mixed content and SSL problems by rendering each of your own pages through the normal front-end pipeline and inspecting the final HTML - so it catches links and images injected by themes, menus, widgets, footers and page builders that database-only checkers miss.

Everything runs on your own server. There is no external crawler, no per-link quota, and nothing about your site is sent to a third-party service.

> **Upgrade to Premium** for a Learning Engine that tunes itself to your site, scheduled scans and email reports, change detection, soft-error and Safe Browsing checks, rule-based exclusions and CSV export. [See plans and pricing](https://plugupp.com/plugins/link-image-health-audit/)

= What you get on the free plan =

* **Rendered-page scanning** - checks the links and images that actually ship to visitors, including those added by your theme, menus, widgets, footers and page builder that database-only checkers never see
* **Links, images and resources** - internal and external links, images, and page resources (CSS, JS, icons, fonts)
* **All your content types** - posts, pages, and any public custom post type, including WooCommerce products
* **Unpublished content too** - optionally scan drafts, scheduled, pending and private content, so links are checked before they go live
* **Clear verdicts** - broken links and images, SSL and certificate problems, permanent and temporary redirects, and hosts that refuse automated visitors, counted separately as "Not checkable" rather than reported as broken
* **Mixed content detection** - flags images, embeds and page resources that load over plain HTTP on your HTTPS site, which browsers block or downgrade
* **Archived-copy links** - every broken external link gets a "View archived copy" link to the Wayback Machine, so you can see what the dead page said or pick a replacement
* **By URL and By page views** - sorted worst-first, with separate Issues, Warnings and Notices counts so you can triage at a glance
* **Drill-down with evidence** - see exactly which pages a broken URL appears on, and open the page source with the offending link or image highlighted in context
* **URL parameter handling** - cache-busters and tracking tags (ver, utm_source, fbclid and the like) are ignored so the same resource is not counted as many different URLs; the common ones are pre-filled, and you can add your own
* **Exclude and ignore** - exclude pages from scanning individually, from the Exclusions screen, or in bulk from the standard Posts and Pages screens; ignore individual URLs
* **Built-in log viewer** - file-based logging with a viewer on the Logs tab
* **No quotas, nothing leaves your site** - scan as much as you like, entirely on your own server

Password-protected content is never scanned - there is no way to render it without the password. Unpublished content is off by default; when you enable it, drafts, scheduled, pending and private posts are rendered privately for the scan only and never shown to visitors.

= What Premium adds =

The premium version is a separate plugin, delivered from plugupp.com, that adds intelligence, automation and reporting - still entirely on your own server.

* **URL Parameter Learning Engine** - watches the parameters in your own scans and suggests the cache-busters and tracking tags worth ignoring, each with evidence, a live example you can open both ways, and a one-click add
* **Image alt-text audit** - finds images with missing, empty or suspicious alternative text on the rendered page - including the media-library divergences no database tool can see - with WCAG-anchored findings and review tiers
* **Scheduled scans** - run scans automatically on the schedule you choose, on standard WordPress cron
* **Email reports** - get the results by email, every run or only when something needs attention
* **Change detection** - a changes-since-last-scan digest: what newly broke, what changed, what got fixed
* **Soft-error detection** - catches pages that return 200 OK but actually show an error, a parked domain or an expired-site notice
* **Google Safe Browsing checks** - check external destinations against Google's malware and phishing lists, with your own API key
* **Rule-based exclusions** - auto-exclude whole patterns of content by post type, category or tag, author, or URL shape; save rule sets and carry them between sites
* **One-click filters and CSV export** - narrow any view to a specific issue type and export it
* **Multi-site licences** - one licence covers 1, 3, 5 or unlimited sites

[See the full plan comparison and pricing](https://plugupp.com/plugins/link-image-health-audit/)

== External services ==

This plugin connects to the following external services.

= Link and image URLs found on your pages =

Checking a link or image means requesting the URL to see whether it resolves. This is the core function of the plugin.

* When data is sent: during a scan, for every unique external link, image or resource URL found in your pages' rendered output.
* What data is sent: nothing beyond the HTTP request to the URL itself, made only to read its response status (for example 200, 404, or a redirect). Only URLs that already appear on your own pages are contacted. Internal links are checked against your own server.

The plugin also renders your own pages by requesting them on your own server (a self-request); that is your site contacting itself, not a third-party service.

= Google Safe Browsing (Premium, optional) =

If you enable Safe Browsing checks and provide your own Google API key, the plugin checks external link destinations against the Google Safe Browsing threat lists.

* When data is sent: during a scan, only when you have entered a Google API key. With no key, this feature is off and nothing is sent.
* What data is sent: the external URLs found in your scan are sent to the Google Safe Browsing Lookup API to check them against Google's malware and phishing lists.
* Terms of service: https://cloud.google.com/terms
* Privacy policy: https://policies.google.com/privacy

= Freemius =

The plugin uses the Freemius platform for licence activation, plan changes, plugin updates (for paid plans), and as the Merchant of Record for purchases.

* When data is sent: on first plugin activation as part of the user-consented opt-in flow, on licence activation or deactivation, on plugin update checks (paid plans), and on uninstall (for optional feedback). Sending the initial opt-in data is the user's choice - declining the opt-in still lets the plugin work in full. Scanning is fully local and never requires the connection.
* What data is sent: standard Freemius opt-in data including site URL, administrator email address, WordPress version, PHP version, plugin version, and active theme name.
* Terms of service: https://freemius.com/terms/
* Privacy policy: https://freemius.com/privacy/

== Installation ==

1. Install from the WordPress.org plugin directory (Plugins > Add New), or upload the plugin ZIP (Plugins > Add New > Upload).
2. Activate the plugin.
3. Open the Link Health screen and click "Scan now" to check the links and images on your pages and posts. You can leave the page; the scan continues in the background.
4. Review the By URL and By page tabs, and open any finding to see where it appears and view the source.

== Frequently Asked Questions ==

= How is this different from other broken link checkers? =

Most checkers read links out of your database. This plugin renders each page the way a visitor's browser would and checks the links and images that actually ship - including ones added by your theme, menus, widgets, footers and page builder, which database-only checkers never see. It runs entirely on your own server, with no external crawler and no per-link quota.

= Does it crawl my site? =

No. It audits only your known WordPress content and the links and images those pages output. It never follows links to discover new URLs like a crawler.

= Does it send my site anywhere? =

No. Scanning is local. To check whether an external link or image works, the plugin requests that URL directly from your server - but only URLs that already appear on your pages, and only to read their response. Google Safe Browsing checks are a Premium, opt-in feature that requires your own Google API key; without one, nothing is sent to Google.

= Is the free plugin limited? =

No. It is fully functional with no limits: it scans all your content - posts, pages, custom post types and WooCommerce products, and optionally unpublished content - and checks every link, image and resource. The premium version is a separate plugin, delivered from plugupp.com, that adds the Learning Engine, scheduled scans and email reports, change detection, soft-error and Safe Browsing checks, rule-based exclusions and CSV export. [See the full plan comparison](https://plugupp.com/plugins/link-image-health-audit/)

= Are private or password-protected pages checked? =

Password-protected pages are never scanned - there is no way to render them without the password. Private, draft, scheduled and pending content is skipped by default, but you can include it by enabling Unpublished content in Settings; it is rendered privately for the scan only and never shown to visitors. Make a page public (or remove its password) and it is picked up on the next scan.

= A link shows as "Not checkable" rather than broken. What does that mean? =

Plenty of large sites refuse automated requests while serving people normally - review sites, marketplaces, forums and social platforms all do it. The plugin tells these apart from genuine failures and counts them under "Not checkable" rather than as issues, so you are not chasing false positives. You can open the link, confirm it works and mark it checked in one click.

== Screenshots ==

1. The dashboard - scan controls, the colour-coded Issues, Warnings and Notices summary, and the By URL results listing every unique link and image with its verdict, with hosts that refuse automated visitors counted separately as Not checkable.
2. The By page view - every scanned page with its Issues, Warnings and Notices counts, sorted worst-first for fast triage.
3. Finding details - a broken URL with the pages it appears on and quick actions, so you can jump straight to the page or view the source.
4. View source - the page re-rendered with the exact broken link or image highlighted in context, so you can see where it lives.
5. The Exclusions screen - the pages you have excluded from scanning, with rule-based auto-exclusion on paid plans.
6. Settings - choose which content types are scanned, manage the URL parameters that are ignored, tune scan politeness, and view the log.
7. The URL Parameter Learning Engine (Premium) - suggested parameters with the evidence, a live example you can open both ways, and a one-click add.
8. The Images view (Premium) - every image whose alternative text needs attention, as it was actually rendered, with a plain-English explanation and the WCAG technique behind each finding.
9. The Not checkable view - links whose host refused our automated request, counted separately from real problems rather than reported as broken, each saying what was actually observed, with a one-click way to confirm the link yourself.

== Changelog ==

= 1.4.0 =
* Added: a "Not checkable" result. Some large sites refuse automated visitors while serving people normally, and the audit now counts those separately instead of calling them broken. Nothing in that view is a problem to fix, so it never inflates your issue count.
* Added: "Mark as checked". Open a not-checkable link, confirm it works, and record that in one click. It then counts as OK. The link is still tested on every scan, so a genuine failure is still reported, and the confirmation lasts six months before the audit asks you to look again.
* Fixed: links that a consent or cookie banner has blocked are no longer reported as broken. A blocked embed leaves a placeholder in the page instead of its real address, and the audit now reads the real address and checks that.
* Fixed: sign-in walls are no longer reported as broken. Instagram, Facebook and similar sites answer an automated request with a sign-in page whether the page exists or not, so the audit says it could not check rather than guessing.
* Fixed: many working links reported as broken because the host refuses a lightweight existence check but serves the page normally. The audit now confirms with a full request before reporting anything as broken. This affected map scripts, share links, camera images and more.
* Fixed: a host that asks us to slow down or reports itself temporarily unavailable is no longer recorded as broken. The audit waits, honours the delay the host asks for, and tries again before saying anything.
* Fixed: a link that redirects only to add or remove a trailing slash is now a notice, not a warning. The old advice to update the link was pointless when the address is the same one.
* Fixed: "View source" could not find references written in inline CSS, or in markup using single quotes, and wrongly said the reference was not in the page.
* Fixed: pages whose address redirects elsewhere could never be rendered, which marked the whole scan as degraded, skipped change detection and triggered a repeat scan that failed the same way.
* Fixed: exclusion rules of type URL were discarded on save unless you pressed Enter first, and the URL rule operators are now explained in the builder.
* Improved: results wording throughout, so every verdict says what was actually observed and what, if anything, you should do about it.

= 1.3.0 =
* Added: image alt-text audit (Premium) - finds images with missing, empty or suspicious alternative text on the rendered page, with review tiers and per-image ignores on a new Images view; anything you ignore also shows on the Ignored view.
* Added: archive pages in the By page view now have Re-scan and Exclude actions, and excluded archive pages show a readable name instead of an internal reference.
* Fixed: excluding a page now removes its findings from the results immediately instead of waiting for the next scan.
* Fixed: the images count in the By page view counted responsive-image variants separately; it now counts each image once.
* Maintenance: confirmed compatible with WordPress 7.1.

= 1.2.2 =
* Fixed: scans now pause and resume automatically when the site is briefly unavailable, for example while WordPress runs a scheduled update (maintenance mode), instead of recording every page as a scan error.
* Fixed: pages that cannot be checked during a scan now keep their previous results instead of losing them; the report says so, and a follow-up scan runs automatically.

= 1.2.1 =
* Improved: scans now run to completion on their own and finish much faster on standard shared hosting. Both scan phases - rendering your pages and checking the links found - keep themselves moving in the background instead of waiting for WP-Cron, which stays in place as a safety net.
* Fixed: a scan could stall partway through on hosting where WP-Cron only runs when the site gets a visit. Stalled scans now recover automatically.

= 1.2.0 =
* Added: mixed content detection - images, embeds and page resources that load over plain HTTP on an HTTPS site are flagged as warnings, with a plain-English explanation on the finding.
* Added: every broken external link now carries a "View archived copy" link to the Wayback Machine, so you can see what the dead page used to say or pick a replacement URL.

= 1.1.1 =
* Improved: the activity log gains an "Errors and warnings" level, and the log file is now named after the plugin for easier identification.
* Fixed: uninstalling the plugin now removes all of its stored data and scheduled tasks.

= 1.0.4 =
* Initial public release.
