Docs

Page sources

How visualdiff finds pages in Craft, WordPress, Statamic, Filament, Laravel and any site with a sitemap, plus signed-in pages.

visualdiff asks the site which pages exist, then picks a sample: every page of the groups you mark all, and a few from each other group (section, post type, collection, route group). A full sweep takes everything. Several sources can run together; their pages are merged.

Every source accepts:

  • perGroup: how many pages to take from each group (3, or per site: { "default": 3, "*": 1 }).
  • alwaysAll: groups where every page is taken (Craft page-builder sections, for example).
  • exclude: groups to skip.
  • sites: which sites to read.
  • "php": "8.2": the PHP version to start the app with (default: the one Herd uses for the folder).

Craft CMS#

Reads the Craft database directly, using the DB_* (or CRAFT_DB_*) settings in .env. It works out which tables and columns exist, so the same source runs on Craft 3.0 through 5.x, on MySQL 5.7, MySQL 8 and MariaDB. Groups are section handles, product-<type> for Commerce and category-<group>. Drafts, revisions and deleted entries are skipped. Craft 2 isn't supported.

WordPress#

Loads WordPress (classic layouts, Bedrock's web/wp, wp/, public/) and asks it for permalinks, so hierarchical pages, custom post types and custom permalink structures all come out right. Groups are post type names, <type>-archive and taxonomy-<taxonomy>.

  • Multisite: every public site in the network. The main site is default; the others are named by their path or subdomain.
  • REST: with "rest": true (the default) it also compares wp-json and the first few items of every REST-enabled post type as data, which shows plugin and core changes to the API.
  • Branches: WordPress stores its own URL in the database, so in a branch's copy visualdiff points home and siteurl at the branch. With WP-CLI you can add "migrate": ["wp core update-db"].

Statamic#

Boots the app and reads published entries (skipping redirects) and taxonomy terms, per site. Statamic 3 to 6. Groups are collection handles and taxonomy-<handle>.

Filament#

Every panel's pages and resources: the index, create, and edit or view pages (with the first record). Filament 2 to 5. These pages need a signed-in session; see below.

Laravel#

Walks the router and takes GET routes, filling in {parameters} from the first record for model-bound ones, or from values you give it:

"laravel": { "params": { "slug": "hello-world" } }

It skips framework and tooling routes (Telescope, Horizon, Debugbar, Livewire, Sanctum and so on), routes on other domains, and routes behind auth, verified or can: unless you set "auth": true. Its summary says which parameters it couldn't fill. Routes under api/ are compared as data.

Sitemap and static lists#

For any site:

"pages": {
  "sitemap": { "site": "default", "url": "sitemap.xml", "perGroup": 3 },
  "static": ["/", "/contact", "french:/", "does-not-exist-404"]
}

Sitemap groups are the first path segment. Including a URL that should 404 checks your error page too.

Signed-in pages#

Comparisons run signed out by default: a fresh browser on both sides, like a private window, so nothing you're signed in to in your own browser affects them. Choose Signed in under Session in New comparison (or --signed-in) to use each side's saved sign-in. It's always both sides or neither: if one side has no saved sign-in, the comparison stops and asks you to sign in first, so one side is never captured signed in and the other signed out. Projects whose pages need a login, like Filament panels, default to signed in.

Sign in to an environment with Sign in… next to it in New comparison, or once per environment from a terminal:

vdiff login before      # a browser window opens: sign in, and visualdiff saves the session
vdiff login after

Sessions are saved in ~/.vdiff/<project>/auth/ and used for every capture. For environments that come and go, like branches, visualdiff can sign in by itself with a local test account taken from environment variables:

"login": {
  "url": "admin/login",
  "fill": { "input[type=email]": "$VDIFF_LOGIN_EMAIL", "input[type=password]": "$VDIFF_LOGIN_PASSWORD" },
  "submit": "button[type=submit]"
}

Use a local test account. Credentials never go in the config file.

Tell me when it's out

visualdiff for Mac is nearly ready. Leave your email and we'll send you one message when you can download it.

Just the launch email. No newsletter, and we never share your address.