Skip to content
ExamsLibraryFor agentsConnect your agent

Words in the interface

beginner·8 min·Markdown for agents

What this lesson teaches

Write labels, errors and status copy that guide, build strings that survive translation, and name components by what they do.

  1. 1The voice rules
  2. 2Errors that guide the exit
  3. 3Status copy stays parallel
  4. 4Labels that do their job
  5. 5Strings that survive translation
  6. 6Naming components by behavior

Set the count to 1. Then to 0. Then switch the locale.

Count1
Glued together"You have " + n + " new messages"You have 1 new messages
One whole ICU message{count, plural, =0 {…} one {…} other {…}}1 new message
MoneyIntl.NumberFormat · currency…
DateIntl.DateTimeFormat · medium…
RelativeIntl.RelativeTimeFormat · auto…
ListIntl.ListFormat · conjunction…

Set the count to 1 or 0 and watch the glued sentence break. The Intl rows follow the locale without one line of formatting code of your own.

The glued sentence breaks at 1 and 0. The ICU message and Intl never do.

"You have 1 new messages" is what you get when a sentence is glued together around a number. It is a small thing, and people notice it every single time. , the small words on buttons, errors, empty states and tooltips, is design. It ships every day, and the wrong word quietly ages the product.

The voice rules

  • Active voice. "Saved your changes" beats "Your changes have been saved".
  • Talk to "you". "You can invite 3 more people", not "Users can…". In errors, "we" sounds like deflection.
  • Specific beats vague. "Couldn't connect to the server" beats "Something went wrong".
  • Skip the throat-clearing. "Saved." beats "Awesome, your changes were saved!".
  • Numerals for counts. "3 projects", even small ones. A non-breaking space keeps "3 MB" together.
  • Real characters. The ellipsis …, curly quotes, an en dash for ranges (5–10).

Pick one capitalization for buttons and headings, Title Case or sentence case, and hold it across the whole product. Mixing them on one screen is the mistake, not either choice.

Don't be cute in errors. "Oops! Something tripped on the wires!" is funny once and annoying the tenth time.

Errors that guide the exit

A good error answers three questions: what went wrong, why (if it helps), and what to do next.

✕ Before

Something went wrong.
Error: 500 Internal Server Error

✓ After

Changes not saved. Check your connection and try again.

Status copy stays parallel

Async states read best as one family: same object, same order.

StatePatternExample
In progress-ing verb + objectSaving changes…
Doneobject + past tense, no "successfully"Changes saved
Failedwhat did not happen + next stepChanges not saved. Check your connection and try again.
Unavailablewhy, beside the controlAdd a payment method to publish
Partialboth counts9 of 12 files uploaded. Retry 3 failed files

Labels that do their job

  • Buttons start with a verb naming the action: "Send", "Save draft", "Delete project". Never "OK" or "Let's go!". An icon button's aria-label follows the same rule.
  • Links name their destination: "Read the billing docs", not "Click here". Two "Learn more" links on one page each get a suffix.
  • Toggles describe the ON state: "Send read receipts", never "Don't send read receipts", which turns the switch into a double negative.
  • Match the device: "tap" on touch, "click" with a mouse, "select" when it could be either.
  • A placeholder is an example, like name@example.com, never the label and never an instruction.

Strings that survive translation

Before writing new copy, find where the existing copy lives (the t( calls and the locales/*.json files) and list the words already in use. If the menu says "Archive", the toast does not say "Move to storage". One thing, one name.

Then build every sentence whole. Word order changes between languages, and many languages have more than two plural forms, so n === 1 ? "" : "s" is wrong outside English. Use one with placeholders:

inbox.count = {count, plural,
  =0 {No new messages}
  one {# new message}
  other {# new messages}
}

And format every number, date and list through with the user's locale:

ValueCall
MoneyIntl.NumberFormat(locale, { style: "currency", currency })
DateIntl.DateTimeFormat(locale, { dateStyle: "medium" })
"Yesterday"Intl.RelativeTimeFormat(locale, { numeric: "auto" })
"Maya, Jon and Ana"Intl.ListFormat(locale, { type: "conjunction" })

toLocaleDateString() with no locale, or a date built from getMonth(), is the bug. Translated strings also grow, a one-word button most of all, so leave room.

Naming components by behavior

Words matter for components too. Some look alike, and picking by looks breaks what users expect. Pick by behavior, not appearance.

PairThe line between them
vs Can it hold a link or button? A tooltip is a hover label and can't; a popover opens on click and can
Badge vs tagA badge is pinned on and read-only (the "3" on an inbox); a tag is standalone and you can select or remove it
Dialog vs sheet vs drawerA dialog interrupts, centre-screen, for a decision now; a sheet slides from an edge; a drawer pulls up from the bottom. Sheets and drawers are for secondary, dismissible surfaces

Three questions settle it: must they interact inside it (popover)? Can they act on it (tag)? Must they decide now (dialog)?

Copy and strings pass· for your agent
Review the copy in this screen:
- Inventory existing nouns and verbs first (t() calls, locales/*.json) and reuse them; one name per thing.
- Buttons start with a verb; links name their destination; toggles describe the ON state; placeholders are examples.
- Errors: what failed + the next step. Status copy parallel: "Saving changes…" → "Changes saved" → "Changes not saved. Check your connection and try again."
- No sentence glued around a variable; plurals through ICU {count, plural, ...}; numbers, dates and lists through Intl with the user's locale.
- Keep one capitalization style for all buttons and headings.

Quick check

A floating box needs to hold a 'Read the docs' link. Which component is it?

What this lesson builds on and leads to, across every course.

  • Words matter
  • Briefs that work
  • Routing the job
  • Every list has four states
  • Copy that sounds generated
  • Real content beats fake proof