fdb/docs

[§] /docs/rules/copy

Copy

Buttons say what they do, errors say how to fix it, and one spelling, one date format and one case style run through the whole product.

TL;DR

  • Buttons start with a verb: "Save changes", not "OK".
  • Errors say what went wrong and how to fix it, next to the field.
  • Every empty state has one clear action.
  • Numbers and dates go through Intl.
  • One spelling (British here), sentence case, short sentences.

Microcopy is interface. The label on a button decides whether people press it, and an error message decides whether they recover or leave. These conventions keep copy short, specific and consistent, so the words stop being the thing people notice.

Buttons and links: table (6 rows)
DoDon'tRule
Save changesOKVerb plus object.
Delete projectYesThe confirm button repeats the action.
Create accountSubmitSay what happens, not what the form does.
Rename…RenameAn ellipsis (…) means "asks for more input first".
Saving…LoadingName the action in progress.
Read the media rulesClick hereLink text makes sense on its own.
  • MUST start every button label with a verb.
  • MUST use the same verb on the trigger, the dialog title and the confirm button: "Delete project?" then "Delete project".
  • MUST label the escape route "Cancel", and make it do nothing destructive.
  • SHOULD keep button labels to 1 to 3 words.
  • SHOULD use the single ellipsis character …, not three full stops.
  • MUST NOT use "Yes" and "No" as dialog buttons. People skim the question.

Sentence case

Use sentence case everywhere: page titles, headings, buttons, menu items, tabs. Capitalise only the first word and proper nouns. Material and Apple's HIG both use sentence case for most UI text; pick it and apply it everywhere.

Sentence case: table (3 rows)
DoDon't
Create new projectCreate New Project
Sign in with GitHubSign In With Github
Rules & conventionsRules & Conventions
  • MUST keep product names and brands in their own casing: GitHub, iPhone, Next.js.
  • MUST NOT set whole labels in capitals in the source text. If a label should look uppercase, use text-transform: uppercase so screen readers do not spell it out.

Error messages

  1. [01]

    What happened

    in plain words, no codes first

  2. [02]

    Why

    only if it helps them act

  3. [03]

    How to fix it

    one concrete next step

The error formula. The fix is the part people need, so it is never optional.

✕ vague

Error 422: Invalid input.

✓ specific

That email is already registered. Sign in instead, or use a different address.

Same failure, two messages. The second one says what went wrong and what to do next, beside the field that caused it.
Error messages: table (6 rows)
SituationMessage
Empty required fieldEnter your email address
Wrong formatEnter an email address like name@example.com
Too longProject name must be 40 characters or fewer
Network failureCould not save. Check your connection and try again.
PermissionOnly owners can delete projects. Ask an owner to do it.
Unknown server errorSomething went wrong on our side. Try again in a minute.
  • MUST show the error next to the field that caused it, and repeat a summary at the top for long forms.
  • MUST keep what the user typed. Never clear a form because one field failed.
  • MUST NOT blame the user ("You entered an invalid…") or joke about failures.
  • MUST NOT lead with a code. If support needs one, put it last: "…try again. (Ref: 8F2A)".
  • SHOULD validate on blur or submit, not on every keystroke.

Empty states

An empty state is the first screen many people see. Treat it as onboarding, not as an absence.

Empty states: table (3 rows)
PartExample
What this place isNo projects yet
Why it is empty, or what goes hereProjects hold your pages, tokens and assets.
One actionCreate project
  • MUST give every list, table and search a designed empty state.
  • MUST offer exactly one primary action. A second one can be a text link.
  • SHOULD make "no results" different from "nothing yet": "No projects match 'riso'. Clear the filter."

Numbers, dates and units

const gb = 'en-GB';

new Intl.NumberFormat(gb).format(12500);                // "12,500"
new Intl.NumberFormat(gb, { style: 'currency', currency: 'GBP' }).format(9.5); // "£9.50"
new Intl.NumberFormat(gb, { notation: 'compact' }).format(12500);              // "13K"
new Intl.DateTimeFormat(gb, { dateStyle: 'medium' }).format(date);             // "29 Sept 2026"
new Intl.RelativeTimeFormat(gb, { numeric: 'auto' }).format(-1, 'day');        // "yesterday"
Numbers, dates and units: table (8 rows)
ThingConventionExample
Dates in UIDay, short month, year, from Intl29 Sept 2026
Dates in data, URLs, filesISO 86012026-09-29
Recent timesRelative, up to 7 days, with the full date on hover3 hours ago
TimesOne clock across the product14:30 or 2:30pm, never both
Large numbersThousands separator12,500
Numbers with unitsNon-breaking space between them10 MB, 250 ms
Ranges"to", or an en dash with no spaces150 to 400ms
CountsWords for zero to nine in prose, digits in UI"three steps", "3 items"
  • MUST NOT write all-number dates such as 09/10/2026. Half the world reads it as September, half as October.
  • MUST format numbers and dates with Intl, not string concatenation, so the locale does the work.
  • MUST handle plurals properly: "1 item", "2 items", "No items". Intl.PluralRules helps.
  • SHOULD use font-variant-numeric: tabular-nums where numbers line up or change.

One spelling

Choose British or US English once, write it in the README, and apply it everywhere users read. This guide uses British English.

One spelling: table (6 rows)
BritishUS
colourcolor
organiseorganize
centrecenter
licence (noun)license
cancelledcanceled
greygray
  • MUST set the matching lang on <html>: en-GB or en-US.
  • MUST keep code in its own spelling. CSS says color and center; your prose says colour and centre. Do not "fix" either.
  • SHOULD name tokens in the code's spelling (--color-accent) and describe them in the prose spelling.
  • SHOULD add a spell-check dictionary set to the chosen variant in the editor and CI.

Voice rules

  • MUST write short sentences. One idea each.
  • MUST address people as "you", and the product as "we" only when it is a person acting (support, a team).
  • MUST use one word per concept: pick "Sign in" or "Log in" and never mix them.
  • SHOULD use curly quotes and apostrophes (’ “ ”) in rendered text.
  • SHOULD NOT use exclamation marks outside genuine celebration, such as a first successful deploy.

Why it works

Specific copy removes guesswork. A button that says "Delete project" cannot be misread, an error that ends with a fix gets people moving again, and one date format means nobody has to wonder which month it is. Consistency does the rest: once every label follows the same pattern, people stop reading words and start recognising them.

Sources

2 sources

On this page