Guiding users through multi-stage business processes is a core design standard in Salesforce. While standard record pages use the native Lightning Path component, developers often need to replicate this modern chevron progress bar inside custom Visualforce pages. By combining standard Salesforce Lightning Design System (SLDS) markup with reusable Visualforce components, you can build a dynamic path indicator that updates instantly based on record status.
1. Understanding SLDS Path CSS Classes
The visual state of each step along the SLDS path is controlled entirely by specific CSS modifier classes applied to the <li class="slds-path__item"> element:
slds-is-complete: Renders a green chevron with a checkmark, indicating the stage has been finished.slds-is-current slds-is-active: Highlights the chevron in dark blue, indicating the stage is currently in progress.slds-is-incomplete: Renders a muted gray chevron, showing upcoming or unreached stages.slds-is-won/slds-is-lost: Used for terminal stages (such as Closed Won or Closed Lost on Opportunities).
2. Building the Reusable Visualforce Component (c:SLDSPath)
Create a custom Visualforce component named SLDSPath.component. It accepts a Status attribute and uses Visualforce expression functions like CASE() to evaluate which CSS classes to attach to each chevron dynamically.
<apex:component>
<!-- Component Attributes -->
<apex:attribute name="Status" type="String" required="false" description="Current Stage Status" default="Draft"/>
<article class="slds-card">
<div class="slds-card__body slds-card__body_inner">
<div class="slds-path">
<div class="slds-grid slds-path__track">
<div class="slds-grid slds-path__scroller-container">
<div class="slds-path__scroller" role="application">
<div class="slds-path__scroller_inner">
<ul class="slds-path__nav" role="listbox" aria-orientation="horizontal">
<!-- Stage 1: Draft -->
<li class="slds-path__item {!CASE(Status,
'Draft', 'slds-is-current slds-is-active',
'Submit', 'slds-is-complete',
'Approved', 'slds-is-complete',
'slds-is-incomplete')}" role="presentation">
<a aria-selected="false" class="slds-path__link" href="javascript:void(0);" role="option" tabindex="-1">
<span class="slds-path__stage">
<span class="slds-assistive-text">Draft Stage</span>
</span>
<span class="slds-path__title">Draft</span>
</a>
</li>
<!-- Stage 2: Submit -->
<li class="slds-path__item {!CASE(Status,
'Draft', 'slds-is-incomplete',
'Submit', 'slds-is-current slds-is-active',
'Approved', 'slds-is-complete',
'slds-is-incomplete')}" role="presentation">
<a aria-selected="false" class="slds-path__link" href="javascript:void(0);" role="option" tabindex="-1">
<span class="slds-path__stage">
<span class="slds-assistive-text">Submit Stage</span>
</span>
<span class="slds-path__title">Submit</span>
</a>
</li>
<!-- Stage 3: Approved -->
<li class="slds-path__item {!CASE(Status,
'Approved', 'slds-is-current slds-is-active slds-is-won',
'slds-is-incomplete')}" role="presentation">
<a aria-selected="false" class="slds-path__link" href="javascript:void(0);" role="option" tabindex="-1">
<span class="slds-path__stage">
<span class="slds-assistive-text">Approved Stage</span>
</span>
<span class="slds-path__title">Approved</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</article>
</apex:component>
- Step 1: Save the component markup above as
SLDSPath.componentin your Salesforce org. - Step 2: Ensure your parent Visualforce page has the
<apex:slds />tag included to load the standard Lightning Design System styles. - Step 3: Pass your record's stage or status field dynamically via the
Statusparameter.
3. Embedding the Component in a Visualforce Page
To use your custom path component inside any Visualforce page, include <apex:slds /> and reference the component prefix c:SLDSPath:
<apex:page standardController="Opportunity">
<!-- Load Lightning Design System -->
<apex:slds />
<div class="slds-scope">
<!-- Pass dynamic record value to your path component -->
<c:SLDSPath Status="{!Opportunity.StageName}" />
<div class="slds-m-top_medium">
<p>Current Opportunity Stage: <strong>{!Opportunity.StageName}</strong></p>
</div>
</div>
</apex:page>
4. Common Traps & Modern Alternatives
slds-scope class will prevent SLDS styles, spacing tokens, and chevron graphics from rendering correctly.
- Visualforce SLDS Path: Ideal for maintaining legacy Visualforce pages without rewriting whole interfaces into Lightning.
- Lightning Web Components (
lightning-progress-indicator): The modern Salesforce standard for building interactive paths with native step transitions and click listeners in LWC. - Standard Record Path: Configured declaratively via Setup > Path Settings for standard record home pages.
CASE() formula inside your component classes, and always include <apex:slds /> on hosting Visualforce pages.
Summary
Using custom Visualforce components with SLDS classes allows you to bridge the gap between classic Visualforce pages and modern Lightning user experiences. By modularizing your progress bar into a standalone component, you can reuse the same clean path UI across multiple pages with zero duplicated code.