Custom Labels are named text strings defined in Setup and referenced from Apex, LWC, Visualforce, Flow, and Aura via a single global namespace. Their two killer features: translatability (one label, many languages, the platform picks the right one for the running user) and deployability (labels move between orgs with a change set or package, unlike string constants in Apex).
The basics
Defined in Setup → Custom Labels. Each label has:
- Name — the Apex-accessible identifier (e.g.,
Welcome_Message). - Categories — for organisation in the Setup UI.
- Short Description — for translators.
- Value — the default-language text.
- Translations — separate values for each supported language.
- Protected/Public — visibility from outside a managed package.
Up to 15,000 custom labels per org, each up to 1,000 characters.
Reading them from each context
// Apex
String welcome = System.Label.Welcome_Message;
<!-- LWC: in the JS module -->
import WELCOME from '@salesforce/label/c.Welcome_Message';
<!-- Visualforce -->
{!$Label.Welcome_Message}
// Flow formula
{!$Label.Welcome_Message}
In Aura: {!$Label.c.Welcome_Message}.
The label namespace is global — once defined, any platform layer can read it.
Translatability — the main reason they exist
Suppose your org supports English, Spanish, and Japanese. You define Welcome_Message:
- English: “Welcome to Acme CRM”
- Spanish: “Bienvenido a Acme CRM”
- Japanese: “Acme CRMへようこそ”
System.Label.Welcome_Message
The runtime substitutes the value matching the running user’s language preference. No conditionals, no map lookups, no hardcoded strings.
To use this, your org must enable Translation Workbench (Setup → Translation Workbench → Translation Settings) and add the supported languages.
When to choose Custom Labels over alternatives
| Use case | Best tool |
|---|---|
| User-facing UI text | Custom Labels |
| Error messages thrown by Apex / shown in UI | Custom Labels |
| Static technical constants used only by Apex | A public static final constant in a class |
| Per-tenant configuration that changes per org | Custom Metadata Types |
| Per-user config that changes per user | Hierarchy Custom Settings |
| Long-form content (terms, privacy text) | A static resource or a Knowledge article |
The dividing line: does this string change per language, and is it visible to users? If yes, label. If no, a class constant or Custom Metadata.
Limits and gotchas
- 1,000-character cap per label value (per language).
- Labels are cached at the application layer — reads cost nothing.
- Labels deploy with change sets, Metadata API, and packages — including their translations.
- A label’s Name cannot change once it’s been referenced from code. You can rename it in Setup, but every reference will break.
- Labels are
Stringonly — no markup, no parameters. For parameterised messages, doString.format(System.Label.Greeting, new List<String>{ name }).
Parameterised messages with String.format
// Setup → Custom Labels → Greeting:
// "Hello, {0}. You have {1} new messages."
String msg = String.format(
System.Label.Greeting,
new List<String>{ 'Vikas', String.valueOf(5) }
);
// → "Hello, Vikas. You have 5 new messages."
The {0}, {1} placeholders are how you inject runtime values without breaking translatability — translators get a string with placeholders, not a string with hardcoded variable names.
Managed-package visibility
A managed package’s labels are namespaced with the package prefix (e.g., acme.Welcome_Message). Subscriber code referencing them needs the prefix. Protected labels are visible only within the package; Public labels can be read by subscriber code.
What interviewers are really looking for
The naming check is “translatable strings.” Strong signals: (1) you read them as System.Label.Name in Apex and @salesforce/label/c.Name in LWC, (2) they’re cached so there’s no governor cost, (3) they enable Translation Workbench for multi-language UIs, (4) String.format with {0}/{1} placeholders lets you build parameterised messages without losing translatability, (5) labels deploy between orgs — making them the right home for any user-facing text that might need to change without a code deployment.
Verified against: Salesforce Help — Custom Labels, LWC Developer Guide — Custom Labels. Last reviewed 2026-05-17.