Skip to main content
Technical Tutorials

How to review an AI-built website change before publishing

A practical way to verify a versioned website change across code, browser behavior, accessibility, metadata, links, and performance before approval.

Sean McLellan profile photo

Sean McLellan

Lead Architect & Founder

12 min read
Retained screenshots from the same article route show the existing 1400 by 820 desktop artwork selected at a tested 1440 by 900 viewport and the dedicated 900 by 1200 mobile artwork selected at a tested 390 by 844 viewport.
Observed captureThe browser selected the retained desktop art at 1440 px and the dedicated mobile art at 390 px.

An AI-built page can load and still be unsafe to publish. A narrow screen can break the layout, a keyboard path can trap a user, metadata can point to the wrong URL, or a working build can sit beside unresolved type errors.

A useful review connects one fixed code revision to observable evidence and a release decision. This tutorial shows how to do that with code checks, browser evidence, accessibility checks, metadata, links, and repeated performance runs. It also shows how to record a hold when the evidence remains incomplete.

Fix the candidate before you collect evidence

Start with an exact revision, route, and environment. Record the commit identifier, parent commit, package versions, browser version, Node.js version, and the URL that you will test. If the code changes during the review, the prior evidence describes an older candidate.

Define the release claim at the same time. A focused claim can be “the new mobile artwork loads at the intended breakpoint, the desktop artwork remains in place, the print packet stays together, and existing metadata and links remain valid.” This claim is specific enough to test. It does not promise that the whole website is correct.

A basic command record can start like this:

git rev-parse HEAD
node --version
pnpm --version

Save the command output with the review date. If the runtime does not match the repository declaration, record the mismatch before you run other checks. A green result from a different runtime can still help with diagnosis, but it is weak release evidence.

State what changed and what remained intact

Use the source diff to make two short lists. The first list contains the intended changes. The second list contains behavior that the release should retain.

For a responsive image change, the changed list can include a new mobile asset, the selection breakpoint, and print rules. The retained list can include the desktop asset, alt text, caption, canonical URL, Open Graph fields, article text, CTA, and internal destinations. This separation prevents the review from checking only the new code while missing a regression in existing behavior.

The source diff establishes which files and lines changed. It does not prove that a browser selected the right asset or that the retained metadata reached the rendered HTML. Use rendered evidence for those claims.

Use each evidence type for a specific job

Different evidence answers different parts of the release decision. Combining the types is useful, but they are not interchangeable.

Table comparing source diff, test assertions, browser trace, screenshot, audit output, and rendered metadata with what each can show and what it cannot show by itself.
Constructed diagramEach evidence type answers a bounded release question. No single artifact proves the whole change.

Scroll sideways to see all 3 columns.

EvidenceWhat it can showWhat it cannot show by itself
Source diffThe files, code paths, and declared scope of the revisionThe final browser state
Test assertionsThe behavior encoded in component, service, or route testsVisual quality or behavior that no test covers
Browser traceThe action sequence, DOM snapshots, sources, requests, console output, and screenshots during a runComplete human review or all assistive-technology behavior
ScreenshotThe visible state at one viewport and one momentDOM semantics, the complete keyboard order, or other viewport sizes
Audit outputA tool result under a recorded version and configurationA general guarantee for production users
Rendered metadataThe title, description, canonical URL, social fields, and structured data present in HTMLHow every external platform will index or display the page

Playwright Trace Viewer can show actions, DOM snapshots, source, network activity, console messages, errors, and attachments from a test run. A trace is valuable when a reviewer needs to reconstruct the browser path. Keep the trace with the exact revision and the test result that produced it.

Screenshots and trace snapshots have different uses. A screenshot is easy for a person to inspect. A trace snapshot can show the DOM around an action and help diagnose a failure. Retain both when the visual state and the action sequence matter.

Run repository checks before browser review

Run the repository’s defined checks before opening the page. This order catches syntax, formatting, type, test, and build failures before browser evidence becomes the focus.

A common sequence is:

pnpm run format:check
pnpm run lint
pnpm exec tsc --noEmit
pnpm exec vitest run <focused test files>
pnpm run test
pnpm run build

Record the command, exit code, warnings, and tool version. Keep focused tests and the full suite as separate entries. Focused tests show that the changed path has direct coverage. The full suite checks for effects outside that path.

Do the same for type and build results. A framework build can pass while a separate TypeScript command reports errors in test files or scripts. Preserve both results. Do not replace the failed result with the build summary.

Exercise the rendered paths on desktop and mobile

Use a production build when practical. Load the changed route at a desktop width and a small mobile width. Record the HTTP status, final URL, viewport, selected assets, document width, console output, failed requests, and responses with an error status.

Check the behavior that the change claims to protect. For a responsive image, inspect the browser’s currentSrc value instead of assuming that the <source> element worked. For a responsive packet, compare element positions to confirm a two-column desktop layout and a one-column mobile layout. Check for horizontal overflow and retain targeted screenshots.

Retained screenshots from the same article route show the existing 1400 by 820 desktop artwork selected at a tested 1440 by 900 viewport and the dedicated 900 by 1200 mobile artwork selected at a tested 390 by 844 viewport.
Observed captureThe browser selected the retained desktop art at 1440 px and the dedicated mobile art at 390 px.

These screenshots came from a local production build and show one moment at each tested viewport. They do not establish behavior at every width, browser, or physical device.

Exercise real interaction paths with the keyboard. The minimum set for an article page can include the skip link, navigation, search, heading links, and the final CTA. Confirm that focus moves to a useful target, controls expose clear names and states, and Escape closes temporary interfaces where expected.

Use the trace to preserve the action sequence. Use targeted screenshots for visual review. A trace can help explain a failed path, while a screenshot can show whether labels, borders, and text were clipped at the tested width.

If the change affects print, generate a PDF with print media enabled. Inspect page boundaries and extract the relevant page text. A screen screenshot with print styles can show the compact layout, but the PDF is better evidence for pagination.

Treat an accessibility scan as partial evidence

Run an automated accessibility scan on the changed page or relevant region at both viewports. Playwright’s accessibility-testing guidance shows how to use axe-core in a test and how to scan a specific page region.

Automated tools find only some accessibility problems. Playwright’s documentation says that manual assessment is still necessary. Record violations, passed rules, and incomplete checks. An incomplete color-contrast check is a manual review item, even when the violation count is zero.

Add keyboard review and, before a significant release, a screen-reader check. For changes that affect a mobile layout, use at least one real mobile device when possible. The automated result and the manual result should remain separate in the record.

Next.js supports static metadata, generated metadata, and file-based metadata. Its metadata and Open Graph documentation also explains static and generated social images. The release check should inspect the output that the candidate actually renders.

Record the page title, meta description, canonical URL, robots value, Open Graph title, Open Graph description, Open Graph URL, Open Graph image, Twitter card, and structured data types. Compare each value with the intended retained state. A source-level metadata function is useful context, but the final HTML is the stronger check for the candidate.

Collect unique internal links from the rendered page and request each destination against the same production build. Record the destination, final status, and redirects. Review the CTA destination separately because a successful response does not prove that the CTA text and destination match the reader’s next task.

Repeat Lighthouse runs under matching conditions

Lighthouse performance data is lab data. Chrome’s performance scoring documentation explains that the score uses weighted metrics and that conditions such as the device, network, and page resources can cause results to vary.

Record the Lighthouse version, browser version, URL, form factor, screen emulation, throttling method, network values, CPU slowdown, and host warning. Run the same candidate more than once. A score without its conditions is weak evidence.

Compare the underlying metrics as well as the score. In Lighthouse 10, Total Blocking Time has a 30% weight, Largest Contentful Paint and Cumulative Layout Shift each have a 25% weight, and First Contentful Paint and Speed Index each have a 10% weight. A change in one weighted metric can move the score even when another metric remains stable.

Repeated candidate runs can show variability under the recorded lab setup. They cannot establish an improvement over the prior revision. To make a performance-change claim, test the parent and candidate under the same stable conditions and repeat both sets.

Two Lighthouse 13.4.1 mobile runs of the same candidate scored 90 and 97, with Total Blocking Time of 330 and 70 milliseconds. Both used 412 by 823 screen emulation, simulated throttling, 150 millisecond network round-trip time, 1,638.4 kilobits per second throughput, and four-times CPU slowdown. Run 1 carried a slower-host-CPU warning, and the benchmark index changed from 967 to 1,697. The values show variability, not improvement, because no parent baseline exists.
Constructed diagramThe same candidate moved seven points across two matching mobile runs. The host warning and benchmark change limit the conclusion. This shows variability—not improvement; no parent Lighthouse baseline exists.

This is a candidate-only repeat. The connected points show run sequence, not a before-and-after performance claim. Do not label either point “before,” “after,” “baseline,” or “improved.”

A versioned sample shows why the record matters

For this tutorial, we reviewed BaristaLabs commit 0932aab09bd10d44a79df817fafa8ca52a644810, with parent d34dc87042dfa9bea61702fc02f066f72c8348c2. The change added a dedicated mobile image and adjusted mobile and print layouts for the article “The AI workflow handoff note before approval.” The review used the exact candidate in a detached worktree and a local production build.

The diff showed seven changed files, 237 insertions, and nine deletions. It added a 900 × 1200 mobile SVG, selected it at a maximum width of 639 px, added responsive and print styles, changed receipt-packet class names, and expanded tests. The desktop SVG, article markdown, alt text, caption, canonical URL, and CTA destinations were outside the intended change.

The repository checks produced a mixed result

The original formatter command exited successfully with warnings in pre-existing audit files. Lint passed. The three focused test files passed, the full suite passed, and the production build passed its compile, TypeScript, static generation, content validation, and post-build checks.

The follow-up recreated the exact parent and candidate in separate detached worktrees and ran both with Node.js 22.23.2 and pnpm 10.28.1. Format, lint, focused tests, the full suite, and production build exited 0 on both revisions. The parent reported 203 passing test files and 1,538 tests; the candidate reported 203 passing test files and 1,540 tests. Standalone tsc --noEmit --pretty false --incremental false still exited 2 with 39 diagnostics on each revision. Matching by file, diagnostic code, and complete message classified all 39 candidate diagnostics as parent/pre-existing, with no parent-only or candidate-only diagnostic.

The rendered checks supported the narrow layout claim

The desktop and mobile routes returned HTTP 200. The desktop browser selected the existing 1400 × 820 image. The mobile browser selected the new 900 × 1200 image. The retained alt text and caption matched, the mobile document had no horizontal overflow, and the receipt panels changed from a desktop row to a mobile column.

The skip link moved focus to the main content. Search opened from the keyboard, focused its input, and closed with Escape. The mobile navigation opened from the keyboard, showed its first link, and closed with Escape. The run recorded no console errors, console warnings, failed requests, or error responses.

The print packet used break-before: page and break-inside: avoid. A generated 11-page Letter PDF placed the complete packet on page 4. That page contained both comparison panels, all six fields, the decision line, and the caption.

Accessibility and performance evidence remained limited

The original axe-core run reported zero violations and 24 passed rules at both viewports. It also returned one incomplete color-contrast rule with serious impact because axe could not resolve text over gradients.

The follow-up inspected all 10 desktop and 12 mobile incomplete nodes. For each node it retained the foreground color, hid only the glyphs, sampled every background pixel across the element, and compared the lowest computed ratio with the applicable WCAG AA threshold. Every node passed. The lowest result was the mobile “Read the approval queue guide” link: #e8d5b7 over worst-case #5a3820, 7.24:1 against a 4.5:1 requirement.

Two sequential Lighthouse 13.4.1 mobile runs used the same URL, 412 × 823 screen emulation, simulated 150 ms network round-trip time, 1,638.4 Kbps throughput, and 4× CPU slowdown. The performance scores were 90 and 97. First Contentful Paint stayed at 1.4 seconds, Largest Contentful Paint moved from 2.3 to 2.5 seconds, Total Blocking Time moved from 330 to 70 milliseconds, and Cumulative Layout Shift stayed at zero.

The first run warned that the host CPU appeared slower than Lighthouse expected. The recorded benchmark index also changed from 967 to 1,697 between runs. The seven-point score range is useful evidence of run variability. It is not evidence that the candidate improved performance because the parent revision was not tested.

Write the release decision in the same record

A concise review record should contain these fields:

Candidate revision:
Parent revision:
Route and claim:
Environment and tool versions:
Changed behavior:
Retained behavior:
Commands and exit codes:
Rendered desktop and mobile results:
Keyboard results:
Accessibility violations, passes, and incomplete checks:
Metadata and link results:
Performance settings and repeated metrics:
Trace, screenshot, report, and PDF locations:
Known gaps:
Decision: approve, hold, or revise
Decision owner:
Next required check:

For the versioned sample, the 2026-08-03 decision was correctly hold. The 2026-08-10 follow-up resolved each named gate: Node.js 22.x checks were repeated, all 39 diagnostics were demonstrated to be parent/pre-existing, all axe-incomplete contrast nodes passed manual review, and the desktop heading permalink showed a visible two-layer focus ring after 16 Tab presses. The editorial packet is therefore ready for publication with the limits below.

The record supports claims about the exact tested revision and conditions. It does not prove complete accessibility, production reliability, search ranking, conversion, or business impact. Those claims require different evidence.

Limits that remain after the follow-up

No screen-reader or physical mobile-device test ran. The rendered review used a local production build; it did not test CDN behavior, deployed headers, analytics delivery, or third-party production services. Search engines and social platforms were not asked to recrawl the page. The candidate-only Lighthouse repeats do not establish a performance improvement. The review contains no customer outcome, conversion result, or production-incident evidence.

Use the record as part of the approval workflow

For a deeper performance evidence example, read The Lighthouse run that earns a place in your AI workflow receipt. Use the AI agent receipt template to keep the revision, action, evidence, and owner together.

The AI workflow controls page helps teams define approval and rollback boundaries. For changes that touch sensitive data, credentials, forms, or third-party services, use the AI workflow security review worksheet before release.

BaristaLabs can also help with the implementation and review path through AI-assisted website development. Bring the candidate revision, current evidence, and open decision to the first review so the work starts from facts.

Implementation review

Review one AI-built website change from revision to release decision

BaristaLabs helps teams verify code, rendered behavior, accessibility evidence, metadata, links, and performance limits before a website change is published.

Bring the exact revision, preview or build, known failures, and the claim the change is expected to support.

Turn this idea into a pilot

Which workflow should go first?

Use the readiness check to compare impact, effort, risk, owner, and next step before booking a call.

  • 3-5 minutes
  • Deterministic score
  • No sensitive data
Check workflow readiness

Practical AI Workflow Notes

Want more practical AI operations ideas?

Get short notes on applying AI inside real small-business workflows — from document handling and customer follow-up to internal reporting, compliance, and automation guardrails.

A useful next step if you’re still exploring and not ready to book a 20-minute AI assessment.

Occasional emails. Practical workflow guidance only. Unsubscribe anytime.