Skip to content

DOMAIN:CREATIVE — UX WRITING & MICROCOPY

OWNER: rick ALSO_USED_BY: jouke (Content), dinand (Content), floris (Frontend Alpha), floor (Frontend Beta), dima (Intake) UPDATED: 2026-03-28 PREREQUISITE: brand-voice.md (voice and tone framework applies to all microcopy)


PRINCIPLE: CLARITY OVER CLEVERNESS

RULE: every piece of interface text exists to help the user accomplish a task. If clever wording slows comprehension by even one second, replace it with plain language.

RULE: UX copy is not marketing copy. Marketing attracts. UX copy guides. The goals are different and the writing must reflect that.

RULE: read every string aloud. If a non-technical person cannot understand it instantly, rewrite it.

MENTAL_MODEL: UX writing is industrial design with words. Every word is a component. If a component does not serve the user's task, remove it.


UX_WRITING:ERROR_MESSAGES

RULE: every error message answers THREE questions. 1. What happened? (specific, not vague) 2. Why did it happen? (cause the user can understand) 3. What do I do next? (actionable recovery step)

Error Message Template

[What happened]. [Why / cause]. [How to fix].

EXAMPLE (good): "Your password must be at least 8 characters. You entered 5. Add 3 more characters to continue." EXAMPLE (bad): "Invalid password." EXAMPLE (good): "We could not save your changes because your session expired. Sign in again to continue." EXAMPLE (bad): "Error 403." EXAMPLE (good): "This file is too large to upload. The maximum size is 10 MB. Compress the file or choose a smaller one." EXAMPLE (bad): "Upload failed."

Error Message Rules

RULE: never blame the user — "That email address is not valid" not "You entered an invalid email" RULE: never use technical jargon in the UI — no "500 Internal Server Error", no stack traces RULE: never use ALL CAPS for errors — it reads as shouting RULE: use sentence case for error text RULE: keep inline validation errors under 2 sentences RULE: for complex errors, offer a "Learn more" link to documentation RULE: include an error code for support reference — "Contact support with code E-4012 if this continues" RULE: error messages MUST be translatable — no string concatenation, no interpolated grammar

Error Severity Tone Map

Severity Tone Opener Pattern Example
Validation Helpful, immediate "Enter a valid..." "Enter a valid email address."
Warning Cautious, informative "This will..." "This will replace your current file."
Blocking Empathetic, solution-focused "We could not... Try..." "We could not process your payment. Try a different card."
System error Calm, reassuring "Something is not working..." "Something is not working. We are looking into it."
Destructive Serious, confirming "This permanently..." "This permanently deletes your account. This cannot be undone."

ANTI_PATTERN: "Something went wrong" with no context FIX: specific message + error code + recovery action

ANTI_PATTERN: "Oops!" or cutesy language on serious errors (payment failure, data loss) FIX: match tone to severity — humor is never appropriate for money, data, or security

ANTI_PATTERN: error message that differs between web and mobile for the same condition FIX: single source of truth for copy — i18n JSON file, not hardcoded strings

ANTI_PATTERN: showing raw API error responses to the user FIX: map every API error code to a human-readable message in a central error copy file


UX_WRITING:EMPTY_STATES

RULE: every empty state has THREE elements. 1. Visual — illustration or icon (not just text) 2. Explanation — what this area will contain once populated 3. Call to action — how to populate it

Empty State Types

First-use (onboarding) - Tone: encouraging, value-focused - EXAMPLE: "No projects yet. Create your first project to start building." - RULE: show the benefit, not the feature name - RULE: use a primary action button, not just a text link

No results (search/filter) - Tone: helpful, suggestive - EXAMPLE: "No results for 'xyz'. Try a different search term or remove filters." - RULE: suggest next actions — broaden search, clear filters, check spelling - RULE: never show a completely blank area — always provide guidance

User-cleared (all items completed or deleted) - Tone: celebratory or neutral depending on context - EXAMPLE: "All caught up. No new notifications." - RULE: acknowledge the achievement when appropriate

Error state (failed to load) - Tone: honest, recoverable - EXAMPLE: "Could not load your projects. Check your connection and try again." - RULE: always provide a retry button

Permission denied - Tone: informative, non-judgmental - EXAMPLE: "You do not have access to this workspace. Ask your admin for an invitation." - RULE: tell them WHO can help and HOW

ANTI_PATTERN: blank white screen with no explanation FIX: every container component has a corresponding empty state design

ANTI_PATTERN: empty state that says "No data" with no further guidance FIX: explain what data will appear AND how to create it


UX_WRITING:ONBOARDING_FLOWS

RULE: progressive disclosure — show only what is needed at each step RULE: lead with value — "Set up your workspace to start collaborating" not "Step 1 of 5" RULE: show progress — step indicator or progress bar RULE: allow skip where possible — "Skip for now, set up later" RULE: explain WHY you need information — "We use your timezone to schedule notifications correctly" RULE: max 3-5 essential steps; defer everything else to contextual discovery

Onboarding Copy Patterns

Step Type Copy Pattern Example
Welcome Greeting + value prop "Welcome to [App]. Let us get you set up in 2 minutes."
Data collection Why + what "Add your company name. This appears on all invoices."
Feature intro Benefit + action "Invite your team to start collaborating in real time."
Completion Achievement + next step "You are all set. Here is your dashboard."

Progressive Disclosure Principles

  1. First run: Show the 1-2 things the user MUST do to get value.
  2. Day 1-3: Surface features contextually as the user encounters them.
  3. Week 1+: Tooltips for advanced features only when the user approaches them.
  4. Never: Dump all features at once in a tour nobody asked for.

ANTI_PATTERN: 10-step onboarding with no skip option FIX: max 3-5 essential steps; everything else is deferred contextual guidance

ANTI_PATTERN: "Welcome to [App]! [App] is a platform that..." (feature-first) FIX: "Welcome to [App]. [What you can achieve]." (value-first)

ANTI_PATTERN: tooltip tour that fires automatically and blocks the interface FIX: user-initiated guidance ("Show me around" link) or contextual tips tied to first-time actions


UX_WRITING:BUTTONS_AND_CTAS

RULE: button labels use verb + object format — "Create project", "Send invoice", "Download report" RULE: never use generic labels — not "Submit", not "OK", not "Click here" RULE: destructive actions use specific labels — "Delete project" not "Delete" RULE: primary action is specific, secondary is generic — "Save changes" / "Cancel" RULE: button text is max 3-4 words RULE: use sentence case for buttons (not Title Case, not ALL CAPS)

Confirmation Dialogs

RULE: dialog title states the action — "Delete this project?" RULE: dialog body states consequences — "This permanently deletes the project and all its data." RULE: confirm button repeats the action verb — "Delete project" (not "Yes" or "OK") RULE: cancel button says "Cancel" or the safe alternative — "Keep project" (not "No")

Pattern Good Bad
Save "Save changes" "Submit"
Delete "Delete project" "OK"
Navigate "Go to dashboard" "Click here"
Create "Create account" "Next"
Send "Send message" "Done"
Confirm "Place order" "Confirm"
Cancel "Discard changes" "No"
Upgrade "Upgrade to Pro" "Learn more"

ANTI_PATTERN: "Are you sure?" dialogs with "Yes" / "No" buttons FIX: title = action question, buttons = specific action / "Cancel"

ANTI_PATTERN: CTA that says "Get started" on every page regardless of context FIX: CTA that matches the specific action — "Create your first project", "Import your data"


UX_WRITING:LOADING_STATES

RULE: if a loading state lasts more than 2 seconds, show a message. RULE: messages should set expectations — "Loading your projects..." is better than a spinner alone. RULE: for long operations (>5 seconds), show progress or explain what is happening. RULE: avoid "Please wait" — it adds no information.

Loading Copy Patterns

Duration Pattern Example
<2 seconds Skeleton / spinner only No text needed
2-5 seconds Action description "Loading your dashboard..."
5-15 seconds Action + context "Generating your report. This usually takes about 10 seconds."
15+ seconds Action + progress + option "Processing 2,450 records (67% complete). You can close this page — we will email you when it is done."
Background Notification pattern "Your export is being prepared. We will notify you when it is ready."

ANTI_PATTERN: "Loading..." with no indication of what is loading FIX: name the thing being loaded — "Loading invoices..." or "Preparing your report..."

ANTI_PATTERN: spinner that runs indefinitely with no timeout message FIX: after 30 seconds, show "This is taking longer than expected. Try refreshing the page."


UX_WRITING:SUCCESS_AND_CONFIRMATION

RULE: confirm what happened, not just that something happened. RULE: include the next logical action. RULE: success messages should be brief — the user wants to move on.

Success Copy Patterns

Action Good Bad
Save "Changes saved." "Success!"
Send "Invoice sent to anna@example.com." "Done."
Delete "Project deleted." "Item removed successfully."
Create "Account created. Check your email to verify." "Registration complete."
Upload "3 files uploaded." "Upload successful."
Payment "Payment of EUR 49.00 received. Receipt sent to your email." "Thank you for your purchase!"

RULE: for destructive actions, confirm what was destroyed and note irreversibility. RULE: for email-dependent flows, tell them WHERE to look: "Check your inbox at j***@example.com" RULE: include undo option where technically possible: "Message archived. Undo."

ANTI_PATTERN: "Success!" toast with no detail FIX: "[What happened] + [what to do next or what to expect]"

ANTI_PATTERN: success message that disappears after 2 seconds before user can read it FIX: auto-dismiss after 5-8 seconds, or make it dismissible but persistent


UX_WRITING:TOOLTIPS_AND_HELPER_TEXT

RULE: tooltips supplement — they never replace visible labels or help text. RULE: helper text appears below the field, always visible. RULE: tooltips appear on hover/focus, for secondary information only. RULE: max tooltip length: 1-2 short sentences.

When to Use What

Use When
Visible helper text The information is needed to complete the field correctly
Tooltip The information is helpful but not essential
Inline link ("Learn more") The explanation requires more than 2 sentences
Neither The label is self-explanatory

Helper Text Rules

RULE: explain constraints before the user hits them — "Max 50 characters" not after they exceed it. RULE: explain WHY when the reason is not obvious — "This appears on your public profile" RULE: use placeholder text for FORMAT hints only — "DD/MM/YYYY", "name@example.com" RULE: placeholders are NOT labels — they disappear on focus

ANTI_PATTERN: hiding critical information inside a tooltip that mobile users cannot hover over FIX: if the information is critical, it is visible helper text, not a tooltip

ANTI_PATTERN: tooltip that repeats the label — hovering over "Email" shows "Enter your email" FIX: tooltip should add NEW information — "We will send your receipt to this address"


UX_WRITING:NOTIFICATION_COPY

Tone Per Channel

Channel Tone Length Urgency
Push notification Brief, actionable <50 chars title, <100 body High — interrupts user
In-app notification Informative, contextual 1-2 sentences Medium
Email Complete, professional Full paragraphs acceptable Low — async
SMS Ultra-brief, urgent <160 chars Highest — reserved for critical

RULE: push notifications state the event + action — "New comment on your project. View now." RULE: never use push for marketing — only transactional/actionable content RULE: in-app notifications are dismissible and have timestamps RULE: email subject lines are specific — "Invoice #1234 is ready" not "Update from [App]"

ANTI_PATTERN: push notification that says "You have a new notification" FIX: state WHAT happened — "Alex commented on your design"

ANTI_PATTERN: notification that provides no way to act on it FIX: every notification links to the relevant screen/action


UX_WRITING:CHARACTER_LIMITS_AND_CONSTRAINTS

Common Platform Limits

Element Recommended Max Hard Limit Notes
Page title 60 chars 70 chars (SEO) Front-load keywords
Meta description 155 chars 160 chars Include CTA
Button label 3-4 words ~25 chars Verb + object
Toast/snackbar 1-2 sentences ~80 chars Must be readable in 5 seconds
Tooltip 1-2 sentences ~150 chars Essential info only
Push title 40 chars 50 chars (iOS) Name the event
Push body 80 chars 178 chars (Android) Include action
Form label 2-4 words Noun or noun phrase
Helper text 1 sentence ~80 chars Constraint or explanation
Error message 1-2 sentences ~120 chars inline What + why + fix
Email subject 40 chars 60 chars (mobile cutoff) Specific, not clever
Email preview text 40-90 chars ~100 chars Extends subject line

RULE: write to the recommended max, not the hard limit. Shorter is almost always better. RULE: test on the smallest screen your users have. If it wraps awkwardly, trim it. RULE: never truncate mid-word. If space is tight, rewrite shorter.


DESIGN SYSTEM WRITING REFERENCES

Google Material Design Writing Guidelines

SOURCE: m3.material.io/foundations/content-design and m2.material.io/design/communication/writing.html

KEY PRINCIPLES: - Concise: short, scannable segments focused on a limited number of ideas - Clear: simple, direct language that is immediately understandable - Useful: text that helps the user complete their task - Address the user as "you" (second person). Use "I" / "my" only for user-owned content. - Sentence-style capitalization for titles, headings, labels, menu items - Skip unnecessary punctuation — periods in labels, colons after headers - Follow AP style for general language conventions

Shopify Polaris Content Guidelines

SOURCE: polaris.shopify.com

KEY PRINCIPLES: - Concise (Jenga test): what is the most you can remove before it breaks? - Actionable: start with verbs. "Add apps" not "You can add apps." - Direct: say it plainly. No hedging, no padding. - Human: read it aloud. Does it sound like something a person would say? - Merchant-first: put the user at the center and in control - Polaris provides per-component content guidelines (button text, banner copy, modal copy, etc.) - Each component doc includes "Best Practices" and "Content guidelines" sections

NN/g Four Dimensions of Tone

SOURCE: Nielsen Norman Group

Every piece of copy sits on four spectrums: 1. Funny <-> Serious — how much humor is appropriate 2. Casual <-> Formal — register and vocabulary level 3. Irreverent <-> Respectful — attitude toward conventions 4. Enthusiastic <-> Matter-of-fact — energy level

RULE: define the brand's position on each dimension and document it in the voice guide. RULE: map tone shifts per scenario type (see brand-voice.md for the full framework).


UX_WRITING:ACCESSIBILITY

STANDARD: WCAG 2.1 Level AA

RULE: write at 8th-grade reading level (Flesch-Kincaid Grade Level 8 or below) RULE: avoid idioms, metaphors, and culturally-specific references RULE: use plain language — "use" not "utilize", "start" not "commence", "buy" not "purchase" RULE: front-load important information in every sentence RULE: link text describes destination — "View billing settings" not "Click here" RULE: alt text for images describes function, not decoration RULE: screen readers read button labels — make them self-explanatory without visual context RULE: never convey meaning through color alone — always include text RULE: aria-label on icon-only buttons RULE: avoid directional language — "the button below" fails for screen readers, say "the Save button"

TOOL: Hemingway Editor — readability scoring TOOL: axe DevTools — automated accessibility testing TOOL: VoiceOver (macOS/iOS) / NVDA (Windows) — screen reader testing RUN: test every new screen with a screen reader before shipping

ANTI_PATTERN: "Click the red button" (relies on color + mouse interaction) FIX: "Select 'Delete project'" (relies on label)

ANTI_PATTERN: placeholder-only form fields (no visible label) FIX: always pair visible label with input — placeholder is supplementary

ANTI_PATTERN: "click here" or "learn more" as standalone link text FIX: "Read the pricing guide" or "View your account settings"


UX WRITING CHECKLIST (per screen)

  • [ ] Every button uses verb + object format
  • [ ] Every error message answers what / why / how-to-fix
  • [ ] Every empty state has visual + explanation + CTA
  • [ ] No placeholder-only form fields
  • [ ] No jargon, no technical codes in user-facing text
  • [ ] All copy tested at 8th-grade reading level
  • [ ] All strings are in i18n files, not hardcoded
  • [ ] Tested with screen reader (VoiceOver or NVDA)
  • [ ] Tone matches severity (no humor on errors involving money/data)
  • [ ] Character limits respected for all constrained contexts

REFERENCES

  • Google Material Design 3 — Content Design: m3.material.io/foundations/content-design/overview
  • Google Material Design 2 — Writing: m2.material.io/design/communication/writing.html
  • Shopify Polaris — Content: polaris.shopify.com/content
  • Kinneret Yifrah. Microcopy: The Complete Guide. 2017.
  • Torrey Podmajersky. Strategic Writing for UX. O'Reilly, 2019.
  • Nielsen Norman Group. "The Four Dimensions of Tone of Voice." nngroup.com.
  • Scott Kubie. Writing for Designers. A Book Apart, 2018.