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 compareswp-jsonand 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
homeandsiteurlat 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.