Work

Museum Label Generator

A tool that generates six interpretive text formats from a single artwork description. Built to support human editorial control, not replace it.

Claude APINext.jsTypeScriptNetlify FunctionsJSON structured output
GitHub
The problem

Museum wall labels are written for visitors who already speak the language of art history. For everyone else (a child, a casual visitor, a designer who thinks visually), the infrastructure meant to help them often doesn't. Labels are a bottleneck: curators are overworked, the writing process is slow, and scaling across formats (audio, kids, alt text) is rarely prioritized. The tool takes a single artwork description and generates six interpretive formats simultaneously. The AI acts as a starting point. Human editorial control is built in at every step.

What came of it

No institution has run this on a live collection. What came out of it instead is a rule I now build in by default: the curator notes field exists to flag what the source description did not say, after early versions filled those gaps by inventing cultural attributions. A tool that produces confident text for a museum wall has to be able to say what it does not know.

Paused

Click to pause · Double-click to resume

Wall Label
Untitled
Artist unknown · Date unknown

Famille noire porcelain exemplifying the Kangxi period's apotheosis of ferric oxide reduction firing, the pictorial program articulating a syncretic cosmological schema through the deployment of peony, prunus, and corvid iconography within a horror vacui compositional field. Wait, what? Use the generator.

Architecture

A browser form collects artwork metadata, source description, tone, and grounding preferences. A Netlify function keeps the API key server-side, sends one Claude request, validates the JSON response, and renders each label format as an editable draft.

Architecture diagram
Wall label Standing visitor, 15 seconds. ~80 words, no jargon.
Extended label Visitor who pauses. ~200 words, permits depth.
Kids label Age 6–10, not simplified but differently framed. Questions, wonder, sensory detail.
Audio guide script Listener, not reader. Written for the ear, with conversational rhythm, present tense, ~45 seconds spoken.
Alt text Screen reader user. A functional replacement for a visual. Objective, WCAG-compliant, no interpretation.
Curator notes Internal. Flags ambiguities, suggests research directions, notes what the source description didn't specify.
Input: "Indigo Resist Length", unknown maker, c. 1890, cotton and natural
indigo. A length of plain-weave cotton dyed using a stitch-resist technique.
Concentric ring patterns emerge where the fabric was gathered and bound
before dyeing. Edges show irregular wear consistent with domestic use.

Wall label: This length of plain-weave cotton was dyed with natural indigo
around 1890 using a stitch-resist technique. Areas of fabric were gathered
and bound before dyeing, creating the concentric ring patterns visible
across the surface. The maker is unknown.

Kids label: This piece of cloth was made around 1890. To create the pattern,
someone gathered parts of the fabric and tied them tightly before dipping
the cloth in blue dye made from a plant called indigo.

Audio guide: You are looking at a length of cotton cloth made around 1890.
The deep blue color comes from natural indigo, a dye made from plants.

Alt text: A rectangular length of plain-weave cotton fabric dyed deep blue
with natural indigo. Lighter concentric ring patterns are distributed across
the surface, and the edges show visible fraying and uneven fading.

Curator notes:
  - Origin is unrecorded; avoid attributing this object to any specific
    culture, region, or tradition without supporting documentation.
  - Stitch-resist dyeing is practiced across many cultures and time periods;
    no single attribution is supported by the available description.

Plus an extended label and three alternate wall labels, not shown.
  • Structured JSON over streaming text All six formats arrive together and render into independent copyable cards. Streaming would have made per-section copy interactions much more complex, and curators typically want all formats at once anyway.
  • Alt text is one of the six formats, not an export option Alt text comes back in the same response as the wall label and renders into the same kind of copyable card. The prompt constrains it to one or two sentences focused on what is visible, because the common failure is alt text that interprets the work instead of describing it, which leaves a screen reader user with the curator's reading and none of the object. The limitation is honest and worth stating: the model never sees the artwork. It writes the alt text from the curator's source description, so anything missing from that text is missing from the output too. The tool drafts the description; it cannot verify it.
  • A single API call for all six formats Higher latency per generation, but simpler architecture and a better match for how the tool gets used. The tradeoff was worth it.
  • Tone as a prompt injection, not a separate system prompt The tone dropdown (Neutral, Warm, Playful, Academic) injects into the user prompt rather than switching system prompts. Less precise, but much simpler to maintain as a single prompt template.
  • The 'Show Prompt & Architecture' toggle Exposes the system prompt, user template, and call flow to anyone who wants to see them. Institutional adopters want to audit what the model is doing before they trust it with their collections. Showing the work is also a trust signal for visitors skeptical of AI tools in cultural contexts.
  • API key security via Netlify Function All calls route through a serverless function. The key never touches the browser. Cold starts add ~300ms latency on first request, which is acceptable for a tool used in considered, not rapid-fire, workflows.
Minimum: ~30 characters
Output
Copy individual sections for drafts and iteration.
Generate to see wall label drafts, alt text, and curator notes here.