Content design
Words are the part of DrumKit you ship most often and review least. This is the standard for every string in the product: labels, buttons, hints, errors, empty states, headings, and anything else a person reads.
Principles
Four positions that govern every string in the product.
Say the thing
Write the next action, not the current state
One idea per string
Never make someone feel stupid for an error
The defaults
Five rules cover most strings. When nothing else on this page applies, these decide.
Sentence case, no stray periods
Buttons are verb + object
Labels are nouns
Errors say what happened and what to do next
One word per concept
Voice
DrumKit sounds like a competent colleague who respects your time. Voice is constant: it doesn’t change between a success toast and a billing failure.
We are | We’re not |
|---|---|
| Direct | Blunt or cold |
| Plain | Simplistic or condescending |
| Warm | Chatty, jokey, or exclamatory |
| Confident | Hedging or over-qualified |
Three tests, in order:
- Read it aloud. If you wouldn’t say it to someone standing next to you, rewrite it.
- Cut a third. Almost every first draft survives it.
- Check the subject. Write what the person does, not what the system does to them.
Tone
Tone flexes with the person’s situation; voice doesn’t. The rule underneath every row: the higher the stakes, the flatter the tone.
First run, onboarding · encouraging, brief
Do
“Add your first item to get started.”
Don’t
“Welcome aboard! We’re so excited to have you! 🎉”
Routine task · neutral, invisible
Do
“Save changes”
Don’t
“Let’s save those changes!”
Success · understated
Do
“Changes saved”
Don’t
“Awesome! You did it!”
Recoverable error · calm, specific
Do
“That file is too large. Choose a file under 10 MB.”
Don’t
“Oops! Something went wrong.”
Destructive action · plain and unhurried
Do
“Delete this permanently? This can’t be undone.”
Don’t
“Are you sure? This is scary!”
System failure · honest, no blame-shifting
Do
“We couldn’t save your changes. Try again in a moment.”
Don’t
“An unexpected error occurred (code 500).”
Billing or legal · precise; unfriendly is fine
Do
“Your plan renews on the date shown.”
Don’t
Anything cute
Mechanics
Capitalization, punctuation, numbers, dates: the small rules that keep every string consistent.
Capitalization
Sentence case everywhere
Do
Don’t
Buttons, labels, headings, menu items, table headers, badges, tabs, tooltips, empty-state titles.
Proper nouns only
Do
“Check your invoices in the dashboard”
Don’t
“Check your Invoices in the Dashboard”
A feature you built is not a proper noun just because you’re proud of it.
Punctuation
No periods on UI strings
Do
Don’t
Labels, buttons, headings, tooltips, badges, table headers, single-sentence hints. Periods belong in multi-sentence body copy.
No exclamation marks
Do
Changes saved
Your edits are stored automatically.
Don’t
Changes saved!
Your edits are stored automatically.
One per product, and you probably don’t need that one.
Serial comma
Do
“Name, email, and phone”
Don’t
“Name, email and phone”
Always, in any list of three or more.
No em dashes
Do
“Autosave is on: edits save as you type”
Don’t
“Autosave is on — edits save as you type”
Anywhere in the product. Use a comma, a colon, or two sentences. En dashes in numeric ranges stay.
Ampersands only under space pressure
Do
Spacing & radius
Don’t
“Fast & easy” in body copy
Otherwise “and”. A nav label can earn one; prose never does.
Quotes: curly in prose, straight in code
Do
“You’re all set”
Don’t
“smart” quotes in code
Curly quotes and apostrophes in what people read; straight quotes in code, where curly ones break strings.
Numbers
Numerals everywhere in UI
Do
“3 items”
Don’t
“three items”
Digits scan; words don’t.
Sentences don’t start with a numeral
Do
“You have 3 overdue invoices.”
Don’t
“3 invoices are overdue.”
Spell it out, or rewrite so it isn’t the start.
Ranges use “to” in prose, an en dash in UI
Do
“1–20 of 143”
Don’t
“1 - 20 of 143”
No spaces around the en dash. Never a hyphen.
Formatting comes from the locale
Do
10,000 · en-US
10.000 · de-DE
Don’t
“10,000” hardcoded in a string
React Aria formats through Intl.NumberFormat. A hardcoded separator is wrong somewhere.
Dates and times
Pass the value, not a string
Do
Don’t
month + “/” + day, by hand
Hand a date value to the component; React Aria formats and parses it per locale.
Sentences compose formatter output
Do
“Renews on 15 Jan 2026”
Don’t
A date built by string concatenation
The sentence wraps the formatter, never replaces it.
Example dates use a day above 12
Do
“15 Jan 2026”
Don’t
“03/04/2026”
In copy examples and design files, the day should never be mistakable for the month.
Contractions
Use contractions
Do
“can’t”, “won’t”, “you’re”
Don’t
“cannot”, “will not” in ordinary UI copy
They read as human. The exception is where ambiguity costs money: in billing and legal copy, spell it out.
Second person
Address the person as “you”
Do
“We couldn’t reach the server”
Don’t
“I couldn’t save your changes”
“We” only when the system genuinely acts on their behalf. Never “I”.
Links
Link the words that describe the destination
Do
See the word list for approved terms
Don’t
Click here to see the word list
Never a bare URL, and never link a trailing period.
Layout constraints
Write to the measure
Do
Don’t
Body copy is capped at a 720px paragraph measure, roughly 75 characters per line.
Front-load truncatable strings
Do
Invoice overdue: Acme Co.
Don’t
Acme Co. has an invoice that is overdue
Truncated strings lose their ends. If the full string matters, give it a tooltip or an expanded view.
Keep headings under about eight words
Do
“Invite your team”
Don’t
“Everything you need to know about inviting your team members”
Balanced wrapping improves ragging but doesn’t rescue a bad heading.
Never write copy that depends on position
Do
“Select Save changes to finish”
Don’t
“Click the button below to finish”
“The button below” breaks on mobile, in RTL, and for screen readers. Name the thing.
The React Aria contract
React Aria implements semantics and keyboard behavior per the W3C ARIA Authoring Practices Guide, and its components are tested against real screen readers. That testing only helps if we give it text to work with. Each rule below is an API requirement, not a preference: breaking it produces a component that is silently broken for assistive tech.
Every field needs a real Label. Placeholder text is not a label: it disappears on focus and is never the accessible name. Where there is no room, aria-label is the fallback and a design smell.
Hint text and error text are different slots. The description slot is persistent guidance; FieldError appears on failure. Don’t repeat the hint inside the error.
Icon-only buttons need an aria-label. Write the action, not the icon: aria-label="Clear", not aria-label="X icon".
List items with rich children need textValue. When a row holds an avatar plus a name plus a badge, supply the plain-text string for announcement and typeahead.
Dialogs need a heading. The dialog title is the accessible name.
Sliders need an output string. The visible value is the accessible value. Include the unit.
Write the announcement, not just the visual. Toasts and live status changes are read in full. “Upload failed” works without the icon; “Failed” does not.
Alt text describes function, not appearance. Decorative images get empty alt. An image inside a link or button describes where it goes.
Component content specs
Every DrumKit component that holds text, and the rules for its slots. Examples are product-neutral.
Buttons
Name the outcome, not the mechanism
Do
Don’t
Verb + object, 1 to 3 words, sentence case, no period. Destructive buttons name the destruction: “Delete project”, not “OK”. A person reading only the buttons should still know what happens, so never “Yes” and “No”.
Inputs
Slot | Rule |
|---|---|
| Label | Noun. Sentence case. No colon, no period. |
| Hint | Persistent. One sentence. Only if it prevents an error. |
| Placeholder | Format examples only. Often better empty. |
| Error | What’s wrong plus how to fix. |
A visible label; a hint that earns its place
Do
Don’t
A hint that restates the label is noise; delete it. Placeholder text is not a label: it disappears on focus and is never the accessible name.
Select, ComboBox, multi-select
Part | Rule |
|---|---|
| Options | Sentence case, parallel in structure. |
| Sort order | Meaningful. Alphabetical only as a last resort. |
| Trigger empty state | Names the thing: “Select a status”. |
| Rich rows | Avatar or badge in the row: supply a plain-text textValue. |
Checkboxes, radios, toggles
Label the on state, never a negation
Do
Don’t
Label the on state, never a negation: a checked “Do not send” is a puzzle. Toggles name the thing they switch, so “Email notifications” plus its state rather than “Notifications”. Radio group labels state the question; the options state the answers.
Badges and tags
States, not sentences
Do
Don’t
“Active”, “In progress”, “Didn’t work”
One or two words, sentence case, no punctuation. Closed vocabulary: one word per state, product-wide, from the word list.
Tooltips
Tooltips add, they don’t repeat: use them for the shortcut, the constraint, or the truncated full value. Under 10 words, no period. Never the only place critical information lives, because tooltips don’t exist on touch.
Alerts and banners
Slot | Rule |
|---|---|
| Title | The situation, in one line. No period. |
| Body | What it means and what to do. One or two sentences. |
| Action | Verb + object, matching button rules. |
Match severity to reality
Do
Payment method expired
Update your card to avoid interruption.
Don’t
Error!
Something went wrong with your account.
Match severity to reality. If the person can keep working, it isn’t an error. Reserve the destructive variant for things that lose data or cost money.
Notifications and toasts
One announcement; the undo is a verb
Do
Item deleted
“Q3 forecast” was removed from this project.
Don’t
“Your file upload has finished processing successfully!”
One announcement: past tense for confirmations, present for in-progress. The title is the complete thought, with supporting text only when it adds something. Toasts vanish, so they never hold the only copy of information a person needs, and an undo is a verb.
Empty states
Slot | Rule |
|---|---|
| Title | What’s missing, or what’s possible. Not “No data”. |
| Body | Why it’s empty and what to do about it. |
| Action | The primary next step. |
Add your first client
Clients you invoice will live here.
First use
No results for that search
Try different keywords or clear filters.
No results
We couldn’t load your clients
Try again in a moment.
Error
Modals
Name the decision and its consequences
Do
Delete this project?
All files and history will be removed. This can’t be undone.
Don’t
Are you sure?
Title is a question or a statement, never a bare noun. Body states consequences before asking. Destructive confirmations say what is lost and whether it is recoverable.
Page and section headers
Page titles match the nav label exactly
Do
Don’t
Page titles are nouns and match the navigation label exactly. Two names for one thing is a bug. Supporting text under a header is optional and usually deletable.
Breadcrumbs
Match the destination page titles exactly
Do
Don’t
Match the destination page titles exactly. Never truncate the current page; never invent an intermediate label.
Tables
Headers are sentence-case nouns; units live in the header
Do
Client | Amount (USD) |
|---|---|
| Acme Co. | 1,200 |
| Bolt Ltd. | – |
Don’t
CLIENT NAME: | Amount in dollars ($) |
|---|---|
| Acme Co. | 1,200 dollars |
| Bolt Ltd. | N/A |
Headers are sentence-case nouns, no periods, as short as clarity allows. Units go in the header, not every cell. Empty cells get an en dash, not blank space or “N/A”. Bulk actions state the count: “Delete 3 items”.
Progress steps
Step labels are 1–3 words, parallel
Do
Details
Payment
Review
Don’t
Enter your details
Payment
Review and confirm your order
1 to 3 words, sentence case, parallel across every step.
File uploaders
State the constraint before the failure
Do
PNG or JPG, up to 10 MB
Don’t
“Upload failed. Try another file.” · the limit revealed only after failing
State the constraint before the failure: accepted formats and max size go in the hint, not only in the error. Errors name the actual limit: “That file is 24 MB. The maximum is 10 MB.”
Command menu
Commands are verb-first
Do
Invoices
Create invoice
Send reminder
Export invoices
Don’t
INVOICE ACTIONS:
Invoice creation
Reminder sending
Exports
Commands are verb-first and match the label used elsewhere in the UI. Group headings are sentence-case nouns. Empty state: “No commands match that search.”
Pagination
Name the controls, and keep the name when the label collapses
Do
Don’t
“<< Prev / Fwd >>”
En dash in the range, no period. Name the controls Previous and Next, and keep that name when the label collapses to an icon: the kit's own controls carry aria-label="Previous Page" and "Next Page" at narrow widths.
Error messages
Errors are where content design either earns its keep or embarrasses us. The formula: what happened → why → what to do next. Drop any part that’s genuinely obvious; never drop the third.
Bad | Better |
|---|---|
| “Invalid input” | “Enter a valid email address, like name@example.com” |
| “Error 403” | “You don’t have permission to edit this. Ask an admin.” |
| “Something went wrong” | “We couldn’t save your changes. Try again.” |
| “Field required” | “Enter a project name” |
- Never blame the person. Not “You entered an invalid date” but “Enter a date in the future”.
- Never expose internals. No status codes, stack traces, or table names in user-facing copy.
- Be specific about limits. If there’s a maximum, name it.
- Validate at the right moment. Copy can’t fix an error that fires while someone is still typing.
- Match the error to the field. A form-level “There were errors” forces a hunt. Point at the field.
Word list
One word per concept, product-wide. Add a row every time we catch ourselves using two words for one thing.
Use | Not | Note |
|---|---|---|
| Sign in / Sign out | Log in, Login, Log out | “Login” is a noun; we rarely need the noun |
| Delete | Remove | “Remove” takes something out of a group without destroying it |
| Settings | Preferences, Config, Options | |
| Select | Choose, Pick | |
| Add | Create, New | “Create” only when the thing didn’t exist before |
Words we don’t use: simply, just, easy, obviously, quickly, please, sorry, oops, whoops. They either minimize a person’s difficulty or apologize for our own design.
Inclusive language: No gendered defaults, no ableist metaphors (“blind spot”, “sanity check”, “crazy”), and no “master/slave” or “blacklist/whitelist” anywhere, including code-facing strings.
Checklist
Before merging any string:
- Sentence case, no stray period
- Every field has a real Label
- Every icon-only button has an aria-label
- Rich list items have a textValue
- Dialogs have a heading
- Dates and numbers come from the formatter, not a string literal
- Truncatable strings are front-loaded
- Errors say what to do next
- Terms match the word list
- No em dashes
- Read it aloud, and cut a third
Reference
Related pages.
- DrumKit Accessibility: labeling, announcements, and the assistive-tech contract behind these rules
- DrumKit Interaction: the states this copy describes