Skip to content

← All notes

29 July 20263 minDesign / Craft

A placeholder is not a promise

A frame captioned "screenshot to follow" does not read as work in progress. It reads as a broken image.

A product page had three browser frames on it, each holding a caption explaining which screenshot would eventually go there. The intent was honest: the captures did not exist yet, and pretending otherwise was not an option.

The problem is that intent is invisible. A visitor arriving cold sees three empty boxes where images should be, and has no way to distinguish "not captured yet" from "the images are failing to load". One of those is a note to self. The other is a site that looks broken, and it is the reading a stranger will reach first.

Making the wrong state unbuildable

The fix was not better placeholder copy. It was removing the ability to render one. The component that shows captures has no empty state at all — it takes an image path and renders an image, and that is the whole of its API.

/**
 * The rule this component exists to enforce: it only ever renders an
 * image file. There is no placeholder state, because a frame with
 * nothing in it reads as a missing asset rather than as evidence.
 * A product with no captures shows no shots at all.
 */

Applying that cost a page three frames and the section built to hold two of them. It is shorter now, and everything on it is real. The captures drop straight in the day they exist, and until then nothing on the page is asking to be believed.

The general form: when a state should never ship, the cheapest place to enforce that is the type or the component, not a reminder to check before deploying. Reminders are load-bearing exactly until the day they are not.

If the empty state should never be seen, do not build one.

The launch checklistPlaceholder copy is one of 49 checks a build gets before it goes out — with the ones that cost real money marked.

Building something like this? Let's talk.

Start a project ↗