{"id":325747,"date":"2026-06-17T15:04:44","date_gmt":"2026-06-17T15:04:44","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/linksentinel\/"},"modified":"2026-06-17T15:07:23","modified_gmt":"2026-06-17T15:07:23","slug":"linksentinel","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/linksentinel\/","author":23516002,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"5.8","stable_tag":"5.8","tested":"7.0","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"LinkSentinel - Internal Link and Broken Link Scanner","header_author":"Pragmatic Bear","header_description":"Scan internal links for redirects & breakage. Auto-fix 301\/308 permanently redirected links; queue 302\/307 and broken links for review. Includes a dashboard with progress indicators, automatic scheduled scans, and CSV export for resolved links.","assets_banners_color":"","last_updated":"2026-06-17 15:07:23","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/www.pragmaticbear.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":28,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"pragmaticbear","date":"2026-06-17 15:03:29"},"5.8":{"tag":"5.8","author":"pragmaticbear","date":"2026-06-17 15:07:23"}},"upgrade_notice":{"5.4":"<p>First open-source release (GPL-2.0-or-later) with security hardening, improved documentation, and translation support. Recommended for all users.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3576031,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3576031,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","5.8"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[932,735,14279,175,726],"plugin_category":[],"plugin_contributors":[267571],"plugin_business_model":[],"class_list":["post-325747","plugin","type-plugin","status-publish","hentry","plugin_tags-932","plugin_tags-735","plugin_tags-broken-links","plugin_tags-links","plugin_tags-redirects","plugin_contributors-pragmaticbear","plugin_committers-pragmaticbear"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/linksentinel\/assets\/icon-128x128.png?rev=3576031","icon_2x":"https:\/\/ps.w.org\/linksentinel\/assets\/icon-256x256.png?rev=3576031","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>LinkSentinel<\/strong> keeps your site healthy by scanning internal links in your posts and pages. It detects redirects and broken destinations without following all hops blindly, letting you focus on what matters:<\/p>\n\n<ul>\n<li>Auto-fixes links that are permanently redirected (HTTP 301\/308) while leaving temporary redirects and broken links for review.<\/li>\n<li>Runs scheduled scans (daily\/twice daily\/weekly) with timezone-aware cron control and live progress feedback.<\/li>\n<li>Provides a full dashboard under <strong>Tools &rarr; LinkSentinel<\/strong> for resolved links, pending redirects, broken links, CSV export and settings.<\/li>\n<li>Customizable Resolve All batching with cooldown controls keeps bulk fixes stable even on rate-limited hosts.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>link-sentinel<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory, or install via the WordPress Plugins screen.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress.<\/li>\n<li>Navigate to <strong>Tools &rarr; LinkSentinel<\/strong> and click <strong>Scan Now<\/strong> to scan existing content. Configure automatic scans in the Settings tab to run on your preferred schedule.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20scan%20external%20links%3F\"><h3>Does this plugin scan external links?<\/h3><\/dt>\n<dd><p>Not yet. The plugin currently focuses on internal links within your site's domain. External link scanning is on the roadmap.<\/p><\/dd>\n<dt id=\"what%20about%20images%20and%20media%20files%3F\"><h3>What about images and media files?<\/h3><\/dt>\n<dd><p>Currently only anchor (<code>&lt;a&gt;<\/code>) tags are scanned. Support for images (<code>&lt;img&gt;<\/code> tags) and other media is planned for a future release.<\/p><\/dd>\n<dt id=\"can%20i%20disable%20automatic%20scans%3F\"><h3>Can I disable automatic scans?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>Tools &rarr; LinkSentinel &rarr; Settings<\/strong> and uncheck \"Enable automatic scheduled scans\". You can also adjust the frequency and time to suit your needs.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>5.8<\/h4>\n\n<ul>\n<li><strong>Naming<\/strong>: Renamed all stored options, transients, the custom database table, cron events, AJAX\/admin-post actions, nonces, and the localized admin script object to the unique <code>link_sentinel_<\/code> \/ <code>LinkSentinel<\/code> prefix. Existing installs begin with a fresh scan history; re-run a scan to repopulate.<\/li>\n<li><strong>Developer<\/strong>: Removed the legacy hook aliases retained in 5.6 \u2014 use the <code>link_sentinel_*<\/code> names.<\/li>\n<li><strong>Compliance<\/strong>: Removed runtime <code>error_reporting()<\/code> adjustments in the scanner.<\/li>\n<\/ul>\n\n<h4>5.7<\/h4>\n\n<ul>\n<li>Renamed the plugin to \"LinkSentinel - Internal Link and Broken Link Scanner\" for a clearer, more descriptive listing. No functional changes.<\/li>\n<\/ul>\n\n<h4>5.6<\/h4>\n\n<ul>\n<li><strong>Compliance<\/strong>: Addressed WordPress Plugin Check findings \u2014 escaped remaining admin output, added translators comments and ordered i18n placeholders, and unslashed\/sanitized all request input.<\/li>\n<li><strong>Developer<\/strong>: Public hooks renamed to the <code>link_sentinel_*<\/code> prefix (e.g. <code>link_sentinel_follow_external_redirects<\/code>); legacy aliases were retained for back-compat (removed in 5.8).<\/li>\n<li><strong>Developer<\/strong>: Debug logging is now only written when <code>WP_DEBUG<\/code> is enabled.<\/li>\n<li>Removed the manual <code>load_plugin_textdomain()<\/code> call; WordPress loads translations automatically.<\/li>\n<\/ul>\n\n<h4>5.5<\/h4>\n\n<ul>\n<li><strong>Bug Fix<\/strong>: Redirects to a different domain with an identical path are no longer misclassified as self-redirects; they are now logged for review.<\/li>\n<li><strong>Bug Fix<\/strong>: Starting a manual scan no longer resets a scan already in progress (e.g. one started by another admin).<\/li>\n<li><strong>Bug Fix<\/strong>: The Change Link form now accepts site-relative paths (e.g. <code>\/about-us\/<\/code>) in addition to full http(s) URLs.<\/li>\n<li><strong>Stability<\/strong>: The scan progress loop now stops with a clear message after repeated batch failures instead of retrying indefinitely.<\/li>\n<\/ul>\n\n<h4>5.4<\/h4>\n\n<ul>\n<li>First public, open-source release under GPL-2.0-or-later.<\/li>\n<li>Security: reviewed and hardened AJAX handlers and database queries.<\/li>\n<li>Added a translation template (<code>languages\/link-sentinel.pot<\/code>) and tidied translatable strings for full internationalization support.<\/li>\n<li>Hardened files against direct access and improved inline documentation.<\/li>\n<\/ul>\n\n<h4>5.2.2<\/h4>\n\n<ul>\n<li><strong>Critical Bug Fix<\/strong>: Fixed race condition where manually fixed broken links would become \"stuck\" in the pending queue during subsequent scans.<\/li>\n<li><strong>Improved Duplicate Detection<\/strong>: Enhanced scanner logic to prevent re-logging manually resolved links regardless of resolution status.<\/li>\n<li><strong>Database Efficiency<\/strong>: Optimized duplicate detection queries for better performance.<\/li>\n<li><strong>Stability<\/strong>: Prevented infinite redirect loops with improved URL normalization.<\/li>\n<\/ul>\n\n<h4>5.0.1<\/h4>\n\n<ul>\n<li>Batch processing for manual scans.<\/li>\n<li>Auto-fix permanently redirected links (301\/308).<\/li>\n<li>Queue temporary redirects and broken links for review.<\/li>\n<li>Scheduled scans with timezone-aware cron control.<\/li>\n<li>Dashboard with progress indicators and CSV export.<\/li>\n<\/ul>\n\n<h4>4.6 - 2025-11-17<\/h4>\n\n<ul>\n<li>Added: Resolve All batching controls in settings with checkbox gating, custom links-per-batch, and cooldown inputs to prevent rate limits.<\/li>\n<li>Added: Shared preference helper so PHP and JavaScript stay in sync when honoring user pacing choices.<\/li>\n<li>Improved: Resolve All localization, timers, and AJAX handler now respect saved batch\/cooldown limits to avoid regressions.<\/li>\n<\/ul>\n\n<h4>4.4 - 2025-11-17<\/h4>\n\n<ul>\n<li>Added: A throttled mode for hosts with strict rate limits \u2014 single-item batches, longer pacing, and tighter server-side throttles to prevent 429 errors.<\/li>\n<li>Added: Resolve All diagnostics in the browser console for fast root-cause analysis.<\/li>\n<li>Improved: Resolve All batching now self-tunes based on step durations and memory ceilings; logging hardened with safer output buffering.<\/li>\n<li>Updated: Documentation and admin UI messaging for the throttled workflow and recommended troubleshooting steps.<\/li>\n<\/ul>\n\n<h4>3.5 - 2025-11-12<\/h4>\n\n<ul>\n<li>Introduced timezone-aware scheduled scans with daily\/twice daily\/weekly frequency controls.<\/li>\n<li>Added progress indicators, scan history, and concurrency protection between manual and scheduled runs.<\/li>\n<\/ul>\n\n<h4>1.9 - 2025-10-22<\/h4>\n\n<ul>\n<li>Added \"Resolved By\" tracking for manual actions plus table wrapping fixes and accountability improvements.<\/li>\n<\/ul>","raw_excerpt":"Scan internal links for redirects and broken destinations. Auto-fix 301\/308 permanent redirects and queue the rest for review.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/325747","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=325747"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/pragmaticbear"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=325747"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=325747"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=325747"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=325747"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=325747"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=325747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}