Skip to content

Microcopy & Content

A UX principle for coding agents. Also covers copy, content, cta, button copy, labels, empty state copy, and 12 more.

Show all 18 aliases

copy, content, cta, button copy, labels, empty state copy, reassurance, benefit copy, swap test, voice of customer, framework principle, structured copy, enumerated points, lists, purpose test, deletion test, ceremonial copy, redundant copy

Words are interface. A button's label, an empty state's one sentence, the error that appears at the worst moment: these do as much work as any layout or color decision, and users read them at exactly the moments that matter most. Yet copy is the part of the UI most often left to a placeholder that ships. "Submit," "Error," "Are you sure?" are not neutral defaults; they're missed opportunities to tell the user what's happening and what to do.

Good microcopy is invisible in the same way good design is: the user never notices the words because the words never make them stop and decode. Bad microcopy makes the user do the product's thinking for it. This doc covers how to write the strings; errors.md and ui/polish.md cover the specific copy for failures and empty states, and this doc cross-references rather than repeats them.

A house rule runs through every example here: no em dashes in shipped UI copy. Use commas, colons, periods, or rephrase. Hyphens in compound modifiers are fine. This is the project copywriting rule, and it applies to every string in the examples below (the rule is for product strings, not for this reference doc's prose).

Start from the Reader's Job

Copy should answer why the screen matters before it explains how the product works. The fastest route to that answer is research, not wordplay.

  • Borrow the user's language. Mine interviews, support tickets, reviews, and sales calls for the exact words people use to describe the problem and desired outcome. Copy feels tailored when it reflects the reader's vocabulary instead of the team's internal model.
  • Lead with the benefit. Translate a feature into what becomes easier, faster, safer, or less stressful. If the benefit is not obvious within a glance, rewrite before polishing the sentence.
  • Anticipate the next doubt. Add concise reassurance at the decision point: whether the action is reversible, what happens next, whether payment starts now, or whether preparation is required. Do not make the user click just to resolve a predictable fear.
  • Know the product before writing about it. Generic copy often signals that the author has not resolved what the product actually does. Research the offer until you can state the outcome concretely.
  • Run the swap test. Remove the logo and visuals. If a competitor could use the same headline or CTA unchanged, the copy is probably too vague. When the string that fails is a landing page headline, the fix is usually upstream in the positioning, not in the wording: see positioning.md.

Every Visible Line Needs a Job

Short copy can still be bad copy. A common generated-interface mistake is adding text because a familiar template usually has it. Examples: a footer provenance line, a generic helper sentence, a reassuring slogan, or a caption under a self-evident thumbnail. That text feels harmless, but it makes the interface heavier without helping the user.

Every visible text fragment needs one concrete user-facing job:

  • Identify context or origin when the screen would otherwise feel ambiguous.
  • Explain what happened after the system changes state.
  • Make the next action clear where the control alone is not enough.
  • Reduce a real doubt the user is likely to have at that moment.
  • Satisfy a legal, security, or compliance requirement that cannot be omitted.

If a line does none of those, remove it. Provenance, security, and legal copy are allowed when they do real work; they fail when they only repeat a brand, sender, or fact the layout already makes obvious.

// ❌ Bad: template memory, not user value
<EmailFooter>This link was sent by Example Co.</EmailFooter>

// ✅ Good: the useful security copy stays, the ceremonial line is gone
<p>If you did not request this, you can ignore this email.</p>

Run the deletion test before shipping. Remove the line. If meaning, action clarity, safety/trust, legal compliance, and intentional tone do not get worse, keep it removed.

Voice & Tone

Voice is constant; tone flexes with the moment. The product always sounds like itself, but it doesn't sound the same announcing a success as it does reporting a failed payment.

  • Voice is the personality: plain and direct, warm and casual, precise and technical. Pick one and hold it across every surface. Inconsistent voice (a playful empty state next to a stiff error) reads as multiple authors, which is exactly what it usually is.
  • Tone adjusts to context and severity. Light for a minor confirmation, calm and serious for a destructive action or a failure. A jokey error after the user lost work is tone-deaf; a heavy, ceremonial confirmation for a trivial toggle is overwrought.
  • Match tone to the user's emotional state at that point in the flow, not to a brand-voice doc in the abstract. The same product can be cheerful at "welcome" and grave at "delete account" without breaking voice.

Buttons & CTAs

A button label is a promise about what happens when it's clicked. Make it a specific verb that names the outcome, not a generic form word.

❌ Submit            ✅ Create project
❌ OK                ✅ Save changes
❌ Yes               ✅ Delete 3 files
❌ Continue          ✅ Go to checkout
  • Lead with a verb and name the object: "Create project," "Send invite," "Export CSV." The user should know the result without reading the surrounding context.
  • Match the label to the action's weight and hierarchy. The primary action gets the confident verb; secondary actions are quieter (see ui/hierarchy.md — the three-level action hierarchy). Don't give two buttons equally loud verbs when one is clearly primary.
  • In confirmations, label the action, not "Yes/No." "Delete project" / "Cancel" is unambiguous even read out of context; "Yes" / "No" forces the user back up to the question (see dialogs.md — Confirmation Dialogs, interactions.md — Confirm Destructive Actions).
  • Use the ellipsis for actions that open a follow-up rather than acting immediately: "Rename…", "Export…" (see interactions.md — Ellipsis for Loading States, for the related loading convention).

Labels

A label is supporting content, and often it's unnecessary. Before adding one, ask whether the format or context already identifies the data.

  • Skip the label when the format speaks: an email, a phone number, a price, a date need no "Email:" prefix to be understood (see ui/hierarchy.md — Labels are a Last Resort).
  • Combine label and value where it reads more naturally: "12 left in stock" beats "In stock: 12"; "3 bedrooms" beats "Bedrooms: 3."
  • When a label is needed, treat it as quiet: smaller, lighter, lower contrast than the value it supports, unless the page is information-dense and users scan for labels (specs, technical tables).
  • Form labels are mandatory and visible, even when the design is compact: a placeholder is not a label (see forms.md — Every Input Has a Label, and Helper & Placeholder Text below).

Helper & Placeholder Text

Helper text and placeholders do different jobs, and conflating them is the most common form-copy mistake.

  • A placeholder is an example, not a label. It shows the expected format and vanishes on input, so it can't carry anything the user needs after they start typing. End it with an ellipsis to signal emptiness and show a real pattern: +1 (123) 456-7890, sk-012345… (see forms.md — Placeholder Patterns).
  • Helper text is persistent guidance that stays visible: format requirements, constraints, the reason a field is needed. Put it where it stays readable while the user types, not in a placeholder that disappears.
  • Don't repeat the label in the placeholder. A field labeled "Email" with placeholder "Email" wastes the example slot; use it for "[email protected]" instead.
  • Keep helper text attached to its field so the relationship is unambiguous (see ui/layout-spacing.md — Text-to-control rhythm).

Error Messages

Error copy is the highest-stakes microcopy because the user reads it frustrated. The full rules and worked examples live in errors.md — Error Copy; the principles in one line each:

  • No blame — describe the situation, not the user's fault.
  • No jargon or codes — the user can't act on an exception name.
  • Specific and actionable — name the fix, not just that something is invalid.
  • Never leak internal detail. Stack traces and error codes are a poor experience and a security leak (see errors.md, and the CLAUDE.md security rule).

Empty State Copy

Empty is not one state, and its copy changes with the cause. Each type answers what's empty, why, and what to do next, in its own voice (see ui/polish.md — Don't Overlook Empty States).

  • First-use: name the missing thing and give the setup action. "No projects yet. Create your first to get started." (see onboarding.md — Empty States Are Onboarding).
  • Filtered-out: name the active cause, not absence. "No orders match these filters" not "No orders yet" when orders exist (see search.md — Zero Results).
  • Cleared-out: acknowledge the change. "All tasks complete" not first-use language.
  • Permission / error: say it plainly. "You don't have access to billing" / "We couldn't load invoices."

The cardinal sin is using first-use copy for every empty state. "No orders yet" displayed when 184 orders exist behind an active filter tells the user the product is broken.

Confirmation & Destructive Copy

When the copy guards an irreversible action, it must name the consequence precisely. Vagueness here is dangerous.

  • State what will happen and whether it's reversible. "Delete 3 projects? This can't be undone." The count and the irreversibility are the two facts the user needs.
  • Don't soften destructive copy into ambiguity. "Are you sure?" makes the user reconstruct the stakes; "Permanently delete this account?" states them.
  • The buttons name the actions, and the safe one is the easy default (see Buttons & CTAs above, dialogs.md — Confirmation Dialogs).
  • Prefer offering Undo over a pre-confirmation for reversible actions; reserve the heavy confirmation copy for the truly irreversible (see notifications.md — Blocking Alerts & Modals).

Numbers, Dates & Units

Numbers and units have their own correctness rules, both in formatting and in how they're typeset.

  • Format for the user's locale. Dates, times, numbers, currencies, and delimiters all differ by locale; use Intl rather than hardcoding (see interactions.md — Locale-Aware Formats). Detect locale from language settings, not IP (see interactions.md — Prefer Language Settings Over Location).
  • Keep units and terms from breaking across lines with non-breaking spaces: 10 MB, ⌘ K, Vercel SDK should never wrap mid-unit (see interactions.md — Non-Breaking Spaces).
  • Use tabular figures for numbers that align in columns or update in place: prices, timers, counters, totals (see ui/typography.md — Tabular Numbers). Proportional figures are fine in running prose.
  • Round and humanize where precision isn't the point. "2 minutes ago" beats a raw timestamp for recency; "1,240 results" beats "1240."

Write for Scanning

Users don't read UI, they scan it. Write so the meaning survives a glance.

  • Front-load the important word. The first words of a label, heading, or list item carry the most weight because they're what the eye catches.
  • Be brief. Cut every word that doesn't change the meaning. "Your changes have been successfully saved" is "Changes saved." Microcopy is where verbosity is most expensive.
  • Write with an eraser. Make a dedicated deletion pass after the meaning is correct. For every sentence, ask whether removing it would break understanding or action. If not, cut it.
  • One idea per string. A label or button that tries to say two things says neither clearly.
  • Use sentence case for most UI text: it's faster to read than Title Case and feels less shouty (see Capitalization & Punctuation below).

The Framework Principle

When copy carries more than one point, summarize it into a framework: name the structure first (the count and the frame), then fill it in. Points that trail out of a winding sentence force the reader to build the structure themselves; copy that announces its shape is scannable at a glance.

❌ "This plan is great because it gives you unlimited projects and it also
    lets your team collaborate and you get priority support too."
✅ "Three things Pro unlocks: unlimited projects, team collaboration,
    priority support."
  • Announce the frame before the content. "3 steps," "2 options," "4 reasons": the count primes the reader for what's coming and tells them when they're done.
  • Deliver exactly what the frame promises, in that order. A "3 things" opener followed by four points breaks the contract. If a point doesn't fit the frame, change the frame or cut the point; never bolt it on as an afterthought.
  • Prefer a list once the frame is named. Parallel items usually read best as a bulleted or numbered list under the framing line (see Write for Scanning above).
  • Apply it wherever copy explains with multiple points: feature callouts, upgrade dialogs, onboarding steps, plan comparisons, changelog entries, tooltips that justify a choice.

Capitalization & Punctuation

Consistency in the small marks is what separates polished copy from improvised copy.

  • Sentence case by default for buttons, labels, headings, and menu items: "Create project," not "Create Project." It reads faster and scales better to long labels. Pick sentence case or Title Case and apply it everywhere; mixing the two is the tell of multiple authors.
  • No em dashes in shipped copy. Use a comma, a colon, or two sentences. "Live data unavailable: showing last known values," never with an em dash. Hyphens in compound modifiers ("pebble-soft," "two-tone") are fine.
  • Minimal terminal punctuation in short UI strings. Labels and buttons don't take periods; full sentences in helper text, errors, and empty states do. Be consistent within a surface.
  • One space, curly quotes where the stack supports them, and no double exclamation. Enthusiasm is carried by the verb, not the punctuation.

Plain & Inclusive Language

Write for the widest possible reader, in the plainest words that are still precise.

  • Plain words over jargon. Say "delete," not "deprovision"; "settings," not "configuration parameters," unless the audience is genuinely technical and expects the term.
  • Address the user directly as "you," and prefer the active voice: "We saved your changes" or "Changes saved," not "The changes were saved by the system."
  • Avoid idioms and culturally narrow references that don't translate and may exclude. They also break under localization (see design-process.md — translated text that is 40% longer).
  • Be inclusive by default: gender-neutral phrasing, no assumptions about ability ("click" can become "select"), and examples that don't center one group.
  • Write for translation. Short, literal, idiom-free copy survives localization; clever wordplay does not.

Checklist

Voice

  • One consistent voice across all surfaces
  • Tone flexes with context and severity (light to grave)
  • Copy uses language gathered from users, not internal product jargon
  • Copy still sounds natural when read aloud

Buttons & labels

  • CTAs are specific verbs naming the outcome ("Create project," not "Submit")
  • Benefit is obvious; generic copy fails the competitor swap test
  • Predictable doubts are answered next to the decision
  • Confirmations label the action, not "Yes/No"
  • Labels skipped when format/context identifies the data; combined where natural
  • Form labels visible (placeholder is never the label)

Helper & errors

  • Placeholder is an example with an ellipsis, not a label
  • Helper text persistent and attached to its field
  • Error copy blameless, jargon-free, actionable; no internal detail (see errors.md)

Structure

  • Multi-point copy names the frame first ("Three things Pro unlocks:"), then delivers exactly those points in order

States & numbers

  • Empty state copy matches its type (first-use / filtered / cleared / permission / error)
  • Destructive copy names the consequence and reversibility
  • Numbers/dates/units locale-formatted; units kept together with &nbsp;
  • Tabular figures for aligned/updating numbers

Style

  • Front-loaded, brief, one idea per string
  • Every visible line has a user-facing job; ceremonial copy passes the deletion test or is removed
  • Sentence case (or chosen case) applied consistently
  • No em dashes in shipped copy
  • Plain, direct, inclusive, translation-friendly language

A link is a promise about where it leads, and screen-reader users navigate by a flat list of a page's links with no surrounding sentence to explain them. The link text has to carry the destination on its own.

  • Name the destination in the link text. "Read the billing docs," "View export history," not a bare "click here" or "read more" that means nothing lifted out of its sentence.
  • Suffix a generic phrase to make it specific. When several "Learn more" links share a page they're indistinguishable in a link list; write "Learn more about exports," "Learn more about billing" instead.
  • "Click here" also fails the device-verb rule (see Device-Matched Verbs below): it assumes a mouse. Describe the destination and the verb problem goes away with it.

Toggle & Setting Labels

A toggle's label should read as the thing that happens when it's on, so the user predicts the effect without parsing a negation.

  • Label the ON case. "Send read receipts," and the off state is understood. Never label the negative ("Don't send read receipts"): switching a "don't" toggle off is a double negative the user has to unwind before they know what they've done.
  • Link straight to the setting, not the path to it. A "Notification settings" link beats the instruction "Go to Settings, then Notifications, then Email." Send the user to the destination rather than describing the clicks to reach it.

Variables in Strings

Copy that wraps a variable in glued-together fragments breaks the moment it's translated, because word order and plural rules differ by language.

  • Never concatenate around a variable. "You have " + n + " new messages" hardcodes English word order; a full templated string ("You have {count} new messages") keeps the whole sentence translatable.
  • Pluralize properly, don't bolt "(s)" onto the noun. Use the framework's plural handling so "1 message" and "3 messages" both read naturally, and languages with more than two plural forms still resolve (see Numbers, Dates & Units above for the locale-formatting side of this).

Consistent Flow Vocabulary

A multi-step flow should speak one vocabulary from the first screen to the last. Pick a word for each role and hold it.

  • One word per action, repeated. "Get started" to enter, "Continue" (or "Next," pick one) to advance every step, "Done" to finish. Don't advance with "Continue" on step 2 and "Next" on step 3.
  • Synonyms read as different actions. When the label for the same action changes between steps, users stop to wonder whether the behavior changed too. Consistency is what makes the flow feel like one path (this is the Voice & Tone consistency rule above, applied inside a single flow).

Device-Matched Verbs

The verb for operating a control depends on the input the user actually has, so match it to the device instead of defaulting to "click."

  • "Tap" on touch, "click" with a pointer, "select" when both are possible. "Select" is the safe cross-device default and the inclusive one, because it doesn't assume a mouse (this is the "click can become select" note from Plain & Inclusive Language above).
  • Hardcoding "click" in a touch context reads as wrong to every mobile user, and "click here" links compound the mistake with a target that names nothing (see Link Text above).

Reword vs Redesign

Microcopy can only carry so much. When the same error fires for a large share of users, the message is not the problem, the interaction is.

  • A systemic, recurring error means redesign the interaction, not reword the message. No phrasing of "Invalid date format" beats a date picker that makes the bad input impossible to enter (see errors.md, Prevent Errors Before They Happen). Treat a high-frequency error as a design signal, not a copy task.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-ux-principle({ topic: "microcopy" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems