Skip to main content

Content patterns

Content patterns provide standardized microcopy for error messages, button labels, empty states, and other UI text. Using consistent, well-crafted copy helps users understand your interface and builds trust.

Pattern categories

CategoryPurposeExamples
ErrorExplain what went wrongValidation errors, API errors, permission denied
EmptyGuide when no contentNo results, first-time user, inbox zero
ButtonLabel actions clearlySave, Delete, Create, Cancel
ConfirmVerify destructive actionsDelete confirmation, unsaved changes
SuccessConfirm completionSaved, Created, Sent
HintHelp users fill formsPlaceholders, helper text

Error messages

Tone rules

  1. Be helpful, not blaming: never blame the user; focus on the problem and solution
  2. Explain what happened: don't just say "error"; describe the issue
  3. Suggest a fix: tell users how to resolve the problem
  4. Avoid technical jargon: use plain language, not error codes

Error patterns

PatternTemplateUse case
error-required-field{field} is requiredRequired field validation
error-invalid-emailPlease enter a valid email addressEmail format validation
error-password-too-shortPassword must be at least {minLength} charactersPassword length
error-network-connectionWe couldn't connect to the server...Network failures
error-server-errorWe're having trouble processing your request...500 errors
error-not-foundThe {item} you're looking for doesn't exist...404 errors
error-permission-deniedYou don't have permission to {action}...403 errors

Examples

// Good error messages
fill_content_template({ pattern: 'error-required-field', values: { field: 'Email' } })
// → "Email is required"

fill_content_template({ pattern: 'error-password-too-short', values: { minLength: 8 } })
// → "Password must be at least 8 characters"

// Bad error messages (don't use)
// "Invalid input"
// "Error occurred"
// "Something went wrong"
// "You entered an invalid email"

Empty states

Types

TypeWhen to useKey elements
First-timeUser has no items yetEncouraging title, create CTA
No resultsSearch returned nothingShow query, suggest alternatives
No matchesFilters exclude everythingClear filters CTA
Inbox zeroAll items processedPositive, encouraging tone

Empty state patterns

PatternTitleMessage
empty-first-timeNo {items} yetCreate your first {item} to get started.
empty-no-search-resultsNo results foundWe couldn't find anything matching "{query}".
empty-no-filter-resultsNo matchesNo {items} match your current filters.
empty-inbox-zeroAll caught up!You have no new {items} to review.

Examples

// First-time empty state
fill_content_template({
  pattern: 'empty-first-time',
  values: { items: 'projects', item: 'project' }
})
// → { title: "No projects yet", message: "Create your first project to get started.", action: "Create project" }

// Search with no results
fill_content_template({
  pattern: 'empty-no-search-results',
  values: { query: 'dashboard' }
})
// → { title: "No results found", message: "We couldn't find anything matching \"dashboard\".", action: "Clear search" }

Button labels

Rules

  1. Use action verbs: describe what will happen: "Save", "Delete", "Create"
  2. Be specific: "Delete Project" is better than "Delete"
  3. Avoid generic labels: "OK", "Yes", "Submit" are unclear
  4. Match the context: "Save Draft" vs "Publish" vs "Send"

Button patterns

PatternLabelSecondaryContext
button-saveSaveCancelGeneral save
button-save-changesSave changesDiscardEditing existing
button-createCreate {item}CancelCreating new
button-deleteDeleteCancelDestructive
button-delete-itemDelete {item}CancelDestructive with context
button-cancelCancel:Dismiss / abort
button-backBack:Navigation

Confirmation dialogs

When to confirm

  • Permanent deletions
  • Actions that can't be undone
  • Navigating away with unsaved changes
  • Bulk operations affecting multiple items

Confirmation patterns

PatternTitleMessage
confirm-deleteDelete {item}?This action cannot be undone. All data...
confirm-delete-with-countDelete {count} {items}?This action cannot be undone. All selected...
confirm-unsaved-changesUnsaved changesYou have unsaved changes that will be lost...
confirm-discard-changesDiscard changes?Your changes have not been saved...

Success messages

Rules

  1. Be specific: confirm exactly what happened
  2. Keep it brief: success should be obvious
  3. Include the item: "Project created" not just "Created"

Success patterns

PatternMessageContext
success-savedChanges savedGeneral save
success-created{item} createdItem creation
success-deleted{item} deletedItem deletion
success-sent{item} sentMessages, emails

MCP tool usage

// Get all error patterns
get_content_pattern({ category: 'error' })

// Get specific pattern
get_content_pattern({ name: 'confirm-delete' })

// Include tone rules
get_content_pattern({ category: 'button', includeRules: true })

// Fill a template
fill_content_template({
  pattern: 'error-required-field',
  values: { field: 'Email' }
})

// Use variants
fill_content_template({
  pattern: 'error-required-field',
  values: { field: 'Email' },
  variant: 'short'
})
// → "Required"

Template placeholders

Placeholders use {curly braces} syntax:

PlaceholderTypeDescription
{field}stringField name (Email, Password)
{item}stringSingular item (project, user)
{items}stringPlural items (projects, users)
{count}numberNumber of items
{query}stringSearch query
{minLength}numberMinimum length
{action}stringAction being attempted

Common mistakes

Blaming the user

// Bad — blames user
"You entered an invalid email"

// Good — focuses on the input
"Please enter a valid email address"

Generic messages

// Bad — unhelpful
"Something went wrong"

// Good — explains and suggests fix
"We couldn't save your changes. Please try again."

Technical jargon

// Bad — confusing
"HTTP 500 Internal Server Error"

// Good — plain language
"We're having trouble processing your request. Please try again in a moment."

Generic button labels

// Bad — unclear




// Good — descriptive



Was this page helpful?

Last reviewed by @jschuyler
All systems operationalDocsDevelopersPlatformPricing
PrivacyTerms© 2026 fndd, LLC