How to Document Website Changes with Before and After Screenshots
Capture matching before and after screenshots, label them with useful context, and review visual changes with a repeatable workflow.
To document a website change clearly, capture the same page in the same state before and after the edit, using the same browser and viewport. Label each image with the route, viewport, date or commit, and a short change summary; then attach both originals to the pull request, issue, or release note. For repeatable checks, use Playwright screenshot assertions and review every proposed baseline change before accepting it.
1. Define what the screenshots need to prove
Start with the user-visible change you want a reviewer to understand. Write down the page or route, the interaction state, and the expected result. For example: “The save action now displays a confirmation” is more useful than “Updated settings page.”
- Record whether the page requires a signed-in user, seeded data, a particular account role, or a specific feature flag.
- Identify the relevant state: initial load, open menu, validation error, successful submission, or another interaction.
- Choose the viewport and browser. Match them for both captures.
- Decide where the evidence belongs: pull request, issue, release note, or change record.
A screenshot documents what was rendered under those conditions. It does not, by itself, establish why the change happened or whether the behavior is correct; add a concise explanation.
2. Capture and label the before image
Before changing the website, open the target route in the state you want to document. Use the browser’s screenshot facility or an automated capture. Save the original image and record enough context to reproduce it.
A practical filename pattern is settings-before-abc123-1440x900.png, where abc123 is a commit identifier. Keep the label readable if the image is attached directly to a ticket instead of saved as a file.
- Page: route or a clear page name.
- Version: date, commit, build, or release identifier.
- Viewport: width and height; include device or scale details when relevant.
- State: the interaction and important test data, without exposing secrets or personal information.
For example: Settings / notifications · before · commit abc123 · 1440×900 · confirmation state not present.
3. Make the change and capture the after image
Make the website change, then reproduce the same route and state. Match the before capture’s browser, viewport, data, and interaction state. Save the after image separately and label it with the new commit or build.
Small differences in capture conditions can look like product changes. A different viewport can reflow text; different data can alter table rows; an unfinished font or image can shift layout. If the page has a hover effect, move the pointer to a neutral area before capture unless the hover state is what you intend to show.
4. Present the evidence for quick review
Place the before and after images side by side when the page remains legible at that size. Put the label next to each image rather than relying only on filenames. Include a short note that names the changed region and intended behavior.
- Show the original before and after images at the same display scale.
- Describe the intended change in one or two sentences.
- Point out the relevant region if the change is subtle.
- If useful, add a diff overlay as a third view. Keep the original images available so reviewers can distinguish a real rendering from a visualization of differences.
Review the whole page, not just the highlighted area. Look for unintended shifts, missing assets, clipped content, font changes, and responsive regressions. A pixel difference shows that two images differ; a reviewer must decide whether the difference is expected.
5. Choose a capture workflow
| Approach | Setup and repeatability | Review context | Good fit |
|---|---|---|---|
| Manual browser captures | Fast to start; consistency depends on matching conditions each time. | Attach images to a ticket, pull request, or release note. | One-off changes, design review, and sign-off. |
| Playwright Test | Requires tests and maintained reference images; captures and comparisons can be repeated. | Reference image changes can be reviewed with the code. | Teams already using Playwright that want visual checks in their development workflow. |
| Percy with Playwright | Adds a hosted workflow to Playwright capture. | The documented integration provides a shared visual snapshot review workflow. | Teams that want hosted review and choose to use a vendor service. |
You do not need a visual testing service to document a change. Playwright can compare screenshots with a saved reference. Percy is an optional hosted review path; see its Playwright integration for the documented integration. The research for this article does not establish current Percy pricing or affiliate terms.
6. Automate comparisons with Playwright Test
Playwright Test’s toHaveScreenshot() assertion compares a page or element with a reference image. The first run can create a reference; subsequent runs compare against it. Screenshot assertions wait until two consecutive screenshots match before comparison. The reference directory should be committed and its changes reviewed. See the official Visual comparisons documentation and PageAssertions API for current syntax and options.
Runnable example
In a project with Playwright Test installed, create tests/settings.visual.spec.ts:
import { test, expect } from '@playwright/test';
test('settings page matches its reviewed visual reference', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto('http://127.0.0.1:3000/settings');
// Replace this with your application's deterministic sign-in and test-data setup.
// Navigate to the exact interaction state that the reference should document.
await expect(page).toHaveScreenshot('settings.png', {
fullPage: true,
animations: 'disabled',
caret: 'hide',
threshold: 0.2,
maxDiffPixels: 100
});
});
Run the project’s local web server separately, then create or update references with:
npx playwright test tests/settings.visual.spec.ts --update-snapshots
Run the test without that flag to compare against the saved reference:
npx playwright test tests/settings.visual.spec.ts
Review the generated or changed snapshot before committing it. Use --update-snapshots only when you intend to change the reference after inspecting the visual result. Playwright recommends keeping snapshot images in version control and reviewing their changes.
Options and when to tune them
fullPage: truecaptures the full page rather than only the viewport. Use it when below-the-fold content matters; use a viewport or element screenshot when the change is localized.animations: 'disabled'disables finite animations and fast-forwards finite transitions during capture. This helps reduce transient differences; ensure the resulting state still represents what you intend to document.caret: 'hide'hides a blinking text caret that can cause inconsistent pixels.thresholdsets per-pixel color-difference tolerance, andmaxDiffPixelslimits the number of differing pixels accepted. These tune comparison sensitivity; they do not prove that a difference is harmless. Keep tolerances tight enough to catch changes that matter and inspect the diff.
Option availability and exact behavior can depend on the Playwright version. Check the linked API reference when adapting the example. Add explicit setup for authentication, seeded data, feature flags, locale, and other state that affects the rendering. If an assertion targets only a specific component, use the locator screenshot assertion documented by Playwright and give the image a stable, descriptive name.
7. Make captures repeatable and trustworthy
- Use stable data: seed known records and avoid timestamps, random values, rotating banners, or live data where possible.
- Wait for the right state: wait for a meaningful locator or application-ready condition instead of relying on an arbitrary delay. If content loads asynchronously, verify it is present before capture.
- Match the environment: keep browser, viewport, device scale, fonts, locale, timezone, and color scheme consistent when they affect the page.
- Control motion and pointer state: avoid transient animation frames and hover effects unless those are the subject of the evidence.
- Protect private data: use test accounts and redact secrets or personal information before attaching screenshots to a broadly visible record.
- Review baseline updates: investigate unexpected movement or missing content. Update a reference only after deciding the change is intended.
- Keep the evidence together: retain the before and after captures, labels, and short explanation with the related change record.
8. Or skip the browser setup
If you need a clean screenshot of a public page without installing or maintaining browser capture code, ScreenshotNeo returns an image or PDF from one API request. The request below captures a page as WebP; see the ScreenshotNeo API documentation for parameters and output options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
f.write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
ScreenshotNeo accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. All features are on every plan.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
9. Performance, reliability, and cost
Manual capture has little setup overhead, but repeating it takes human time and makes consistency dependent on the capture checklist. Automated baseline checks add test maintenance and image review to the workflow. Keep the test focused on meaningful pages and states, use deterministic fixtures, and avoid regenerating every reference without review. This reduces noisy changes and makes failures easier to investigate.
A visual assertion is evidence about a rendered state in a particular environment. Browser, operating system, font rendering, external assets, and unstable page data can all affect pixels. Use a consistent CI environment where possible, keep reference updates reviewable, and treat a passing tolerance as a comparison rule rather than a guarantee of design correctness. No effectiveness benchmark is provided in the cited technical documentation.
Manual captures and Playwright are options without a hosted review service. Percy adds hosted infrastructure, but current pricing is not established by the sources used here. ScreenshotNeo’s stated plans range from free for 1,000 monthly screenshots to paid plans starting at $5 for 3,000; yearly billing gives two months free. See its documentation for request options and response headers before incorporating it into an automated record workflow.
10. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The after image differs across repeated runs. | Unstable data, animation, hover state, asynchronous content, or changing external resources. | Use fixed test data, disable motion where appropriate, move the pointer to a neutral area, and wait for a meaningful page condition before capture. |
| Text wraps differently from the reference. | Viewport, browser, font loading, locale, or device scale differs. | Match capture settings and ensure the intended fonts and content have loaded. |
| The screenshot is blank or missing a section. | The page or element was captured before it reached the required state, or the target route/data is wrong. | Check navigation and test setup, wait for a visible locator, and verify the route and account state. |
| A visual test fails after an intended design change. | The saved reference still represents the old design. | Inspect the actual and expected images, confirm the change is intended, then update the snapshot and review the changed image in version control. |
| A visual test passes despite a difference that matters. | Comparison tolerances may be too permissive, or the tested screenshot does not include the changed area. | Lower tolerance or the maximum differing-pixel allowance, target the relevant page or element, and inspect the captured image. |
| A screenshot contains private or unexpected content. | The capture used a real account, live data, or the wrong interaction state. | Switch to controlled test data and review or redact the image before sharing it. |
| A hosted snapshot review step is unavailable. | The workflow depends on a vendor service or integration configuration. | Check the vendor’s current integration documentation and credentials, or use Playwright’s local reference workflow. |
11. FAQ
Should I attach a diff instead of the two screenshots?
Attach the original before and after images. A diff can help locate changes, but it does not show each rendered page as clearly on its own.
Should I keep screenshots in the repository?
For automated Playwright references, the official guidance recommends committing the snapshot directory and reviewing changes. For one-off records, retain images where your team can find them with the related issue or change.
Can screenshots prove a change works for every user?
No. They document a particular rendered state and set of capture conditions. Pair them with functional checks and additional viewport or state coverage when those matter.
Do I need Percy to use Playwright screenshots?
No. Playwright supports reference images and screenshot assertions directly. Percy is an optional hosted review workflow.


