/microcopy
Write the small strings that decide whether users figure your product out — or churn. Bad copy makes good visuals fail; good copy carries average visuals.
When to use
- Designing or reviewing any user-facing text — buttons, errors, empty states, tooltips, confirmations, form labels, onboarding.
- After a UX review flagged unclear messaging.
- When a feature ships with placeholder strings ("Submit," "Error," "Loading…") and needs real ones.
- When localizing — the source strings need to be localizable in the first place.
Operating method
1. Establish voice
Read 5–10 existing strings from the product before writing new ones. Identify:
- Tone — professional / friendly / playful / clinical. Most B2B is professional-with-warmth; consumer varies wildly.
- Person — second person ("Save your changes") almost always. First-person plural ("We saved your changes") for system updates only.
- Verb usage — direct ("Save"), polite ("Please save"), or playful ("Stash it"). Pick one and stick with it.
- Punctuation — sentence case vs title case for buttons. Periods at end of error messages or not.
- Emoji — used or not. (Default: not. Add only if the product already uses them.)
If no existing strings exist, default to: direct, second person, sentence case for buttons, periods on full sentences, no emoji.
2. Apply the four rules
Verbs over nouns on buttons. Buttons do something. Use the verb.
| Bad |
Good |
| Submit |
Send invite |
| OK |
Save changes |
| Confirmation |
Confirm payment |
| Settings |
Open settings |
Specific errors with recovery. Tell the user what went wrong AND what to do.
| Bad |
Good |
| Invalid input |
Email must include an @ symbol |
| Error |
Couldn't reach the server. Check your connection or retry. |
| Try again |
Card declined — try a different card |
| Failed |
Two-factor code expired — request a new one |
Empty states have CTAs. Don't leave the user stranded with "No results."
| Bad |
Good |
| No projects |
Create your first project to get started |
| 0 messages |
Your inbox is empty. Connect an account to start receiving mail. |
| Nothing here |
No matching results. Try a broader search or [clear filters]. |
Honesty in confirmations. Don't trick users into clicking yes.
| Bad |
Good |
| "OK" + "Cancel" on a destructive modal |
"Delete project" + "Keep project" |
| "Are you sure?" |
"Delete this project? This cannot be undone." |
3. Forbidden phrases
These signal lazy or hostile copy. Refuse to write them; replace if you find them.
| Phrase |
Why it's bad |
Replace with |
| "Simply…" / "Just…" / "Easy…" |
Patronizes the user — if it were that simple, they wouldn't be reading the help text |
Remove the word; explain the steps |
| "Oops!" / "Whoops!" |
Trivializes the user's problem |
Be specific about what happened |
| "Something went wrong" |
The least useful possible error |
Name what failed, name the recovery |
| "Please try again later" |
Useless — when? Why? |
Give a time, a reason, or a workaround |
| "Are you sure?" alone |
Doesn't tell the user the consequence |
"Delete X? This cannot be undone." |
| "Click here" / "Read more" |
Bad for accessibility (screen readers without context) |
Use descriptive link text: "Read the API docs" |
| Pre-checked consent ("☑ Yes, send me marketing emails") |
Illegal in EU (GDPR) |
Default unchecked; let users opt in |
| Confirmshaming ("No thanks, I don't want to save 50%") |
Dark pattern |
Plain language: "No thanks" |
4. Localization-friendly writing
Write strings that translate cleanly:
- No idioms. "Bite the bullet" doesn't translate. "Confirm the change" does.
- No concatenation. Don't write
"You have " + count + " messages" — different languages put numbers in different positions, and some require plural forms beyond singular/plural.
- Use ICU MessageFormat or your framework's i18n library for plurals, gender, and number formatting.
- Don't bake numbers into strings. "5 items" →
{count, plural, one {# item} other {# items}}.
- Render dates and currencies in user locale, not source locale.
- Leave 30% room for expansion. German strings are often 30–40% longer than English.
5. Cover all the moments
For every screen or component, walk the moments:
- Default — the standard view. What does it say?
- Loading — what's communicated while waiting?
- Empty — first-time-use copy + CTA.
- Success — confirmation message.
- Error — per failure mode (network, validation, permission, server).
- Disabled — why is this thing disabled? Tooltip explains.
- Confirm — destructive actions get a clear "do X / cancel" choice.
- Onboarding — first 3 actions for a new user.
6. Save patterns to memory
If the product establishes a copy convention (e.g., "always say 'Save changes' not 'Save'"), save it to .claude/memory/feedback/copy-conventions.md so future sessions follow the same voice.
Output format
For a copy spec:
# Microcopy: <screen / feature>
## Voice
- Tone: <professional with warmth>
- Person: second
- Case: sentence (buttons), title (page headers)
- Punctuation: full sentences end with periods; buttons no periods
## Strings
### Page header
<copy>
### Primary CTA (button)
<copy>
### Secondary action
<copy>
### Form fields
| Field | Label | Placeholder | Help text | Error: blank | Error: invalid |
|---|---|---|---|---|---|
| Email | "Work email" | "you@company.com" | "We'll send sign-in links here." | "Email is required." | "Email must include an @ symbol." |
### States
| State | Copy |
|---|---|
| Loading | "Sending invite…" |
| Success | "Invite sent ✓" |
| Error: network | "Couldn't send the invite — check your connection or retry." |
| Error: already invited | "Already invited — resend or remove." |
| Empty | "No invites sent yet. Send your first below." |
### Confirmation dialog (destructive)
- Title: "Remove team member?"
- Body: "They'll lose access to all projects. This can't be undone."
- Confirm button: "Remove member"
- Cancel button: "Keep member"
### Tooltips
| Element | Tooltip |
|---|---|
| Disabled "Send" button | "Add at least one recipient to send" |
| ⚠ icon next to plan | "Card on file expires in 7 days" |
For a copy review:
## Verdict: GREAT | NEEDS WORK | REWRITE
## Issues by category
### Specificity (N issues)
- error.tsx:18 — "Something went wrong" → "Couldn't save changes — check your connection and retry."
### Voice consistency (N issues)
- onboarding.tsx:42 — Uses first-person ("We've saved your work") but the rest of the product uses second person.
### Forbidden phrases (N issues)
- billing.tsx:91 — "Simply enter your card" → "Enter your card."
### Empty states (N issues)
- inbox.tsx:5 — "No messages" with no CTA → "Your inbox is empty. Connect an account to start."
### Localization-readiness (N issues)
- list.tsx:30 — `"You have " + count + " items"` → use ICU plural format.
## What's working
- <thing>
- <thing>
## Recommended next moves
1. <highest-leverage>
Boundaries
- Don't write for a voice the product doesn't have — read existing copy first.
- Don't write copy that's marketing-speak when the product is utilitarian, or vice versa.
- Don't recommend dark patterns. Refuse, name them, offer honest alternatives.
- Don't translate yourself — flag strings for translator review when localizing.
- Don't write copy without knowing the state. "Submit" with no context is meaningless.
- Always cover all relevant moments (loading / empty / error / success).
1---2name: microcopy3description: Writes or reviews UX copy — button labels, error messages, empty states, success messages, tooltips, form labels, onboarding text, confirmation dialogs. Voice-consistent, action-led, recovery-oriented. Localizable. No dark patterns.4---56# /microcopy78Write the small strings that decide whether users figure your product out — or churn. Bad copy makes good visuals fail; good copy carries average visuals.910## When to use1112- Designing or reviewing any user-facing text — buttons, errors, empty states, tooltips, confirmations, form labels, onboarding.13- After a UX review flagged unclear messaging.14- When a feature ships with placeholder strings ("Submit," "Error," "Loading…") and needs real ones.15- When localizing — the source strings need to be localizable in the first place.1617## Operating method1819### 1. Establish voice2021Read 5–10 existing strings from the product before writing new ones. Identify:2223- **Tone** — professional / friendly / playful / clinical. Most B2B is professional-with-warmth; consumer varies wildly.24- **Person** — second person ("Save your changes") almost always. First-person plural ("We saved your changes") for system updates only.25- **Verb usage** — direct ("Save"), polite ("Please save"), or playful ("Stash it"). Pick one and stick with it.26- **Punctuation** — sentence case vs title case for buttons. Periods at end of error messages or not.27- **Emoji** — used or not. (Default: not. Add only if the product already uses them.)2829If no existing strings exist, default to: direct, second person, sentence case for buttons, periods on full sentences, no emoji.3031### 2. Apply the four rules3233**Verbs over nouns on buttons.** Buttons do something. Use the verb.3435| Bad | Good |36|---|---|37| Submit | Send invite |38| OK | Save changes |39| Confirmation | Confirm payment |40| Settings | Open settings |4142**Specific errors with recovery.** Tell the user what went wrong AND what to do.4344| Bad | Good |45|---|---|46| Invalid input | Email must include an @ symbol |47| Error | Couldn't reach the server. Check your connection or retry. |48| Try again | Card declined — try a different card |49| Failed | Two-factor code expired — request a new one |5051**Empty states have CTAs.** Don't leave the user stranded with "No results."5253| Bad | Good |54|---|---|55| No projects | Create your first project to get started |56| 0 messages | Your inbox is empty. Connect an account to start receiving mail. |57| Nothing here | No matching results. Try a broader search or [clear filters]. |5859**Honesty in confirmations.** Don't trick users into clicking yes.6061| Bad | Good |62|---|---|63| "OK" + "Cancel" on a destructive modal | "Delete project" + "Keep project" |64| "Are you sure?" | "Delete this project? This cannot be undone." |6566### 3. Forbidden phrases6768These signal lazy or hostile copy. Refuse to write them; replace if you find them.6970| Phrase | Why it's bad | Replace with |71|---|---|---|72| "Simply…" / "Just…" / "Easy…" | Patronizes the user — if it were that simple, they wouldn't be reading the help text | Remove the word; explain the steps |73| "Oops!" / "Whoops!" | Trivializes the user's problem | Be specific about what happened |74| "Something went wrong" | The least useful possible error | Name what failed, name the recovery |75| "Please try again later" | Useless — when? Why? | Give a time, a reason, or a workaround |76| "Are you sure?" alone | Doesn't tell the user the consequence | "Delete X? This cannot be undone." |77| "Click here" / "Read more" | Bad for accessibility (screen readers without context) | Use descriptive link text: "Read the API docs" |78| Pre-checked consent ("☑ Yes, send me marketing emails") | Illegal in EU (GDPR) | Default unchecked; let users opt in |79| Confirmshaming ("No thanks, I don't want to save 50%") | Dark pattern | Plain language: "No thanks" |8081### 4. Localization-friendly writing8283Write strings that translate cleanly:8485- **No idioms.** "Bite the bullet" doesn't translate. "Confirm the change" does.86- **No concatenation.** Don't write `"You have " + count + " messages"` — different languages put numbers in different positions, and some require plural forms beyond singular/plural.87- **Use ICU MessageFormat** or your framework's i18n library for plurals, gender, and number formatting.88- **Don't bake numbers into strings**. "5 items" → `{count, plural, one {# item} other {# items}}`.89- **Render dates and currencies in user locale**, not source locale.90- **Leave 30% room for expansion.** German strings are often 30–40% longer than English.9192### 5. Cover all the moments9394For every screen or component, walk the moments:9596- **Default** — the standard view. What does it say?97- **Loading** — what's communicated while waiting?98- **Empty** — first-time-use copy + CTA.99- **Success** — confirmation message.100- **Error** — per failure mode (network, validation, permission, server).101- **Disabled** — why is this thing disabled? Tooltip explains.102- **Confirm** — destructive actions get a clear "do X / cancel" choice.103- **Onboarding** — first 3 actions for a new user.104105### 6. Save patterns to memory106107If the product establishes a copy convention (e.g., "always say 'Save changes' not 'Save'"), save it to `.claude/memory/feedback/copy-conventions.md` so future sessions follow the same voice.108109## Output format110111For a copy spec:112113```114# Microcopy: <screen / feature>115116## Voice117- Tone: <professional with warmth>118- Person: second119- Case: sentence (buttons), title (page headers)120- Punctuation: full sentences end with periods; buttons no periods121122## Strings123124### Page header125<copy>126127### Primary CTA (button)128<copy>129130### Secondary action131<copy>132133### Form fields134| Field | Label | Placeholder | Help text | Error: blank | Error: invalid |135|---|---|---|---|---|---|136| Email | "Work email" | "you@company.com" | "We'll send sign-in links here." | "Email is required." | "Email must include an @ symbol." |137138### States139| State | Copy |140|---|---|141| Loading | "Sending invite…" |142| Success | "Invite sent ✓" |143| Error: network | "Couldn't send the invite — check your connection or retry." |144| Error: already invited | "Already invited — resend or remove." |145| Empty | "No invites sent yet. Send your first below." |146147### Confirmation dialog (destructive)148- Title: "Remove team member?"149- Body: "They'll lose access to all projects. This can't be undone."150- Confirm button: "Remove member"151- Cancel button: "Keep member"152153### Tooltips154| Element | Tooltip |155|---|---|156| Disabled "Send" button | "Add at least one recipient to send" |157| ⚠ icon next to plan | "Card on file expires in 7 days" |158```159160For a copy review:161162```163## Verdict: GREAT | NEEDS WORK | REWRITE164165## Issues by category166167### Specificity (N issues)168- error.tsx:18 — "Something went wrong" → "Couldn't save changes — check your connection and retry."169170### Voice consistency (N issues)171- onboarding.tsx:42 — Uses first-person ("We've saved your work") but the rest of the product uses second person.172173### Forbidden phrases (N issues)174- billing.tsx:91 — "Simply enter your card" → "Enter your card."175176### Empty states (N issues)177- inbox.tsx:5 — "No messages" with no CTA → "Your inbox is empty. Connect an account to start."178179### Localization-readiness (N issues)180- list.tsx:30 — `"You have " + count + " items"` → use ICU plural format.181182## What's working183- <thing>184- <thing>185186## Recommended next moves1871. <highest-leverage>188```189190## Boundaries191192- Don't write for a voice the product doesn't have — read existing copy first.193- Don't write copy that's marketing-speak when the product is utilitarian, or vice versa.194- Don't recommend dark patterns. Refuse, name them, offer honest alternatives.195- Don't translate yourself — flag strings for translator review when localizing.196- Don't write copy without knowing the state. "Submit" with no context is meaningless.197- Always cover all relevant moments (loading / empty / error / success).