=== LinkVeri ===
Contributors: kylin010
Tags: broken links, link checker, 404, dead links, seo
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Finds broken links in posts, page builder content, menus, widgets and comments. Blocked checks are reported, not guessed.

== Description ==

LinkVeri checks every link on your site, a few at a time in the background, and reports the results in a way you can act on without second-guessing.

= Three states, not two =

A 403 means the site refused to answer an automated request. A 301 is a normal redirect. Neither means the page is gone, so LinkVeri does not call them broken. It reports three states:

* **Confirmed dead** — the target really is gone. That means the server answered 404 or 410, or the domain no longer resolves,, or the link points at content on your own site that was deleted, is no longer public, or is a file that is not on disk
* **Unverifiable** — the site blocked the check (403, 429, timeout) or asks not to be checked in its robots.txt. LinkVeri says so instead of guessing
* **OK** — everything else

When a site answers 403, LinkVeri sends one extra request to a deliberately non-existent path on the same domain. If that comes back 404, the site does answer automated requests, so the original 403 is a genuine permission restriction and the page exists. If that is blocked too, the site blocks everything and LinkVeri cannot know, so it tells you exactly that.

= Where it looks =

* Post and page content
* Elementor content stored in post meta, including templates, headers and footers
* Navigation menus
* Widgets
* Comments — both the comment text and the commenter's website field
* Custom fields whose value is a URL, including ACF fields
* Category and tag descriptions
* Image and iframe sources

= Light on your server =

LinkVeri checks a handful of links every few minutes, forever. No burst, no spike. When a visitor is browsing your site it drops to the smallest batch size to stay out of the way.

Most internal links are resolved directly from your database instead of over HTTP. Only the few it cannot classify locally are requested, so the plugin does not compete with your visitors for PHP workers.

Need results right now? Click **Scan the whole site now**. It runs only while you keep that page open, shows live progress, and stops the moment you close the tab or press Stop.

= LinkVeri Pro =

The free version checks every link on your site, with no cap on how many, and reports what it finds. It never modifies your content.

LinkVeri Pro adds one-click fixing: replace a dead link, or unlink it while keeping the text, across every place it appears. Before changing anything, Pro copies the original content into its own backup table — independent of WordPress revisions — so every fix is one undoable batch.

== Installation ==

1. Install it through **Plugins → Add New**, or upload the plugin folder to your plugins directory
2. Activate it
3. Open **LinkVeri** in your admin menu

That's it. Checking starts automatically in the background. Click **Scan the whole site now** if you want results immediately.

== Frequently Asked Questions ==

= Will this slow down my website? =

No. The background check handles only a few links every five minutes and automatically backs off when your site is busy. Most links to your own site are answered from the database with no HTTP request at all; only the ones that cannot be classified that way are actually requested.

= Why does a link show as "Couldn't verify" instead of broken? =

Because the target site refused the check. Many large sites (Stack Overflow, Medium, Amazon, LinkedIn) block automated requests. That tells us nothing about whether the page exists, so LinkVeri does not guess. Open the link yourself to confirm.

= Can the plugin fix links for me? =

Detection is free and unlimited. Replacing or unlinking dead links in one click, with automatic backups and undo, is part of LinkVeri Pro.

= Does it work with Elementor? =

Yes, including headers and footers built with Elementor. Their links live in post meta, and LinkVeri reads them from there.

= How many results does the list show? =

The list shows up to 50 confirmed dead links and 50 unverifiable ones at a time, ordered by how many places each link appears in. Checking itself is not limited: every link on the site is checked and counted, and the totals above the tables reflect all of them.

= Does it check images? =

Yes. `<img>` and `<iframe>` sources are checked alongside regular links.

== Screenshots ==

1. Results are grouped into three states. Only the first group is called broken; the second is what the plugin could not check, said plainly rather than guessed.
2. The unverifiable group, with the reason for each link. Sites that refuse automated checks, and sites whose robots.txt asks not to be checked, land here instead of being reported as dead.

== External services ==

= Checking links =

To find out whether a link still works, LinkVeri sends an HTTP HEAD request (and, if the site rejects HEAD, a small GET limited to the first 2 KB) from your server to that link's address. Before contacting any site for the first time it reads that site's robots.txt and honours it. Requests go only to links found in your own content; nothing is sent about your site or you. The User-Agent is fixed and documented at https://linkveri.com/bot so site owners can identify and, if they wish, block it. Links pointing at private or internal network addresses are never requested.

= Freemius =

LinkVeri uses the Freemius SDK for licensing, updates of the Pro version, and optional usage tracking. Tracking is opt-in: nothing is sent unless you explicitly allow it on the screen shown after activation, and you can skip it. If you opt in, Freemius receives the information listed on that screen — your name and email address, your site URL, title and language, your WordPress and PHP versions, the plugin and SDK versions, the plugins and themes installed on the site, and activation, deactivation and uninstall events. Each of these is listed individually on the opt-in screen and can be reviewed there before you agree. Freemius privacy policy: https://freemius.com/privacy/ — terms: https://freemius.com/terms/

== Changelog ==

= 1.0.4 =
* The fix button now offers the free trial to people who have not used one yet, and returns to the upgrade link afterwards.

= 1.0.3 =
* Larger, more readable type throughout the results screen.
* Counts, tables and status codes redesigned for scanning a long list.
* Admin styles are now enqueued through the WordPress style API.

= 1.0.2 =
* A domain that cannot be looked up is no longer reported as broken unless the lookup itself is known to be working, and internationalized domain names are now encoded correctly before lookup.
* Response bodies are capped locally instead of relying on the server to honour a Range request.
* robots.txt rules are matched without regular expressions.
* Pro: unlinking a menu item can now be undone.
* Result state names in this readme match the labels shown in the plugin.

= 1.0.1 =
* Admin scripts are now enqueued through the WordPress script API.
* Static-file paths are derived from the site's content and includes URLs instead of fixed prefixes.
* Translations for the free version come from translate.wordpress.org; no translation files are bundled.
* Readme and description corrected to match exactly what the code does.

= 1.0.0 =
* First release.
* Three-state reporting: only 404 and 410 count as broken; blocked checks are labelled as such instead of guessed.
* Scans page builder content, navigation menus, widgets, comments, custom fields and term descriptions.
* Most internal links are resolved against the database instead of over HTTP.
* Continuous background checking that slows down when visitors are active.
* Honours robots.txt (RFC 9309) before requesting anything on another site.
* Pro: one-click replace and unlink, with every change backed up and undoable.
