Every word in an interface is a design decision. Button labels, error messages, empty states, onboarding steps — they all teach the user how the product works. Generic copy teaches nothing.
The Principles
- Clear over clever. "Submit" is clearer than "Let's go." "Save changes" is clearer than "Done." Users scan — they don't read. Make the scan work.
- Action-oriented. Start with the verb. "Create project" not "Project creation." "Delete account" not "Account deletion."
- Specific over vague. "Your file report.pdf is too large (max 10MB)" beats "File too large." "Enter your work email" beats "Enter email."
- One idea per message. Error messages explain ONE problem and ONE fix. Not three possible causes.
- Match the tone to the context. Error messages: empathetic, solution-focused. Empty states: encouraging, action-oriented. Success: brief, celebratory (but not over-the-top).
Button Labels
The Rule
The button label should complete the sentence "I want to ___"
| Button | User thinks |
|---|---|
| Save changes | I want to save changes ✓ |
| Continue | I want to continue ✓ |
| Create project | I want to create project ✓ |
| Submit | I want to submit... what? ✗ |
| Click here | I want to click here... why? ✗ |
| OK | I want to OK... what does this do? ✗ |
Primary vs. Secondary
- Primary button: the main action. Use a specific verb: "Create project", "Save changes", "Send invitation".
- Secondary button: the alternative. "Cancel", "Discard", "Go back".
- Danger button: destructive action. "Delete project", "Remove member". Always red/warning colored.
Never Use
- "Submit" (what am I submitting?)
- "Click here" (where does it go?)
- "OK" / "Confirm" (what am I confirming?)
- "Learn more" (about what? Link to what?)
Instead: "Create account", "Download report", "View pricing", "Read the guide".
Error Messages
The Formula
[What went wrong] + [Why, if useful] + [What to do next]
| Bad | Good |
|---|---|
| Error 404 | Page not found. Check the URL or go back to the homepage. |
| Invalid input | Email address is missing an @ symbol. Use format: name@example.com |
| Something went wrong | We couldn't save your changes. Check your connection and try again. |
| Payment failed | Your card was declined. Update your payment method or try a different card. |
Rules
- Never blame the user. "You entered the wrong password" → "Incorrect password. Try again or reset it."
- Never show raw error codes without human explanation. "Error 500" means nothing to users.
- Never leave the user stuck. Every error message must suggest a next action.
- Be specific about what failed. "Couldn't upload avatar.jpg" beats "Upload failed."
- Keep it short. One sentence for the problem, one for the fix. Max.
Empty States
Empty states are the first thing new users see. They should teach, not just inform.
The Formula
[What goes here] + [Why it's empty] + [What to do about it]
| Context | Bad | Good |
|---|---|---|
| No projects | No projects yet. | You don't have any projects yet. Create your first project to get started. [Create project] |
| No search results | No results. | No projects match "quarterly." Try a different search or browse all projects. |
| No notifications | Nothing here. | You're all caught up! New notifications will appear here. |
| No messages | No messages. | Start a conversation with your team. [New message] |
Rules
- Always include a call-to-action if there's something the user can do.
- Use the empty state to teach what the feature does.
- Keep the tone encouraging — empty states shouldn't feel like failures.
- Show an illustration or icon to make the state feel intentional, not broken.
Form Validation
Inline Validation
Validate on blur (when user leaves the field), not on every keystroke. Keystroke validation feels like being watched.
| Field | Bad | Good |
|---|---|---|
| Email (invalid) | Invalid email | Enter a valid email address, like name@example.com |
| Password (weak) | Weak password | Use at least 8 characters with one number and one uppercase letter |
| Required (empty) | This field is required | Enter your full name |
| URL (invalid) | Invalid URL | Enter a valid URL, like https://example.com |
Success States
After form submission:
- Inline: "Saved" or a checkmark next to the field.
- Page-level: "Your changes have been saved" toast or banner.
- Redirect: "Project created! Here's your new project." with a link.
Onboarding
The Progressive Disclosure Pattern
Don't explain everything upfront. Teach one concept at a time, in context.
- Welcome screen: one sentence about what the product does. One CTA.
- First action: guide the user to their first success (create a project, invite a teammate).
- Contextual tips: show tips when the user reaches the relevant feature, not before.
- Checklist: for complex products, a progress checklist ("3 of 5 steps complete") motivates completion.
Onboarding Copy Rules
- Max 3 sentences per step. If it takes more, the step is too complex.
- Show, don't tell. A screenshot or animation beats a paragraph.
- Let users skip. "Skip tutorial" should always be visible.
- Celebrate completion. "You're all set! Here's what to do next." with clear next steps.
Notifications & Toasts
| Type | Duration | Tone | Example |
|---|---|---|---|
| Success | 3–5s | Brief, positive | "Project created" |
| Info | 5s | Neutral | "3 new comments on your post" |
| Warning | Until dismissed | Cautionary | "Your trial ends in 3 days" |
| Error | Until dismissed | Empathetic + actionable | "Couldn't save. Check your connection." |
Rules
- Don't stack more than 3 toasts. If there are more, group them: "5 new notifications."
- Success toasts auto-dismiss. Error and warning toasts stay until the user acts.
- Include an undo option for destructive actions: "Project deleted. Undo"
Voice & Tone
The Four Dimensions
| Dimension | Range | Example |
|---|---|---|
| Formal ↔ Casual | "We apologize for the inconvenience" ↔ "Oops, something went wrong" | |
| Serious ↔ Playful | "Your data has been securely encrypted" ↔ "Your secrets are safe with us 🔒" | |
| Authoritative ↔ Collaborative | "Update required" ↔ "Let's update your settings" | |
| Enthusiastic ↔ Restrained | "Amazing! You did it! 🎉" ↔ "Changes saved." |
Rules
- Pick a lane and stay in it. Don't mix formal error messages with playful empty states.
- Match the stakes. Error messages should be more serious than success messages.
- Cultural sensitivity matters. Humor doesn't translate. When in doubt, be restrained.
- The product's audience determines tone. A banking app is more formal than a game.
Localization Considerations
- Don't concatenate strings. "Delete " + project_name + "?" breaks in languages with different word order. Use interpolation: "Delete {name}?"
- Allow for text expansion. German text is typically 30% longer than English. Design buttons and labels to accommodate.
- Date and number formats vary by locale. Use
Intl.DateTimeFormatandIntl.NumberFormat. - Pluralization is complex. "1 item" / "2 items" works in English but not in Arabic (which has 6 plural forms). Use
Intl.PluralRules.
Anti-Patterns
- "Are you sure you want to ___?" in confirmation dialogs. The buttons should make the action clear: "Delete project" / "Cancel" — not "Yes" / "No."
- Jargon in user-facing copy. "Authentication failed" → "Incorrect password."
- Passive voice. "The file was deleted" → "We deleted the file" or "File deleted."
- Double negatives. "Don't not save" → "Discard changes?"
- Emoji in error messages (unless the product tone is explicitly playful).
- Exclamation marks everywhere. One per page max. Not every success is "Amazing!"
- Lorem ipsum in production. Write real microcopy — it teaches the user and documents the design.