# VitalLens

> Core Web Vitals monitoring for WordPress that keeps its own history, tells real-visitor data from lab tests, and names the element and cause behind a failing metric.

- **Type:** Plugin (WordPress plugins)
- **Version:** 1.0.0
- **Availability:** Submitted to WordPress.org on 3 November 2026, awaiting review
- **Requires:** WordPress 6.2+, PHP 7.4+, A free Google PageSpeed Insights API key
- **Tested with:** WordPress 7.1
- **Licence:** GPL-2.0-or-later
- **Documentation:** https://developers.zactonz.com/wordpress/plugins/vitallens/

## Overview

VitalLens checks the pages you pick against Google PageSpeed Insights on a schedule, stores every result in your own database, and shows you what changed over time. It uses your own free Google API key and sends nothing anywhere else. The product site is [vitallens.zactonz.com](https://vitallens.zactonz.com/); this page is the reference.

![The VitalLens dashboard in WordPress, stating that 2 of 6 tracked pages are failing for real visitors, with the pages that need attention listed](https://developers.zactonz.com/assets/images/wordpress/vitallens-1.webp)

*The dashboard states the situation in a sentence, including when the situation is "nothing has run".*

### Real-user data where Google has it, a lab test where it does not

Google publishes real-user measurements, the Chrome UX Report, only for URLs with enough traffic, which most individual pages never have. Plenty of tools quietly show a lab score and let you believe visitors measured it. VitalLens labels every number as *real visitors*, *origin only* or *lab only*, because a green page nobody has ever measured is worse than no answer.

### The cause, not just the symptom

"CLS 0.16" names the metric. "A 0.162 shift on a layout container, caused by an image with no explicit size and two web fonts" is something you can go and fix. For each failing metric VitalLens names the element involved, the cause Lighthouse attributed it to, and how much of the metric it accounts for. It reads seventeen of Lighthouse's diagnostic audits to do so, including the insight audits that Lighthouse 13 moved most of its findings into.

![One page's VitalLens report, showing a CLS failure in the lab test, the explanation that Google has no real-user data for the page, the lab metrics, and a 90-day history chart](https://developers.zactonz.com/assets/images/wordpress/vitallens-3.webp)

*A page's report: which data Google had, the lab test, and the history built from your own stored checks with the failing threshold drawn on the chart.*

### What you get

- A **two-dot column** on the Posts and Pages lists: a filled disc for real visitors, a ring for the lab test. Hover either for the latest LCP, INP and CLS.
- A **dashboard** that states the situation in a sentence, and a **dashboard widget** switched on and off from Screen Options like any other.
- **History** for every tracked page, built from your own stored checks, with the failing threshold drawn on the chart and a readout on hover or with the arrow keys.
- **Email alerts** that fire before a page crosses a threshold, not only after. See [Alerts, exports & backups](https://developers.zactonz.com/wordpress/plugins/vitallens/alerts/).
- **Check now** on any page's report, so a page you have just fixed is re-measured immediately.
- **Export**: a branded, printable report you can save as a PDF, and CSV of every tracked page or of one page's whole history.
- **Backups** written automatically to your uploads folder whenever the plugin is deactivated, with one-click restore.

![The WordPress Pages list with the VitalLens two-dot column and a hover card showing LCP, INP and CLS for one page](https://developers.zactonz.com/assets/images/wordpress/vitallens-2.webp)

*The two-dot column on the Pages list, with the hover card.*

### What it costs to run

One call to Google per page per device, per run. Thirty pages on mobile and desktop checked daily is about 1,800 calls a month, against a free allowance of 25,000 a day. The Tracked pages screen shows the figure for your own selection before you save it. Checks run in the background a few pages at a time, and nothing is added to your front end: no script, no tracking, no extra requests for visitors.

### External service

The plugin connects only to the Google PageSpeed Insights API, at `https://www.googleapis.com/pagespeedonline/v5/runPagespeed`. Each check sends the public URL of a tracked page and the API key you entered. No post content, visitor data or personal information leaves your site, and nothing is sent to Zactonz. Google's [terms of service](https://developers.google.com/terms) and [privacy policy](https://policies.google.com/privacy) apply to those requests.

### Not affiliated

VitalLens is developed by Zactonz Technologies and is not affiliated with, endorsed by or sponsored by Google. Google, PageSpeed Insights, Lighthouse and Chrome are trademarks of Google LLC.

## Installation & setup

### Install the plugin

VitalLens was submitted to the WordPress plugin directory on 3 November 2026 and is awaiting review. The directory steps below are the route once it is listed; until then, install it from the plugin zip by uploading the folder to `/wp-content/plugins/vitallens/` and activating it from the **Plugins** menu.

From the dashboard, go to **Plugins › Add New**, search for **VitalLens** and click **Install Now**, then **Activate**.

With WP-CLI:

```bash
wp plugin install vitallens --activate
```

### Get a Google API key

VitalLens talks to Google directly using your own PageSpeed Insights API key. It is free, needs no billing account, and allows 25,000 calls a day. Create one in the [Google Cloud console](https://console.cloud.google.com/) with the PageSpeed Insights API enabled, then paste it into **VitalLens › Settings**. The **Test key** button tells you immediately whether it works. The key is stored in your database, used only to call Google, and never written to a backup snapshot.

![The VitalLens settings screen: the API key field with a Test key button, the schedule, pages per run, history retention, device choice, the cost of the current selection, and the choice between WP-Cron and the host's cron](https://developers.zactonz.com/assets/images/wordpress/vitallens-4.webp)

*Settings: the key, the schedule, how many pages each run checks, and the cron command filled in for your install.*

### Choose what to track

Go to **VitalLens › Tracked pages** and tick the pages to watch. The screen shows exactly how many API calls your selection will cost per run, and follows the selection as you tick. Choose mobile, desktop or both in Settings; each device counts as its own check.

### Make sure the schedule runs

A sweep runs every 15 minutes and takes the pages that are due, so **Pages per run** in Settings sets how fast a backlog clears. WP-Cron only fires when somebody visits your site, so on a quiet site it drifts or stalls. VitalLens flags an overdue run on the dashboard rather than letting the gap pass unnoticed, and Settings gives you a real cron command with the paths already filled in for your install, which is the recommended way to run it.

The first check runs within the hour. **Run checks now** on the dashboard starts a run immediately, and **Check now** on a page's report re-measures that page alone.

### Where the results appear

- **VitalLens › Dashboard**: the situation in a sentence, counts of tracked, passing, failing and lab-only pages, and the pages that need attention.
- **Posts and Pages lists**: the two-dot column, with a hover card for the latest readings.
- **A page's report**: real-user data where Google has it, the lab test, what is causing each failing metric, and the history chart.
- **Dashboard › Home**: a Core Web Vitals widget, listed in Screen Options alongside At a Glance and Activity.

### Remove the plugin

Deactivating stops the schedule and writes a backup of every tracked page, check and setting to your uploads folder. Deleting keeps your tracked pages and every stored check, so re-installing picks up where you left off. To remove the tables as well, tick the box under **Your data** on the Settings screen before you delete. It is off by default, because deleting a plugin is often just a step in updating it.

## Alerts, exports & backups

### Alerts that earn their send

Most tools alert on a percentage change, which is close to useless for Core Web Vitals: the Chrome UX Report gives CLS on a 0.01 grid, so the smallest move a healthy page can make is a double-digit percentage. VitalLens judges a change by **how much of the remaining margin it consumed**. A metric that spends a third of its headroom gets an email while it is still passing; a metric that ticks by one grid step does not.

Four alerts, each switched on or off separately in Settings:

- A page starts failing for real visitors.
- A page is running out of headroom.
- A page starts passing again. Off by default, because good news should be opt-in.
- Checks stop running.

### Exports

Three ways to get the data out:

- **Download CSV** on the dashboard gives every tracked page with its latest reading, as raw numbers a spreadsheet treats as numbers.
- **Export history** on a page's report gives that page's whole stored history, one row per check.
- **Save as PDF** opens a printable, branded site-wide report and your browser's print dialog, where "Save as PDF" is a destination.

The last one is deliberate. A plugin that bundles a PDF engine ships megabytes of vendored code, a GD and mbstring dependency and a memory limit a cheap host will not grant, to redraw a report the browser renders perfectly already.

![The printable VitalLens site-wide report: a header with the site and generation time, the summary that 2 of 6 pages are failing, counts, and a table of every tracked page with its source, score, LCP, INP, CLS and check time](https://developers.zactonz.com/assets/images/wordpress/vitallens-5.webp)

*The site-wide report: every tracked page in one table, ready to print or save as a PDF.*

### Backups

Every time the plugin is deactivated, which is the step before every delete, a snapshot of every tracked page, check and setting is written to your uploads folder. It lives outside the plugin folder, so deleting the plugin cannot take it, and the Settings screen restores it in one click. The API key is never written to a snapshot.

### Your data stays yours

Updating never touches your data. Deactivating stops the schedule. Deleting keeps your tracked pages and every stored check, so re-installing picks up exactly where you left off. If you genuinely want the tables gone, tick the box under **Your data** on the Settings screen before deleting; it is off by default.

## FAQ

### Why do some pages say "lab only"?

Google only publishes real-user data for URLs with enough traffic. Those pages are still checked, but what comes back is one simulated load rather than what your visitors experienced. VitalLens says so rather than mixing the two.

### Checks have stopped running. Why?

WP-Cron only fires when somebody visits your site, so on a quiet site it drifts or stalls. VitalLens flags an overdue run on the dashboard instead of letting the gap pass unnoticed. Settings gives you a real cron command, with the paths already filled in for your install.

### Can I get the data out?

Yes, three ways: a CSV of every tracked page with its latest reading, a CSV of one page's whole history, and a printable report that your browser saves as a PDF. See [Alerts, exports & backups](https://developers.zactonz.com/wordpress/plugins/vitallens/alerts/).

### How much does it cost in API calls?

One call per page per device, per run. Thirty pages on mobile and desktop checked daily is about 1,800 calls a month, against a free allowance of 25,000 a day. The Tracked pages screen shows the figure for your own selection before you save it.

### Does it slow down my site?

No. Checks run in the background a few pages at a time, and nothing is added to your front end: no script, no tracking, no extra requests for visitors.

### What happens to my data if I deactivate or delete the plugin?

Nothing, either way, and updating never touches it. Deactivating stops the schedule and writes a backup to your uploads folder. Deleting keeps your tracked pages and every stored check, so re-installing picks up exactly where you left off. A tick box under **Your data** on the Settings screen removes the tables if you want them gone.

### Is my API key ever sent anywhere other than Google?

No. It is stored in your database, used only to sign requests to the PageSpeed Insights API, never written to a backup snapshot, and never sent to Zactonz.

### Which WordPress and PHP versions are supported?

WordPress 6.2 or newer and PHP 7.4 or newer. It is tested with WordPress 7.1.

## Changelog

### 1.0.0

First public release. Earlier numbered builds were development versions that were never published.

- Tracks the pages you choose against Google PageSpeed Insights on a schedule, using your own API key, and stores every result.
- Labels every reading as real visitors, origin only or lab only.
- Names the element, the cause Lighthouse attributed it to and the share of the metric it accounts for, for each failing Core Web Vital, reading seventeen diagnostic audits.
- Two-dot column on the Posts and Pages lists with a hover card; a dashboard that states the situation in a sentence; a dashboard widget.
- History per page with the failing threshold on the chart and a readout on hover or arrow keys.
- Four email alerts judged by the headroom a change consumed, not by percentage.
- Check now on a page's report; Run checks now on the dashboard.
- CSV export of every tracked page or one page's history, and a printable site-wide report.
- Automatic backups on deactivation with one-click restore; data kept on delete unless you opt out.
- A real cron command in Settings for sites where WP-Cron stalls.
