Skip to content
SalesforceSkills

UI Writing & Labels

Writes button labels, error messages, help text, and empty state copy for you. Gets the tone right every time.

Clear over cleverActive voiceVerb-first buttonsNo jargonConsistent terminology

Skill Details

Install this skill

Versionv1.1.0AuthorJorge ArteagaLicenseMITSections12

Works with

Claude CodeCursorWindsurf

The words inside a component matter as much as the visual design. Write clear, helpful, human UI text that guides users and reduces confusion.

Core Principles

1
Clear over clever — say exactly what happened and what to do next
2
Active voice — "Save the record" not "The record will be saved"
3
Verb-first buttons — "Create Account" not "Account Creation"
4
No jargon — "Something went wrong" not "Null pointer exception in line 42"
5
Consistent terminology — pick one word and use it everywhere

Error Messages

Structure: What + Why + What to Do

Every error message answers three questions:

┌─────────────────────────────────────────────┐
│  WHAT happened    │ "Record couldn't be saved"
│  WHY it happened  │ "Required fields are missing"
│  WHAT TO DO next  │ "Fill in Account Name and click Save again"
└─────────────────────────────────────────────┘

Error Templates

Error in Code

JavaScript
get userFriendlyError() {
    if (!this._error) return class="code-string">'';
    if (this._error.body?.message) {
        return this._error.body.message;
    }
    return class="code-string">'Something went wrong. Try again, or contact your admin if the problem continues.';
}

Anti-Patterns

Empty States

Empty states are opportunities to guide users, not dead ends.

Structure: Explain + Guide + Act

┌─────────────────────────────────────────────┐
│           [Icon or illustration]             │
│                                             │
│     No {items} yet                          │  ← Explain
│     {Why this is empty or what items are}   │  ← Guide
│     [Create {Item}]                         │  ← Act
└─────────────────────────────────────────────┘

Empty State Templates

Industry-Specific Copy Templates

Financial Services

Healthcare

Manufacturing

Retail / Commerce

Persona-Based Labels

For demos, personalize greetings and contextual messages:

JavaScript
get welcomeMessage() {
    const hour = new Date().getHours();
    const greeting = hour < 12 ? class="code-string">'Good morning' : hour < 17 ? class="code-string">'Good afternoon' : class="code-string">'Good evening';
    return class="code-string">`${greeting}, ${this.userName}. ${this.taskSummary}`;
}

get taskSummary() {
    const count = this.openTasks?.length || 0;
    if (count === 0) return class="code-string">'You\'re all caught up!class="code-string">';
    return class="code-string">`${count} ${count === 1 ? 'item needsclass="code-string">' : 'items need'} your attention.`;
}

Button Labels

Rules

  • Verb first: Save Record, Create Contact, Send Email
  • Specific over generic: Save Changes not Submit, Delete Account not OK
  • Match the action: the button label should describe what happens when clicked
  • Destructive actions: use the verb that matches (Delete, Remove, Disconnect)

Common Pairs

Anti-Patterns

Help Text and Tooltips

When to Use

Help Text Templates

Accessibility Note

Tooltips must be keyboard-accessible. Use aria-describedby to link help text to its field:

HTML
<class="code-tag">lightning-input
    label="Annual Revenue"
    field-name="AnnualRevenue"
    aria-describedby="revenue-help">
</class="code-tag">lightning-input>
<class="code-tag">div id="revenue-help" class="help-text">
    Enter the company's total annual revenue in USD.
</class="code-tag">div>

Confirmation Dialogs

Structure: Consequence + Specific Action

┌─────────────────────────────────────────────┐
│  Delete this account?                        │  ← Question (what will happen)
│                                             │
│  This will permanently delete "Acme Corp"   │  ← Consequence
│  and all related contacts and cases.         │
│  This action can't be undone.               │
│                                             │
│        [Cancel]    [Delete Account]          │  ← Specific labels
└─────────────────────────────────────────────┘

Templates

Toast Messages

Format

JavaScript
class="code-comment">// Success: past tense, brief
{ title: class="code-string">'Account saved', message: class="code-string">'Your changes have been saved.', variant: class="code-string">'success' }

class="code-comment">// Error: what happened + what to do
{ title: class="code-string">'Couldn\'t save recordclass="code-string">', message: 'Check required fields and try again.class="code-string">', variant: 'errorclass="code-string">' }

class="code-comment">// Warning: what to be aware of
{ title: 'Limited resultsclass="code-string">', message: 'Showing first 200 records. Refine your search.class="code-string">', variant: 'warningclass="code-string">' }

class="code-comment">// Info: neutral notification
{ title: 'Record updatedclass="code-string">', message: 'Changes made by another user have been loaded.class="code-string">', variant: 'info' }

Rules

  • Title: 2-4 words, sentence case
  • Message: 1 sentence, actionable for errors
  • Success toasts: optional message (title alone is often sufficient)
  • Error toasts: always include a message with guidance

Placeholder Text

Rules

  • Placeholders are examples, not labels — never replace a label with a placeholder
  • Use realistic examples: Search accounts... not Type here
  • Keep short: max 30-40 characters

Templates

Internationalization Readiness

String Patterns

  • Never concatenate translated strings — word order varies by language
  • Use Custom Labels for all user-facing text
  • Allow 40% expansion for translated text (German/French are longer than English)
  • Avoid text in images — it can't be translated
JavaScript
import SAVE_LABEL from class="code-string">'@salesforce/label/c.Save_Changes';
import ERROR_TITLE from class="code-string">'@salesforce/label/c.Error_Title';

export default class MyComponent extends LightningElement {
    labels = { SAVE_LABEL, ERROR_TITLE };
}
HTML
<class="code-tag">lightning-button label={labels.SAVE_LABEL}></class="code-tag">lightning-button>

Scoring Rubric (100 Points)Reference

Cross-Skill IntegrationReference

ScenarioMessage
Field validation{Field Name} is required. Enter a value to continue.
Server errorWe couldn't save this record. Check your entries and try again.
Permission deniedYou don't have access to {action}. Contact your admin for help.
Network errorWe couldn't connect to Salesforce. Check your connection and try again.
Not foundThis {record type} was deleted or you don't have access to it.
Limit reachedYou've reached the maximum of {limit} {items}. Remove one to add another.
Do NOT SaySay Instead
Error: 500 Internal Server ErrorSomething went wrong. Try again in a moment.
FIELD_CUSTOM_VALIDATION_EXCEPTION{Validation rule error message text}
null or blankSomething unexpected happened. Try again.
Invalid inputEnter a valid {field type}. Example: name@company.com
ContextTitleDescriptionAction
First useNo cases yetCases appear here when customers reach out.Create a Case
No resultsNo matching recordsTry adjusting your filters or search terms.Clear Filters
Filtered emptyNo {items} match "{query}"Check your spelling or try different keywords.Clear Search
CompletedAll caught upYou've resolved all open cases. Nice work.
PermissionNothing to showAsk your admin for access to {feature}.Request Access
ElementGenericFinancial Services
Empty stateNo records foundNo open positions in this portfolio
Search placeholderSearch...Search clients, accounts, or holdings...
Welcome messageWelcome backGood morning, {Name}. 3 client reviews due today.
KPI labelTotal valueAssets Under Management
Action buttonCreate recordLog Client Interaction
Success toastRecord savedClient profile updated
ElementGenericHealthcare
Empty stateNo records foundNo open care plans for this patient
Search placeholderSearch...Search patients, care plans, or encounters...
Welcome messageWelcome backGood morning, {Name}. 12 patients on your panel today.
KPI labelCompletion rateCare Plan Adherence
Action buttonCreate recordSchedule Appointment
Success toastRecord savedCare plan updated successfully
ElementGenericManufacturing
Empty stateNo records foundNo open orders for this account
Search placeholderSearch...Search accounts, agreements, or products...
Welcome messageWelcome backGood morning, {Name}. 5 agreements need attention.
KPI labelTotal amountRun Rate Revenue
Action buttonCreate recordCreate Sales Agreement
Success toastRecord savedForecast updated for Q2
ElementGenericRetail
Empty stateNo records foundNo recent orders for this customer
Search placeholderSearch...Search customers, orders, or products...
Welcome messageWelcome backWelcome back, {Name}. 8 orders need fulfillment.
KPI labelAverage valueAverage Order Value
Action buttonCreate recordProcess Return
Success toastRecord savedOrder status updated
PrimarySecondaryContext
SaveCancelEdit form
Create {Item}CancelNew record form
DeleteKeepDestructive confirmation
ConfirmGo BackMulti-step process
SendCancelEmail/message action
ApplyResetFilter/settings
Do NOTDo Instead
OK / Yes / NoSpecific: Delete Record / Keep Record
Submit (generic)Save Changes, Create Account, Send Request
Click HereView Details, Download Report
ProcessRun Report, Calculate Total
PatternUse When
Inline help textField needs context every time (format, constraints)
TooltipSupplementary info; not needed for task completion
Info icon + popoverDetailed explanation that would clutter inline
Field TypeHelp Text Pattern
EmailEnter a valid email address. Example: name@company.com
PhoneInclude country code for international numbers. Example: +1 (555) 123-4567
DateEnter a date in MM/DD/YYYY format.
CurrencyEnter the amount without currency symbols.
LookupSearch by name or record number.
PicklistSelect the option that best describes {context}.
PercentageEnter a number between 0 and 100.
ActionTitleBodyConfirm Button
Delete recordDelete this {type}?This will permanently delete "{name}" and its related data. This can't be undone.Delete {Type}
Discard changesDiscard unsaved changes?You have unsaved changes that will be lost.Discard Changes
Remove from listRemove {name}?{Name} will be removed from this {list}. You can add them back later.Remove
ReassignReassign this {type}?{Name} will be reassigned from {current} to {new}.Reassign
FieldPlaceholder
SearchSearch {items}...
NameEnter full name
Emailname@company.com
DescriptionDescribe the issue...
URLhttps://example.com
CategoryPointsPass Criteria
Error Messages25All errors follow what/why/do structure; no raw exceptions shown
Empty States20Every list/table has an empty state with guidance and action
Button Labels15Verb-first, specific, destructive actions clearly labeled
Help Text15Fields that need context have help text; accessible linking
Confirmation Dialogs15Destructive actions confirmed; specific labels on buttons
i18n Ready10Custom Labels used; no string concatenation; expansion room
SkillRelationship
sf-lwc-uxEmpty/error/loading states need well-written content
sf-lwc-reviewAudit includes content quality checks
sf-lwc-page-compositionApp Builder property labels and descriptions need good copy
sf-lwc-mobileMobile copy must be even more concise
sf-se-demo-scriptsIndustry copy templates make demos feel authentic

Navigate User Experience