reflow

2022-03-08

How to keep product images in documentation up to date

Documentation screenshots rot the moment your product changes. Treat them as build artifacts instead: one command regenerates every viewport and theme variant from the same automation that tests your product.

Documentation with relevant, contextual product images is far better than documentation without. But images are the part of documentation that rots fastest:

  1. Your product will change. Every release, each screenshot either gets manually retaken or drifts. With enough drift, documentation reads as wrong even when the words are right.
  2. Your users don’t share one visual experience. A reader on a phone in dark mode is looking at documentation illustrated with desktop light-mode screenshots. The more you theme your product, the more jarring that mismatch gets.

The root problem is that screenshots are treated as handmade artifacts. Someone opens the product, arranges the right state, crops a capture, and pastes it in — and that work is thrown away on the next release.

The fix is to treat product images as build artifacts: outputs of an automated flow that walks your product and captures them, rerun whenever the product changes. Reflow auto-heals browser interactions when your product changes, which makes it suitable for exactly this kind of long-living automation. The same flow doubles as a small end-to-end test suite — if your login page breaks, your screenshot pipeline tells you before your users do.

This walkthrough produces a single command that generates six sets of product images — one per viewport and theme combination — and a component that serves the right one to each reader.

ViewportDark modeLight mode
DesktopScenario 1Scenario 4
MobileScenario 2Scenario 5
TabletScenario 3Scenario 6

Record the capture flow

Install and start reflow locally:

npm install -g reflowio
reflowio dashboard

Then record a flow that walks the product through every state you want pictured:

  1. Create a flow against your product’s URL, named something stable — the name becomes the handle the CLI uses later. Here, “Reflow Documentation Flow”.
  2. Parameterize the theme. Add a browser JavaScript step that takes a darkMode variable and applies it the way your application expects — for an app that reads a localStorage key, set the key and fire a storage event. One recorded flow now produces both themes.
  3. Capture each screenshot as a visual assertion scoped to the element you care about (the whole body for full-page shots). Set the assertion to warn rather than fail on difference — the page is expected to evolve, and the flow should keep walking when it does.
  4. Name each capture step. A step described “login” exports as login.*.png; an unnamed one exports by step number. Names keep the import side of the pipeline readable.

Save the flow and run it once to seed the baseline.

Automate the matrix

With the flow recorded, the entire image set regenerates from the command line. Run the flow once per device profile and theme, then pull each run’s images into a directory per variant:

Terminal window
reflowio test "Reflow Documentation Flow" --device-emulation-profile "Chrome Desktop" --params "darkMode=false"
reflowio test "Reflow Documentation Flow" --device-emulation-profile "Chrome Desktop" --params "darkMode=true"
reflowio test "Reflow Documentation Flow" --device-emulation-profile "iPad Pro 11 (landscape)" --params "darkMode=false"
reflowio test "Reflow Documentation Flow" --device-emulation-profile "iPad Pro 11 (landscape)" --params "darkMode=true"
reflowio test "Reflow Documentation Flow" --device-emulation-profile "iPhone 13" --params "darkMode=false"
reflowio test "Reflow Documentation Flow" --device-emulation-profile "iPhone 13" --params "darkMode=true"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "Chrome Desktop" --params "darkMode=false" --out-dir "./desktop"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "Chrome Desktop" --params "darkMode=true" --out-dir "./desktop-dark"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "iPad Pro 11 (landscape)" --params "darkMode=false" --out-dir "./tablet"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "iPad Pro 11 (landscape)" --params "darkMode=true" --out-dir "./tablet-dark"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "iPhone 13" --params "darkMode=false" --out-dir "./mobile"
reflowio pull images "Reflow Documentation Flow" --device-emulation-profile "iPhone 13" --params "darkMode=true" --out-dir "./mobile-dark"

Six directories, one per scenario, regenerated on demand. Wire this into CI (an API key removes the interactive login) and documentation images stop being a maintenance task at all.

Serve the right image to each reader

The last step is making documentation pick the matching variant at read time. The shape of the solution is a themed-image component: it knows all six sources and renders the one matching the reader’s viewport and color-scheme preference.

<ThemedImage
alt="logging in"
sources={{
lightdesktop: '/img/desktop/login.png',
lightmobile: '/img/mobile/login.png',
lighttablet: '/img/tablet/login.png',
darkdesktop: '/img/desktop-dark/login.png',
darkmobile: '/img/mobile-dark/login.png',
darktablet: '/img/tablet-dark/login.png',
}}
/>

Two implementation notes that matter regardless of your documentation framework:

  • Selection is two media queries. Viewport buckets (max-width: 480px, 481–1025px, min-width: 1026px) and the dark-mode preference pick one of the six sources.
  • Render all variants on the server, then hide. If your documentation is statically rendered, emit every variant and let CSS media queries choose which displays. Selecting in JavaScript alone causes a flash of the wrong image before hydration.

The value

A reader on an iPhone in dark mode sees your product as they would experience it. A reader on a desktop in light mode sees theirs. And when your product changes, you run one command instead of retaking dozens of screenshots — the documentation images are now as automated as the tests.