The WordPress plugin
The plugin is the client side of WP Diff. It owns page discovery and orchestration, and renders the timeline and diff viewer in wp-admin. The scanner only ever captures and compares what the plugin sends it.
Page discovery
Section titled “Page discovery”When you press Run scan now, the plugin builds the page inventory from your WordPress content:
- the home page
- every published post, page, and public custom post type entry
- archive pages for post types that have them
The list is sent to the scanner with the scan request. Because discovery uses WordPress itself rather than a sitemap, it works regardless of your permalink or SEO plugin setup.
Two controls shape the list:
- Max pages per scan in the settings caps the list for large sites.
0means no cap. - The
wpdiff_scan_urlsfilter lets a developer add or remove URLs:
add_filter( 'wpdiff_scan_urls', function ( array $urls ): array { $urls[] = home_url( '/pricing/?variant=b' ); return array_filter( $urls, fn( $url ) => ! str_contains( $url, '/private-' ) );} );The timeline
Section titled “The timeline”Every snapshot appears as a card with its date and page count. The plugin defaults to comparing the two most recent snapshots. Use the Baseline and Compare buttons on any two cards to compare across a longer window. A blue outline marks the baseline, green marks the compare target.
Results are grouped into accordions: changed pages open at the top, with new, removed, and unchanged pages collapsed below, each with a count. View diff opens the baseline and current screenshots side by side with changed regions outlined.
Tickets
Section titled “Tickets”Every piece of work has a ticket. Tickets come from three places:
- Scans: when a scan finds changes against the previous snapshot, each changed page gets an open ticket automatically.
- Reviews: marking a region as needing a fix creates a ticket for that element, and marking it fine again resolves it.
- Manual: on the live site, press New ticket in the review sidebar and click any element. The ticket stores a CSS selector for the element, so its pin stays attached across devices.
WP Diff → Tickets is the board: open, in progress, and resolved columns with per-ticket assignee, status buttons, and an Open on site link that lands on the live page with the review layer active. Assigning a ticket emails that person a direct link.
Reviewing changes
Section titled “Reviewing changes”Detection is half the job. The other half is deciding whether each change was intended. Every changed region can be marked:
- Looks fine: the change was expected, for example new blog copy.
- Needs fixing: something broke. An optional note travels with it.
Press Review changes on a changed page and each region appears as a cropped baseline and current pair, so you review the element rather than scrolling a full page screenshot. The full screenshots stay available underneath. Rows show a summary chip: green when everything on the page is reviewed, red with a count when something needs fixing.
Every changed page also has a Review on site button. It opens the live page framed in blue with a left sidebar, the way Pastel and Atarim work: the sidebar lists this page’s changed regions and every open ticket across the site, and clicking a ticket for another page navigates there with the review layer still active. Numbered pins sit on the changed elements with dashed outlines around the regions. Clicking a pin (or moving with j and k) opens a card with the baseline and current crops, Looks fine and Needs fixing controls, a note field, and an assignee dropdown. Pin colours track status: amber unreviewed, green fine, red needs fixing, violet for manual tickets.
Marks are stored in WordPress per snapshot pair, so a half-finished review is still there tomorrow, and the dashboard and on-site views share the same state. When anything is marked as needing a fix, a Copy report button appears next to the summary. It puts a plain text report on the clipboard listing each failing URL, the region coordinates, and your notes, ready to paste into an email or a ticket for whoever fixes it.
Carousels and animation
Section titled “Carousels and animation”Anything that moves between two captures creates false positives: a carousel on its third slide today and its first slide next week has “changed” without changing. WP Diff handles this in three layers:
- CSS animations are frozen automatically during every capture.
- Known motion libraries are detected and paused. The plugin scans your active theme and plugins for common libraries (Swiper, Slick, Owl Carousel, Splide, Flickity, AOS, WOW.js, and popular slider plugins). Detections appear in the settings under Motion and animation, each with a checkbox so you can turn pausing off per library, and on the WP Diff dashboard. During each scan the paused widgets are stopped and reset to their first slide before screenshotting. HTML5 videos are always paused and rewound.
- Ignore selectors cover everything else. Add CSS selectors (one per line) in the settings and matching elements are hidden during capture while keeping their layout space, so tickers, ad slots, or unrecognised widgets cannot flag.
Libraries the plugin recognises but cannot pause automatically (for example Slider Revolution) are listed with a suggestion to add an ignore selector.
Viewports
Section titled “Viewports”Scans capture every page at a 1440px desktop viewport. Tick Mobile viewport in the settings to also capture each page at 375px. Each viewport is diffed against its own baseline, and mobile results carry a badge in the diff view. The first scan after turning it on shows the mobile captures as new pages, since there is no mobile baseline yet.
Notifications
Section titled “Notifications”WP Diff can alert you when a scan finds changes compared with the previous snapshot. Two channels are supported, configured under WP Diff → Settings → Notifications:
- Email: sent with
wp_mail, so it uses whatever mail setup the site already has. No SMTP configuration in the plugin. - ntfy: a full topic URL on ntfy.sh or a self-hosted ntfy server.
The alert lists the changed, new, and removed URLs with a link back to the diff view. Delivery uses WP-Cron to poll the scanner until the run finishes, so on very low traffic sites the alert can lag until the next visit triggers cron. A real cron runner or Action Scheduler integration is the upgrade path for guaranteed timing.
Security model
Section titled “Security model”The browser never talks to the scanner and never sees the API token:
- The React app calls the site’s own REST routes under
wpdiff/v1/*, authenticated with a WordPress nonce and amanage_optionscapability check. - The plugin proxies those calls server side to the scanner, attaching the bearer token stored in the WordPress options table.
This also means the scanner does not need to be reachable from your visitors’ browsers, only from the WordPress server.
Settings reference
Section titled “Settings reference”| Setting | Purpose |
|---|---|
| Backend URL | Scanner base URL, without a trailing slash |
| API token | Bearer token, must match the scanner’s WPDIFF_TOKEN |
| Max pages per scan | Cap on the URL inventory, 0 for no cap |
| Detected on this site | Per-library checkboxes controlling which detected motion libraries are paused |
| Ignore selectors | Elements hidden during capture, one CSS selector per line |
| Diff pipeline stages | Adds pipeline inspection to the diff view, see Developer mode |
| Client debug info | Shows the scan inventory breakdown and capture options sent with each scan |