Skip to content

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.

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. 0 means no cap.
  • The wpdiff_scan_urls filter 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-' ) );
} );

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.

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.

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.

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:

  1. CSS animations are frozen automatically during every capture.
  2. 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.
  3. 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.

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.

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.

The browser never talks to the scanner and never sees the API token:

  1. The React app calls the site’s own REST routes under wpdiff/v1/*, authenticated with a WordPress nonce and a manage_options capability check.
  2. 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.

SettingPurpose
Backend URLScanner base URL, without a trailing slash
API tokenBearer token, must match the scanner’s WPDIFF_TOKEN
Max pages per scanCap on the URL inventory, 0 for no cap
Detected on this sitePer-library checkboxes controlling which detected motion libraries are paused
Ignore selectorsElements hidden during capture, one CSS selector per line
Diff pipeline stagesAdds pipeline inspection to the diff view, see Developer mode
Client debug infoShows the scan inventory breakdown and capture options sent with each scan