ux-copy

SKILL.md

UX Copy — UI Text That Works

Production-ready UX copy patterns for React and Next.js applications. Every pattern includes real JSX examples — not just advice, but copy you can use directly in components.

This skill works in two modes:

  • Greenfield — establishing voice, writing first copy, setting up copy architecture
  • Mature codebase — auditing existing copy, fixing inconsistencies, refactoring for clarity

Architecture Overview

[Voice Definition]
    ├── Voice worksheet (4 dimensions: formality, humor, authority, warmth)
    ├── Tone spectrum map (which contexts allow flexibility)
    └── Project voice profile ("confident, precise, reassuring")
[Component Copy Rules]
    ├── Buttons → verb-first, specific action, 2-4 words
    ├── Errors → what happened + why + what to do
    ├── Empty states → explain + guide + single CTA
    ├── Confirmations → name the action, never Yes/No
    ├── Notifications → severity determines tone and persistence
    ├── Labels → describe the field, not the format
    └── Tooltips → one sentence, answers "what is this?"
[Writing]
    ├── Apply universal rules (plain language, active voice, front-load)
    ├── Modulate tone to context (errors serious, onboarding flexible)
    └── Match existing voice if mature codebase
[Review]
    ├── 3 C's test: Clear → Concise → Character
    ├── Read aloud test
    └── Consistency check (1 entity = 1 term)

Quick Reference

Need to... See
Define voice for a new project Voice and Tone
Infer voice from existing copy Voice and Tone
Write button labels, form labels, tooltips Microcopy
Write error messages and validation text Errors and Validation
Write empty states and loading indicators Empty and Loading
Write CTAs, sign-up flows, onboarding Onboarding and CTAs
Write destructive confirmation dialogs Confirmation and Danger
Write toasts, banners, alerts, status messages Notifications and Status
Audit and fix copy across a mature codebase Auditing and Refactoring

Decision Matrix: "What Should This Say?"

By component type

Component Copy Pattern Length Tone Range Example
Button Verb + object 2-4 words Full range "Create project" / "Send invite"
Link Describes destination 2-6 words Full range "View pricing" / "Learn more about plans"
Label Describes the field 1-3 words Neutral "Email address" / "Company name"
Placeholder Shows format or example 3-6 words Neutral "name@company.com" / "Search by title..."
Tooltip Answers "what is this?" 1 sentence Neutral "Messages older than 30 days are archived automatically."
Toggle Describes the ON state 2-5 words Neutral "Send email notifications"
Error (inline) What's wrong + how to fix 1 sentence Serious "Enter a password with at least 8 characters."
Error (system) What happened + recovery path 1-2 sentences Serious "We couldn't save your changes. Check your connection and try again."
Empty state What goes here + how to start 1-2 sentences + CTA Flexible "No projects yet. Create your first project to get started."
Toast (success) Confirm what happened 2-4 words Brief "Changes saved" / "Invite sent"
Toast (error) What failed + next step 1 sentence Serious "Couldn't save changes. Try again."
Banner Awareness + optional action 1-2 sentences Informational "Your trial expires in 3 days. Upgrade to keep your data."
Confirmation dialog Consequence + specific action buttons 1-3 sentences Serious "This will permanently delete 12 files. They can't be recovered."
Onboarding Value + single next step 1-2 sentences + CTA Warm/flexible "Track your team's work in one place. Create your first board."

"Is this copy good?" — The 3 C's Test

1. CLEAR — Can a new user understand this without context?
   ├── YES → continue
   └── NO → rewrite in plain language, remove jargon
2. CONCISE — Can any words be removed without losing meaning?
   ├── NO, it's tight → continue
   └── YES → cut them (especially: "please", "in order to", "simply", "just")
3. CHARACTER — Does the tone match the project's voice AND this context?
   ├── YES → ship it
   └── NO → adjust toward the right point on the tone spectrum
             (errors → serious end, onboarding → flexible end)

Source: Nielsen Norman Group — 3 C's framework (Clarity > Concision > Character, in that priority order)

Core Principles

These 8 rules are universal — every major UX writing authority agrees on them regardless of brand, industry, or tone.

1. Plain language, always

Use "buy" not "purchase." Use "start" not "initiate." Use "end" not "terminate." This applies even to formal/enterprise products — plain is not casual, it's clear.

Source: GOV.UK (9-year-old reading age target), Microsoft ("simpler is better"), Shopify Polaris (7th-grade reading level)

2. Active voice, address the user as "you"

// FAIL — passive, impersonal
<p>The password has been reset successfully.</p>

// PASS — active, direct
<p>You reset your password.</p>

Source: All 6 sources (NN/g, GOV.UK, Google, Microsoft, Apple, Atlassian)

3. Front-load important information

Users read in an F-pattern — they scan the first few words of each line. Put the critical information first.

// FAIL — buries the action
<p>In order to access your dashboard, you need to verify your email first.</p>

// PASS — leads with what matters
<p>Verify your email to access your dashboard.</p>

Source: NN/g (users read only 20-28% of page content), GOV.UK (inverted pyramid)

4. One idea per copy unit

Every microcopy element has one job. A button label describes one action. An error message addresses one problem. A tooltip answers one question. If you need to convey two ideas, use two elements.

Source: NN/g (3 I's — each copy item either Informs, Influences, or facilitates Interaction), Kinneret Yifrah ("1 microcopy item = 1 idea")

5. Never blame the user

// FAIL — accusatory
<p className="text-destructive">Invalid email address.</p>

// PASS — helpful
<p className="text-destructive">This email needs an @ symbol.</p>

// FAIL — scolding
<p className="text-destructive">You entered an incorrect password.</p>

// PASS — guides toward the fix
<p className="text-destructive">That password doesn't match. Try again or reset it.</p>

Words to avoid in error states: "invalid", "illegal", "incorrect", "wrong", "bad", "failed"

Source: NN/g (13 error message guidelines), Apple HIG, Shopify Polaris

6. Voice is constant, tone adapts to context

Your product's voice (personality) stays the same everywhere. Tone (emotional register) shifts based on what the user is experiencing:

Context Tone direction Why
Error / failure → Serious, direct User is frustrated, not entertained
Destructive action → Serious, careful Consequences are real
Success → Brief, confident Confirm and get out of the way
Empty state → Supportive, guiding User needs direction
Onboarding → Warm, encouraging Most room for personality
Loading / waiting → Calm, informative Reduce anxiety

Source: Apple HIG ("voice is constant; tone adapts"), Microsoft, Atlassian

7. One entity = one term

If you call it "project" in the sidebar, don't call it "workspace" in the settings page and "space" in the empty state. Pick one term per concept and use it everywhere.

Source: Kinneret Yifrah, Microsoft ("use one word for a concept consistently; avoid synonyms for the same feature")

8. Read it aloud

If it sounds unnatural spoken, rewrite it. This catches robotic phrasing, excessive formality, and awkward constructions faster than any other method.

Source: Apple HIG, Microsoft, Shopify Polaris ("Read it out loud. Does it sound like something a human would say? Ship it.")

Anti-Patterns Checklist

When reviewing UI code, watch for these copy problems:

  • "Submit" buttons — replace with specific action: "Create account", "Send message", "Save changes"
  • "Click here" links — replace with descriptive text: "View pricing", "Read the docs"
  • "Are you sure?" dialogs — replace with specific consequence: "Delete 3 projects?"
  • Yes/No/OK buttons on dialogs — replace with action labels: "Delete" / "Keep", "Send" / "Cancel"
  • "An error occurred" — replace with what happened and what to do about it
  • "Invalid [field]" — replace with what's actually wrong: "Email needs an @ symbol"
  • "No data" empty states — replace with what goes here and how to add it
  • "Please" in instructions — usually unnecessary: "Enter your email" not "Please enter your email"
  • "Loading..." without context — say what's loading: "Loading your dashboard..."
  • Mixed terminology — same concept called different names in different places
  • Passive voice in actions — "Your password has been reset" → "You reset your password"
  • Humor in error states — stales on repetition, frustrates stuck users
  • ALL CAPS text — harder to read, signals shouting
  • Jargon or internal terms — "token expired" → "Your session ended. Log in again."
  • Vague success messages — "Success!" → "Payment sent" (name what succeeded)
  • Long paragraphs in UI — break into bullets, shorten sentences, let whitespace work

When Reviewing Code

Run this checklist on any component with user-facing text:

  • Every button label starts with a verb and names the specific action
  • Error messages explain what went wrong AND what to do about it
  • Empty states explain what belongs here AND offer a CTA to get started
  • Confirmation dialogs name the destructive action in the button label (not "OK")
  • The same concept uses the same term everywhere (check nav, headings, buttons, empty states)
  • Placeholder text shows format or example, not the label ("name@company.com" not "Enter email")
  • Toast messages are 2-5 words for success, 1 sentence with next step for errors
  • No instances of "invalid", "illegal", "incorrect", "click here", "submit", or "are you sure"
  • Sentences under 25 words, paragraphs under 3 sentences in UI text
  • Copy reads naturally when spoken aloud
  • Tone matches context (serious for errors, flexible for onboarding, brief for success)
  • No hardcoded strings that should be in content constants or i18n files
Weekly Installs
1
First Seen
9 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
warp1