{"id":383882,"date":"2026-10-10T14:12:48","date_gmt":"2026-10-10T14:12:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/effortless-website-health-check\/"},"modified":"2026-10-12T13:45:13","modified_gmt":"2026-10-12T13:45:13","slug":"effortless-website-health-check","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/effortless-website-health-check\/","author":23148025,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.38","stable_tag":"1.0.38","tested":"7.1.3","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"EffortLess Website Health Check","header_author":"domclic","header_description":"Public website audit tool. A visitor submits a URL, receives a 0-100 health score with recommendations and an indicative quote, and is captured as a lead in the admin.","assets_banners_color":"9e9e9e","last_updated":"2026-10-12 13:45:13","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/id7.dev\/donate\/","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":68,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.36":{"tag":"1.0.36","author":"domclic","date":"2026-10-10 14:22:06","revision":3738142},"1.0.37":{"tag":"1.0.37","author":"domclic","date":"2026-10-12 13:27:05","revision":3741698},"1.0.38":{"tag":"1.0.38","author":"domclic","date":"2026-10-12 13:45:13","revision":3741783}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.jpg":{"filename":"icon-128x128.jpg","revision":3738142,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3738142,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3738142,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3738142,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.36","1.0.37","1.0.38"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Public audit form and result.","2":"Admin dashboard with lead statistics.","3":"Audit detail with findings and copyable follow-up messages."}},"plugin_section":[],"plugin_tags":[8533,34356,247,600,186],"plugin_category":[54,55],"plugin_contributors":[241557],"plugin_business_model":[],"class_list":["post-383882","plugin","type-plugin","status-publish","hentry","plugin_tags-audit","plugin_tags-health-check","plugin_tags-performance","plugin_tags-security","plugin_tags-seo","plugin_category-security-and-spam-protection","plugin_category-seo-and-marketing","plugin_contributors-domclic","plugin_committers-domclic"],"banners":{"banner":"https:\/\/ps.w.org\/effortless-website-health-check\/assets\/banner-772x250.jpg?rev=3738142","banner_2x":"https:\/\/ps.w.org\/effortless-website-health-check\/assets\/banner-1544x500.jpg?rev=3738142","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/effortless-website-health-check\/assets\/icon-128x128.jpg?rev=3738142","icon_2x":"https:\/\/ps.w.org\/effortless-website-health-check\/assets\/icon-256x256.jpg?rev=3738142","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>EffortLess Website Health Check adds a shortcode, <code>[elwhc_health_check]<\/code>, that displays a form. A visitor enters a website URL and an email address, confirms they own the site or are authorized to request the audit, and submits. The plugin then fetches the public home page of that site with the WordPress HTTP API and returns:<\/p>\n\n<ul>\n<li>An overall score out of 100.<\/li>\n<li>Six category scores: HTTPS, security headers, WordPress hygiene, performance, technical SEO, and contact\/conversion.<\/li>\n<li>A list of findings, each with a severity (Important \/ To improve \/ For info) and a recommendation.<\/li>\n<li>An indicative price range, chosen from the price ranges you configure according to the score.<\/li>\n<li>Buttons to contact you on LINE (if a LINE URL is set), request a quote, and print or save the report as a PDF via the browser's print dialog.<\/li>\n<\/ul>\n\n<p>Every submission is stored in the admin under <strong>Website Health Check \u2192 Audits<\/strong>, with a dashboard, filters (score, lead status, search), a detail page, lead statuses, internal notes, copyable follow-up messages and a CSV export.<\/p>\n\n<h4>What the audit checks<\/h4>\n\n<p>The audit only reads publicly available responses. Per audit it sends a small number of requests to the submitted site: the home page (HTTPS, falling back to HTTP), the <code>http:\/\/<\/code> variant to check for an HTTPS redirect, <code>robots.txt<\/code>, <code>sitemap.xml<\/code> \/ <code>wp-sitemap.xml<\/code>, and one TLS connection to read the certificate's expiry date. Everything else is derived from the response headers and the HTML of the home page: security headers, compression, caching headers, page size, number of scripts and stylesheets, mixed content, title and meta description length, H1, Open Graph, Schema.org, analytics, favicon, WordPress detection and an exposed WordPress version. It does not log in, submit forms, test for vulnerabilities, or crawl other pages.<\/p>\n\n<h4>Settings<\/h4>\n\n<p>All settings are under <strong>Website Health Check \u2192 Settings<\/strong>.<\/p>\n\n<p>Public form<\/p>\n\n<ul>\n<li><strong>Enable public form<\/strong> (on by default) \u2014 when off, the shortcode shows \"temporarily unavailable\" and the REST endpoint rejects submissions.<\/li>\n<li><strong>Audits per IP \/ day<\/strong> (default 10, 0 = no limit) \u2014 maximum audits one visitor IP address can run per day.<\/li>\n<li><strong>Audits per domain \/ day<\/strong> (default 5, 0 = no limit) \u2014 maximum audits for the same domain per day.<\/li>\n<li>Independently of these settings, one IP address can run at most 5 audits per minute.<\/li>\n<li><strong>HTTP timeout (seconds)<\/strong> (3-30, default 12) \u2014 timeout for each request sent to the audited site.<\/li>\n<\/ul>\n\n<p>Pricing<\/p>\n\n<ul>\n<li><strong>Currency<\/strong> \u2014 EUR (default), USD, GBP, CHF, CAD, AUD, BRL, MXN, JPY, KRW, CNY or TWD. The symbol is shown before each amount; the price ranges below are plain numbers you set yourself, so enter them in the chosen currency.<\/li>\n<li><strong>Price ranges<\/strong> (min\/max for Standard optimization, Complete repair, Monthly maintenance). The estimate shown to the visitor is picked by score: 80-100 uses Monthly maintenance, 60-79 uses Standard optimization, 0-59 uses Complete repair.<\/li>\n<\/ul>\n\n<p>Contact<\/p>\n\n<ul>\n<li><strong>LINE contact URL<\/strong> \u2014 when set, a \"Contact me on LINE\" button appears on the result. Leave empty to hide it.<\/li>\n<li><strong>Contact email<\/strong> (default: the site admin email) \u2014 receives quote requests submitted from the result popup.<\/li>\n<li><strong>CTA text<\/strong> \u2014 label of the \"Request a full quote\" button. Leave empty to use the translated default.<\/li>\n<\/ul>\n\n<p>Legal \/ GDPR<\/p>\n\n<ul>\n<li><strong>Terms of Use URL<\/strong> and <strong>Privacy Policy URL<\/strong> \u2014 linked from the optional \"receive my quote by email\" consent checkbox. Leave empty to show the label as plain text.<\/li>\n<\/ul>\n\n<p>Data &amp; advanced<\/p>\n\n<ul>\n<li><strong>Data retention (days)<\/strong> (default 0 = keep forever) \u2014 audits older than this are deleted by a daily scheduled task.<\/li>\n<li><strong>PageSpeed Insights<\/strong> (off by default) and <strong>API key<\/strong> \u2014 when both are set, Google PageSpeed Insights mobile and desktop scores are added to the result and drive the performance score. See External services.<\/li>\n<li><strong>Debug mode<\/strong> (off by default) \u2014 writes extra diagnostic entries to <strong>Website Health Check \u2192 Tools &amp; Logs<\/strong>.<\/li>\n<li><strong>On uninstall<\/strong> (off by default) \u2014 when checked, deleting the plugin removes its tables, settings and secrets.<\/li>\n<\/ul>\n\n<h4>Multisite<\/h4>\n\n<p>Each site keeps its own audits and settings. A network administrator can turn on global mode under <strong>Network Admin \u2192 Settings \u2192 Website Health Check<\/strong> to apply one shared set of settings to every site. In global mode, a site can still use its own currency and prices from its own Settings page.<\/p>\n\n<h4>Notes and limitations<\/h4>\n\n<ul>\n<li>The score is a quick, automated reading of a site's public home page, not a full audit. Sites that return a block or challenge page (bot filters, CDNs) get their content-based checks marked \"Not assessed\".<\/li>\n<li>Private, local and reserved IP addresses (IPv4 and IPv6) are refused, including after redirects, and URLs containing credentials are rejected.<\/li>\n<li>Visitor IP addresses are never stored as-is; only a keyed hash is kept for rate limiting.<\/li>\n<li>When a visitor ticks \"receive my quote by email\", the plugin first sends a confirmation link to that address and only emails the quote after the link is clicked. Email delivery uses <code>wp_mail()<\/code>, so it depends on your site's mail setup.<\/li>\n<li>The form uses the REST API (<code>\/wp-json\/elwhc\/v1\/audit<\/code>, with a <code>?rest_route=<\/code> fallback). If a security plugin blocks the REST API for anonymous visitors, submissions fail.<\/li>\n<li>Page caching: the form includes a REST nonce. If a cached page is served for longer than the nonce lifetime (24 hours by default), submissions fail with \"Security check failed\" until the cache is cleared. Exclude the page containing the shortcode from your page cache if this happens.<\/li>\n<\/ul>\n\n<h4>Languages<\/h4>\n\n<p>Includes French (fr_FR), German (de_DE), Spanish (es_ES), Brazilian Portuguese (pt_BR), Korean (ko_KR), Japanese (ja) and Traditional Chinese (zh_TW) translations in the <code>languages<\/code> folder, plus a <code>.pot<\/code> template. A translation approved on translate.wordpress.org takes priority over the bundled file for that language.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin can optionally connect to one third-party service:<\/p>\n\n<ul>\n<li><strong>Google PageSpeed Insights API<\/strong> \u2014 Only used when you enable it and provide an API key in the settings (off by default). When enabled, the URL submitted by the visitor is sent to Google's PageSpeed Insights API to retrieve performance data for each audit. No visitor personal data (email, IP address) is sent. Terms: https:\/\/developers.google.com\/terms \u2014 Privacy policy: https:\/\/policies.google.com\/privacy<\/li>\n<\/ul>\n\n<p>In addition, the plugin sends HTTP requests to the website URL a visitor submits (the site being audited) to read its public responses, as described under \"What the audit checks\".<\/p>\n\n<!--section=installation-->\n<ol>\n<li>In the admin, go to <strong>Plugins \u2192 Add New Plugin<\/strong>, search for \"EffortLess Website Health Check\", click <strong>Install Now<\/strong>, then <strong>Activate<\/strong>. (Or upload the zip under <strong>Plugins \u2192 Add New Plugin \u2192 Upload Plugin<\/strong>.) The plugin's database tables are created on activation; on multisite, network activation creates them for every site, including sites added later.<\/li>\n<li>Go to <strong>Website Health Check \u2192 Settings<\/strong>. Set the <strong>Currency<\/strong> and <strong>Price ranges<\/strong>, check the <strong>Contact email<\/strong>, and optionally add a <strong>LINE contact URL<\/strong>, <strong>Terms of Use URL<\/strong> and <strong>Privacy Policy URL<\/strong>. Click <strong>Save Changes<\/strong>.<\/li>\n<li>Create or edit a page, add the shortcode <code>[elwhc_health_check]<\/code> (Shortcode block in the block editor), and publish it.<\/li>\n<li>Visit the page, enter a URL and an email, tick the authorization checkbox and click the submit button. The result appears on the page, and the submission is listed under <strong>Website Health Check \u2192 Audits<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"i%20added%20the%20shortcode%20but%20nothing%20happens%20when%20i%20submit%20the%20form\"><h3>I added the shortcode but nothing happens when I submit the form<\/h3><\/dt>\n<dd><p>Check the following:<\/p>\n\n<ul>\n<li><strong>Enable public form<\/strong> is checked under Website Health Check \u2192 Settings.<\/li>\n<li>The visitor has not hit the <strong>Audits per IP \/ day<\/strong> or <strong>Audits per domain \/ day<\/strong> limit (the form shows a message when a limit is reached).<\/li>\n<li>The REST API is reachable by logged-out visitors \u2014 some security plugins disable it.<\/li>\n<li>The page is not served from a cache older than 24 hours (see Notes and limitations).<\/li>\n<li>The submitted URL points to a public website; local or private addresses are refused.<\/li>\n<\/ul>\n\n<p>With <strong>Debug mode<\/strong> on, errors are written to Website Health Check \u2192 Tools &amp; Logs.<\/p><\/dd>\n<dt id=\"does%20the%20audit%20put%20load%20on%20the%20analyzed%20site%3F\"><h3>Does the audit put load on the analyzed site?<\/h3><\/dt>\n<dd><p>Each audit sends a handful of requests (listed under \"What the audit checks\"), and per-IP and per-domain daily limits apply.<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20pagespeed%20api%20key%3F\"><h3>Do I need a PageSpeed API key?<\/h3><\/dt>\n<dd><p>No. The audit works without any external API. A Google PageSpeed Insights API key is only needed if you enable the optional PageSpeed integration.<\/p><\/dd>\n<dt id=\"where%20are%20the%20leads%20stored%3F\"><h3>Where are the leads stored?<\/h3><\/dt>\n<dd><p>In two custom database tables (<code>{prefix}elwhc_audits<\/code> and <code>{prefix}elwhc_logs<\/code>) on each site. They can be exported to CSV under Website Health Check \u2192 Tools &amp; Logs.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.38<\/h4>\n\n<ul>\n<li>Removed the manual load_plugin_textdomain() call; translations are loaded by WordPress.<\/li>\n<\/ul>\n\n<h4>1.0.37<\/h4>\n\n<ul>\n<li>Completed the bundled translation files: a template (.pot) and translations for Spanish, Traditional Chinese, Korean, French, Japanese, German, Italian and Brazilian Portuguese.<\/li>\n<\/ul>\n\n<h4>1.0.36<\/h4>\n\n<ul>\n<li>Fix: the bundled French, German, Spanish, Brazilian Portuguese, Korean, Japanese and Traditional Chinese translations are loaded again (the text domain was no longer loaded since 1.0.33) and ship in the plugin package. The <code>Domain Path<\/code> header is restored.<\/li>\n<\/ul>\n\n<h4>1.0.35<\/h4>\n\n<ul>\n<li>Changed: translation source files were kept out of the plugin package (reverted in 1.0.36).<\/li>\n<\/ul>\n\n<h4>1.0.34<\/h4>\n\n<ul>\n<li>Changed: variables in the admin view templates now carry the plugin prefix.<\/li>\n<\/ul>\n\n<h4>1.0.33<\/h4>\n\n<ul>\n<li>Security: the quote request endpoint now requires an access token that is issued only in the response to the audit it belongs to. Previously any valid REST nonce plus a numeric audit ID could add a note to, or change the lead status of, any stored audit.<\/li>\n<li>Changed: the readme short description is shortened to 150 characters or fewer.<\/li>\n<li>Changed: translation files are no longer bundled and the plugin no longer calls <code>load_plugin_textdomain()<\/code>; translations are delivered through translate.wordpress.org language packs. The <code>Domain Path<\/code> header is removed.<\/li>\n<\/ul>\n\n<h4>1.0.32<\/h4>\n\n<ul>\n<li>New: GBP, CHF, CAD, AUD, BRL, MXN, JPY, KRW and CNY added to the Currency setting (EUR, USD and TWD are unchanged). Existing audits keep the currency they were created with.<\/li>\n<\/ul>\n\n<h4>1.0.31<\/h4>\n\n<ul>\n<li>Changed: shortened the plugin description and reworded one FAQ answer to describe the audit requests factually.<\/li>\n<li>New: Spanish (es_ES), German (de_DE), Brazilian Portuguese (pt_BR), Korean (ko_KR) and Japanese (ja) translations.<\/li>\n<li>i18n: regenerated the <code>.pot<\/code> template and the French and Traditional Chinese translations; strings for findings removed in 1.0.28 and the old offer names are no longer included.<\/li>\n<\/ul>\n\n<h4>1.0.30<\/h4>\n\n<ul>\n<li>Changed: the offer shown with the visitor's estimate now uses the same names as the price ranges in Settings \u2192 Pricing (\"Monthly maintenance\" instead of \"Preventive maintenance\", \"Standard optimization\" instead of \"Light optimization\").<\/li>\n<\/ul>\n\n<h4>1.0.29<\/h4>\n\n<ul>\n<li>Removed: the \"Small fix\" price range from Settings \u2192 Pricing. It was saved but never used by the estimate.<\/li>\n<li>Changed: scores below 40 now show the \"Complete repair\" offer, matching the price range they were already quoted with (previously labelled \"Priority manual audit\" while using the Complete repair prices).<\/li>\n<\/ul>\n\n<h4>1.0.28<\/h4>\n\n<ul>\n<li>Changed: the audit no longer requests \/xmlrpc.php, \/wp-json\/wp\/v2\/users, \/.git\/HEAD or \/readme.html on the submitted site. It now only reads the home page, robots.txt, sitemaps and the TLS certificate. The corresponding four findings were removed.<\/li>\n<li>Removed: the unused public REST route GET \/elwhc\/v1\/audit\/{id}, which returned any stored audit's result by its numeric ID.<\/li>\n<li>Fix: the bundled French and Traditional Chinese translations are loaded again (they were not loaded since 1.0.22).<\/li>\n<li>Fix: the donate notice now appears on the Settings screens in every admin language, not only English.<\/li>\n<li>Changed: the quote confirmation page now uses the standard WordPress message page instead of its own inline stylesheet, and the printable report window is built without inline script or style tags.<\/li>\n<li>Changed: database queries now pass table and column names through prepared-statement identifier placeholders. Requires WordPress 6.2 or later.<\/li>\n<li>Removed: the filter that forced the plugin's name to stay in English in the Plugins list.<\/li>\n<li>Readme: documented every setting, the requests the audit sends, and known limitations.<\/li>\n<\/ul>\n\n<h4>1.0.27<\/h4>\n\n<ul>\n<li>Fix: the audit form and result boxes had no explicit text color of their own, so they silently inherited the active theme's body text color \u2014 on a theme with light\/white body text, they could render nearly invisible against their fixed light backgrounds. The plugin's whole front-end output now sets its own explicit text color instead of relying on the theme.<\/li>\n<\/ul>\n\n<h4>1.0.26<\/h4>\n\n<ul>\n<li>Security: the \"receive my quote by email\" checkbox no longer emails the audit report straight to whatever address is typed in. It now sends a confirmation link first, and only sends the actual quote once that link is clicked \u2014 closing a gap where the public form could otherwise be used to email an arbitrary third party's inbox.<\/li>\n<li>Fix: closed a race condition in the per-IP\/per-domain daily audit limits where several concurrent requests could all slip past the count check before any of them was recorded; added a short atomic burst guard.<\/li>\n<li>Fix: the score review's clearer \"highlights\" layout (introduced in 1.0.25) is now also used on the printable PDF report and the admin audit detail page, instead of only the interactive on-page result \u2014 both previously still showed the old \"Score: X\/100 \u2014 Label \u2014\" flat sentence.<\/li>\n<li>Fix: uninstalling with \"delete all plugin data\" enabled now also removes two secret options that were left behind (elwhc_ip_hash_secret, elwhc_quote_token_secret).<\/li>\n<li>i18n: regenerated the .pot and updated the French and Traditional Chinese translations to cover strings added in 1.0.24\/1.0.25 (consent checkbox, Settings \u2192 Legal\/GDPR, quote emails).<\/li>\n<\/ul>\n\n<h4>1.0.25<\/h4>\n\n<ul>\n<li>Improved: the on-page audit result now shows a clearer, more visual \"score review\" \u2014 a plain-language condition sentence, the top priority findings as severity-colored chips, and the indicative estimate in a prominent highlight box, instead of one long summary sentence.<\/li>\n<li>New: the \"Contact on LINE\" \/ \"Request a quote\" \/ \"Download PDF report\" buttons now also appear right after the score review, in addition to the end of the results, so visitors do not have to scroll to act on their result.<\/li>\n<\/ul>\n\n<h4>1.0.24<\/h4>\n\n<ul>\n<li>New: an optional \"receive my quote by email and accept the Terms of Use \/ Privacy Policy (GDPR)\" consent checkbox on the public form. When checked, the submit button label changes to \"Analyze my site and receive the quote\", the consent is stored with the lead, and the visitor is emailed their score, priority findings and price estimate immediately after the audit.<\/li>\n<li>New: Settings \u2192 Legal \/ GDPR section to configure the Terms of Use and Privacy Policy URLs linked from that checkbox.<\/li>\n<\/ul>\n\n<h4>1.0.23<\/h4>\n\n<ul>\n<li>Fix: trimmed the readme's Tags line from 6 to 5 (removed \"leads\"), per WordPress.org's tag limit.<\/li>\n<li>Update: Tested up to WordPress 7.1.<\/li>\n<\/ul>\n\n<h4>1.0.22<\/h4>\n\n<ul>\n<li>Fix: removed the Author URI header (pointed at a promotional domain, not permitted for submission), and added the required Donate link plus a dismissible donate notice on the Settings and Network Settings screens.<\/li>\n<li>Fix: removed the discouraged load_plugin_textdomain() call \u2014 WordPress.org auto-loads translations for hosted plugins.<\/li>\n<li>Fix: the plugin's name in the Plugins list is now forced to stay in English, so a GlotPress community translation of the \"Plugin Name\" header can no longer rename the brand on non-English sites.<\/li>\n<li>Security: the visitor IP hash no longer derives its HMAC key from wp_salt() \u2014 it now uses a standalone, plugin-generated secret stored per site, independent of WordPress's own auth material.<\/li>\n<li>Bumped \"Tested up to\" to 7.0.<\/li>\n<\/ul>\n\n<h4>1.0.21<\/h4>\n\n<ul>\n<li>Fix: \"HTTPS not detected\" could be wrongly reported for a site that is fully HTTPS but was audited via an http:\/\/ URL that correctly redirects to HTTPS (e.g. via .htaccess). The audit now probes https:\/\/ directly in that case instead of assuming HTTPS is broken just because the request started on http, and the TLS-certificate check now runs whenever HTTPS is confirmed working rather than only when the original request used https.<\/li>\n<li>New: when HTTPS genuinely fails (invalid\/incomplete certificate chain, a firewall blocking the request, etc.) with Debug mode enabled, the real underlying error is now recorded under Tools and Logs instead of only the generic finding text.<\/li>\n<\/ul>\n\n<h4>1.0.20<\/h4>\n\n<ul>\n<li>New: \"Download PDF report\" on the public result and the admin audit detail page. Opens a branded, print-ready report (via the browser's native print-to-PDF, no external library or dependency) with the full score, category breakdown, PageSpeed and every finding \u2014 not just the on-screen top 8. The admin version also hides the WP admin chrome and interactive-only sections when printing.<\/li>\n<li>Fix: the \"Core Web Vitals\" table label was hardcoded in English; it is now translated (fr_FR\/zh_TW added).<\/li>\n<\/ul>\n\n<h4>1.0.19<\/h4>\n\n<ul>\n<li>Security: the TLS-certificate-expiry check (introduced in 1.0.16) opened a raw socket directly to the audited domain without the SSRF protection used everywhere else in the plugin. It now resolves and validates the domain to a public IP first and connects to that literal IP (with SNI still set to the hostname), closing a DNS-rebinding gap.<\/li>\n<li>Fix: six new WordPress-hygiene findings (exposed .git, user enumeration, XML-RPC, readme.html, etc.) were tagged with the category 'WordPress' instead of the lowercase 'wordpress' id used everywhere else, which would have silently split them out of any future per-category filtering or reporting.<\/li>\n<\/ul>\n\n<h4>1.0.18<\/h4>\n\n<ul>\n<li>Multisite: when global (network-wide) mode is on, each site can now optionally keep its own currency and prices while all other settings stay global \u2014 useful for a network of sites targeting different countries. Set it under a site's Website Health Check \u2192 Settings.<\/li>\n<\/ul>\n\n<h4>1.0.17<\/h4>\n\n<ul>\n<li>PageSpeed Insights now reports both mobile and desktop, shown side by side (result, admin detail and quote email). The mobile score continues to drive the performance rating (Google is mobile-first).<\/li>\n<\/ul>\n\n<h4>1.0.16<\/h4>\n\n<ul>\n<li>New: Google PageSpeed Insights integration (opt-in, needs an API key). Real mobile Lighthouse scores (performance, SEO, accessibility, best practices) and Core Web Vitals are shown in the result, admin detail and quote email, and drive the performance score.<\/li>\n<li>New checks: TLS certificate expiry, mixed content, exposed .git\/readme.html, XML-RPC enabled, REST user enumeration, page-title length, missing H1, and Open Graph\/Schema.org\/analytics detection.<\/li>\n<\/ul>\n\n<h4>1.0.15<\/h4>\n\n<ul>\n<li>Fix: rate-limit, retention and \"this week\" windows now use the site timezone (they previously used UTC while rows are stored in local time), so the per-IP\/per-domain daily limits and data retention are accurate on non-UTC sites.<\/li>\n<li>Fix\/security: the URL validator now resolves IPv6 (AAAA) records and blocks private\/reserved IPv6 ranges (including unique-local fc00::\/7). IPv6-only sites can now be audited, and an AAAA record pointing at an internal address can no longer bypass the SSRF check.<\/li>\n<\/ul>\n\n<h4>1.0.14<\/h4>\n\n<ul>\n<li>The quote-request notification email now contains the full report (overall score, summary, every category score, all findings with recommendations and the estimate) in addition to the visitor's message, instead of only the score.<\/li>\n<\/ul>\n\n<h4>1.0.13<\/h4>\n\n<ul>\n<li>Security: added a honeypot field to the audit form and quote popup to silently reject automated bot submissions (no third-party service, no CAPTCHA for real visitors).<\/li>\n<\/ul>\n\n<h4>1.0.12<\/h4>\n\n<ul>\n<li>Security hardening: block SSRF via redirects and DNS rebinding by re-validating every request and redirect hop (reject_unsafe_urls) and capping the download size at the transport level; reject URLs containing embedded credentials; rate-limit quote requests and cap the message length; and neutralize spreadsheet formula injection in the CSV export.<\/li>\n<\/ul>\n\n<h4>1.0.11<\/h4>\n\n<ul>\n<li>Fix: the \"Request a full quote\" button now follows the site language. Its label is a stored setting whose English default did not translate; it now falls back to the translated default when left at the default or empty. You can still enter a custom label per site.<\/li>\n<\/ul>\n\n<h4>1.0.10<\/h4>\n\n<ul>\n<li>New: translations. The plugin now ships with French (fr_FR) and Traditional Chinese \/ Taiwan (zh_TW) alongside English, covering both the admin and the public form\/result\/quote popup. A .pot template is included.<\/li>\n<\/ul>\n\n<h4>1.0.9<\/h4>\n\n<ul>\n<li>Fix: HTTPS is no longer reported as missing when a site returns a non-200 status (e.g. a 403\/503 from a security filter or CDN) \u2014 any response over HTTPS now counts as HTTPS working.<\/li>\n<li>Fix: when a site returns a block\/challenge page instead of its real content, the content-based checks (WordPress, SEO, contact) are marked \"Not assessed\" and excluded from the score instead of reporting false errors, with one clear note explaining why.<\/li>\n<li>Clearer results: findings now show a severity label (Important \/ To improve \/ For info) with the issue and recommendation, category rows show \"Not assessed\" where applicable, and a positive message appears when nothing needs attention.<\/li>\n<\/ul>\n\n<h4>1.0.8<\/h4>\n\n<ul>\n<li>New: \"Request a quote\" now opens a popup form pre-filled with the visitor's email, website URL and an editable message (built from their audit result). Submitting it records the request on the lead (status \"Quote requested\") and emails the site's contact address. Added a REST endpoint \/elwhc\/v1\/quote for this.<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>Fix: the public form now receives its configuration (REST endpoint, nonce, translations) via a data attribute on the form instead of wp_localize_script, which some themes\/caches\/multisite setups did not print \u2014 this was the underlying cause of submissions reloading the page with no result.<\/li>\n<li>New: full multisite support. Tables are created for every site on network activation and for any new site; uninstall cleans up each site.<\/li>\n<li>New: optional global (network-wide) settings. A network admin can enable global mode under Network Admin \u2192 Settings \u2192 Website Health Check to apply one shared configuration to all sites.<\/li>\n<\/ul>\n\n<h4>1.0.6<\/h4>\n\n<ul>\n<li>Fix: on block themes (e.g. Twenty Twenty-Five \/ Full Site Editing) the form script was not being enqueued because the shortcode was not detected on the main post, so submissions only reloaded the page. The script and its data now load on all singular views and no-op when no form is present.<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>Fix: the public form script now loads in the page header and initializes on DOMContentLoaded, so it works even on themes\/page builders that do not output wp_footer() where expected. This resolves cases where submitting the form simply reloaded the page instead of running the audit.<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Email is now required on the public form; the name and LINE ID fields have been removed for now.<\/li>\n<li>Fix: added a language-agnostic REST fallback endpoint so submissions work on multilingual sites (e.g. WPML\/Polylang) where the default REST URL can 404. The form now retries the fallback automatically and logs diagnostics to the browser console.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Fix: the public form script now loads reliably by detecting the shortcode in the page content up front, so submissions are handled by JavaScript instead of falling back to a full-page reload. Hardened the form to POST to itself so visitor details are never exposed in the URL if scripts are unavailable.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Set plugin author to domclic.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Audit now falls back to plain HTTP when HTTPS does not respond, so HTTP-only or misconfigured sites can still be analyzed (they score 0 on the HTTPS category rather than failing outright).<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: public audit shortcode, REST API, non-intrusive scoring across six categories, indicative quote estimate, lead capture, admin dashboard\/list\/detail, settings, logs, CSV export, rate limiting, SSRF protection, retention cleanup and clean uninstall.<\/li>\n<\/ul>","raw_excerpt":"Public form where visitors submit a website URL and get a 0-100 health score, recommendations and a price estimate. Submissions are saved as leads.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/383882","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=383882"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/domclic"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=383882"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=383882"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=383882"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=383882"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=383882"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=383882"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}