Placeholder Art

Tasteful stand-ins for missing images: a token-tinted pattern (grid, dots, lines, rings or glow) picked deterministically from a seed string, with an optional glyph and caption. No assets, no network, no dependencies — it follows theme and accent. Image uses it automatically when there is no src, so blocks never need hard-coded stock photos.

CSS gradients (no dependencies) components/placeholder-art.tsx, components/image.tsxtheme · material · accent · density · font
Harbour terraceRooftop · 40 guests
Linden loftStudio · 12 guests
Orchard roomPrivate dining · 18 guests

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { Image, PlaceholderArt } from "@vamos-ui/react";

// Image with no src renders art, named by alt
<Image src={post.cover} alt={post.title} aspect="16/9" />

// Art while loading and on error
<Image src={url} alt="Team offsite" aspect="4/3" placeholder="art" />

// Standalone (fills its parent)
<PlaceholderArt seed="harbour-terrace" label="Harbour terrace" caption />

Colours are color-mix() of --chart-1…6 and --surface-2, so the art follows dark mode and the accent (chart-1 is the accent ink).

PlaceholderArt has no client code and renders in server components. It fills its parent: give the parent a size, or use it inside AspectRatio or Image.

Placeholder art is a stand-in, not decoration: give it a label when the image carries meaning, so screen readers still hear what belongs there.

Examples

Patterns

The seed picks the pattern, tint (a chart palette slot), angle and focal point. pattern forces one.

grid
dots
lines
rings
glow

Image without a src (blog list)

src null, undefined or "" renders art at the given aspect (4:3 if none) with alt as its accessible name. seed defaults to alt.

How we cut onboarding from 9 days to 3

Mira Castell

A field guide to quarterly pricing reviews

Jonas Ferreira

Notes from the spring partner summit

Ada Lindqvist

While loading and on error

placeholder="art" shows the art under a loading image and keeps it when the source fails. placeholderCaption prints the alt.

Team offsite in the hills
Broken URL — the art is the fallback, named by alt.
No src, forced grid pattern, no glyph.

Site hero before photography

strength="bold" for large areas, a custom glyph and a caption that says what goes there.

Spring season

Ceramics evenings at Fernwood Studio

Six Thursdays, small groups, clay and glazes included.

API

PlaceholderArt

PropTypeDefault
seed
Any stable string (slug, title, record id). Same seed → same art on server and client.
stringlabel
pattern
Force a pattern; auto picks from the seed.
"auto" | "grid" | "dots" | "lines" | "rings" | "glow""auto"
label
What the missing image would show. Set → role="img" with this name; unset → decorative (aria-hidden).
string—
icon
Centre glyph in a small frosted ring. false hides it.
ReactNode | falseimage glyph
caption
true prints the label in the bottom corner; or pass your own text.
boolean | ReactNode—
strength
bold raises the tint for large hero areas.
"subtle" | "bold""subtle"

Image (placeholder props)

PropTypeDefault
src
null, undefined or "" renders art (alt required, "" = decorative).
string | MediaAsset | null—
placeholder
art: seeded art while loading and as the error fallback (unless fallback is set).
"blur" | "color" | "skeleton" | "art" | "none"—
seed
Seed for the art.
stringalt, then URL
placeholderPattern
Force the art pattern.
PlaceholderArtPattern | "auto""auto"
placeholderIcon
Glyph in the art; false hides it.
ReactNode | false—
placeholderCaption
true prints alt as a caption on the art.
boolean | ReactNode—

Helpers (pure, server-safe)

PropTypeDefault
placeholderArtRecipe(seed, pattern?)
{ pattern, hue, hue2, angle, cell, x, y } from an FNV-1a hash of the seed.
→ PlaceholderArtRecipe—
placeholderArtStyle(recipe, strength?)
The background for a recipe — use it on your own element.
→ CSSProperties—
hashSeed(seed)
32-bit FNV-1a hash.
→ number—
PLACEHOLDER_ART_PATTERNS
All pattern names.
PlaceholderArtPattern[]—