A style guide with guidelines for building a clean Salesforce org that's easy on the eyes and simple to maintain
The guiding principle is “no underscores”, which is a reminder to pay attention to details. Salesforce out-of-the-box will auto-generate API names for many common components such as objects and fields, but sadly those API names use underscores as filler to replace special characters and spaces. The result is that uncoordinated implementations will result in the creation of things in the org like the following.
Account.of_Users__c
)Account.Platforms__c
) on one object and
Platforms checkbox field on a different objectContact.Accounts1__r
,
Lead.Accounts2__r
or Opportunity.Accounts3__r
If you care to avoid such tragedies, talk to your team about adopting a few simple habits.
Below are step-by-step instructions for getting rid of underscores and making your components look as if they came natively out of the box.
snake_case
namesnake_case
to CamelCase
Is
prefix for checkbox fields)Step | Result |
---|---|
Write the label in plain English | Auto-POST Job Status |
Expand common abbreviations | Auto-POST Job Status |
Drop to lowercase | auto-post job status |
Strip special characters | autopost job status |
Replace spaces with underscores | autopost_job_status |
Convert to CamelCase |
AutopostJobStatus |
Apply well known conventions | AutopostJobStatus |
Step | Result |
---|---|
Write the label in plain English | PayPal Transaction No. |
Expand common abbreviations | PayPal Transaction Number |
Drop to lowercase | paypal transaction number |
Strip special characters | paypal transaction number |
Replace spaces with underscores | paypal_transaction_number |
Convert to CamelCase |
PaypalTransactionNumber |
Apply well known conventions | PaypalTransactionNumber |
Below are conventions for different component types, ordered by the current label (e.g., Aura Component vs. Lightning Component) seen in the latest Salesforce release notes and other documentation.
Custom fields should be named following the conventions below.
Field Label | Field Name | Child Relationship Name |
---|---|---|
Campaign | CampaignId |
CampaignMembers |
First Disbursement | FirstDisbursement__c |
FirstFundingRequests__r |
Last Disbursement | LastDisbursement__c |
LastFundingRequests__r |
Follow the same conventions as lookup fields.
URL fields should be named with the word “URL” in the label, unless the name is well known (e.g., website) to imply a URL.
Object Label | Field Label | Field API Name |
---|---|---|
Account | Website | Website |
Auth Provider | Authorize URL | AuthorizeUrl |
Auth Provider | Error URL | ErrorUrl |
Custom settings come in two types: hierarchy and list.
Hierarchy settings should be named with a descriptor and end with the word “Setting”.
Custom Setting Label | API Name |
---|---|
Feature Setting | FeatureSetting__c |
Integration Setting | IntegrationSetting__c |
Conceptually this is similar to the “settings” field in scratch org definition files.
Email templates should be named to match the subject. This will make it easier to locate specific email templates when troubleshooting.
See examples below.
Subject | Email Template Name | Template Unique Name |
---|---|---|
CTA: Rock the Vote! | CTA: Rock the Vote! | CtaRockTheVote |
Big Deal Alert | Big Deal Alert | BigDealAlert |
What’s on your mind? | What’s on your mind? | WhatsOnYourMind |
Account Name Changed to {!Account.Name} | Account Name Changed | AccountNameChanged |
Object-specific flows should be prefixed with the object’s API name. Omit the namespace for objects from a managed package if possible.
Object API Name | Flow Label | Flow API Name |
---|---|---|
outfunds__Disbursement__c |
Disbursement: Submit for Full Approval | DisbursementSubmitForFullApproval |
Opportunity |
Opportunity: Submit for Finance Review | OpportunitySubmitForFinanceReview |
Record-triggered flows should be limited to a maximum of five per object, one in each context.
Flow Label | Flow API Name |
---|---|
Account: Before Create | AccountBeforeCreate |
Account: After Create | AccountAfterCreate |
Account: Before Update | AccountBeforeUpdate |
Account: After Update | AccountAfterUpdate |
Account: Before Delete | AccountBeforeDelete |
Payment: After Update | PaymentAfterUpdate |
If you must split record-triggered flows for ease of maintenance, keep the object label and context as a prefix.
Flow Label | Flow API Name |
---|---|
Account: After Update Create Follow-up Task | AccountAfterUpdateCreateFollowupTask |
Account: After Update Alert on Finance Hold | AccountAfterUpdateAlertOnFinanceHold |
Account: After Update Alert on Poor Health | AccountAfterUpdateAlertOnPoorHealth |
Label | API Name | Description |
---|---|---|
Create SyncPayment Job | createSyncPaymentJob | Create an async job with Class Name “SyncPayment”. |
A Boolean decision should have a question mark at the end of the label.
Label | API Name |
---|---|
Status Change? | statusChangeDecision |
New Status | newStatusDecision |
The singular outcome elements for a Boolean decision should have “True” as
the label, with the Decision
suffix replaced with Outcome
in the
Outcome API Name.
The default outcome for a Boolean decision should be relabled as “False”.
Label | Outcome API Name |
---|---|
True | statusChangeOutcome |
Ready | newStatusReadyOutcome |
Not Ready | newStatusNotReadyOutcome |
If you’re lazy, the label can simply be “Email Alert” for most alerts, so as to avoid clutter in the flow.
The API name should be fully qualified with the name of the email template and the suffix “EmailAlert”.
Label | API Name |
---|---|
Email Alert | ofacSearchResultFoundEmailAlert |
Big Deal Alert | bigDealEmailAlert |
Email Alert | rockTheVoteEmailAlert |
Keep the scope of each permission set meaningful, and choose one of these two naming conventions.
This permission set grants a user access to perform a specific action or well known set of actions. Simple examples below.
Label | API Name |
---|---|
Convert Leads | ConvertLeads |
Hide Salesforce Classic | HideSalesforceClassic |
Manage Closed Opportunities | ManageClosedOpportunities |
This permission set grants a user access to a robust feature for which fine-grained control of specific cations is either unnecessary or infeasible. Simple examples below.
Label | API Name |
---|---|
DML History App | DmlHistoryApp |
Lightning Dialer | LightningDialer |
Lightning Experience | LightningExperience |
Validation rules are named as imperative statements.
Rule Name | Sample Description |
---|---|
BlockSpam |
Prevent messages that look like spam from being saved. |
RequireAccountOrContact |
Either an account or a contact must be specified on this payment method. |
Workflow rules should be named as imperative statements.
Rule Name | Description |
---|---|
Alert Operator on Account Name Change | Send an email to operators when Account Name changes. |
Prefer evaluating the rule when a record is “created, and every time it’s edited”.
Email alerts should be named to match the associated email template.
Email Alert Field | Email Template Field |
---|---|
Description | Subject |
Unique Name | Template Unique Name |
Field updates are named like assignment statements in Apex, using the field label in the Name and the field name in the Unique Name. The new value should also be included.
Name | Unique Name |
---|---|
Old Account Name = PRIORVALUE | OldNamePriorvalue |
Success Plan = NULL | SuccessPlanNull |
Success Plan = Premier | SuccessPlanPremier |
This repo is configured to publish a GitHub Pages site from the /docs
folder
on the master
branch, using the Leap Day theme.
Feel free to create issues or pull requests into master
update the guide!