PageReference.
Hardcoding URLs in Salesforce components breaks across sandboxes, production environments, Experience Cloud sites, and the Salesforce Mobile App. The NavigationMixin module from lightning/navigation provides an environment-agnostic routing framework that ensures your links and redirects work smoothly across every device and deployment target.
Prerequisites
- A Salesforce Developer Edition, Scratch Org, or active Sandbox.
- Salesforce CLI (
sf) installed and authenticated. - Basic knowledge of JavaScript ES6 classes and LWC event handlers.
Step 1: Set Up the Component Bundle
# Create the Lightning Web Component bundle
sf lightning generate component -n navigationDemo -d force-app/main/default/lwc --type lwc
Step 2: Implement Common Navigation Targets in JavaScript
In navigationDemo.js, extend your component class with NavigationMixin(LightningElement) and configure routing methods for record pages, list views, record creation, and web URLs:
import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
export default class NavigationDemo extends NavigationMixin(LightningElement) {
@api recordId; // Injected automatically when placed on a record page
// 1. Navigate to a Specific Record View Page
navigateToRecordView() {
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: {
recordId: this.recordId || '001000000000000AAA',
objectApiName: 'Account',
actionName: 'view'
}
});
}
// 2. Navigate to Record in Edit Mode
navigateToRecordEdit() {
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: {
recordId: this.recordId || '001000000000000AAA',
objectApiName: 'Account',
actionName: 'edit'
}
});
}
// 3. Navigate to Object Home / Recent List View
navigateToObjectHome() {
this[NavigationMixin.Navigate]({
type: 'standard__objectPage',
attributes: {
objectApiName: 'Contact',
actionName: 'home'
}
});
}
// 4. Navigate to Create New Record Dialog
navigateToNewRecord() {
this[NavigationMixin.Navigate]({
type: 'standard__objectPage',
attributes: {
objectApiName: 'Opportunity',
actionName: 'new'
}
});
}
// 5. Navigate to an External Web URL
navigateToExternalUrl() {
this[NavigationMixin.Navigate]({
type: 'standard__webPage',
attributes: {
url: 'https://developer.salesforce.com'
}
});
}
}
NavigationMixin(LightningElement), calling this[NavigationMixin.Navigate] will silently fail or throw a runtime error (TypeError: Cannot read properties of undefined). Always wrap your export class declaration.
Step 3: Build the UI Template
In navigationDemo.html, wire each navigation helper method to standard Lightning buttons:
<template>
<lightning-card title="Navigation Service Control Panel" icon-name="utility:routing_offline">
<div class="slds-p-around_medium">
<p class="slds-text-body_regular slds-m-bottom_medium">
Select a routing destination to test dynamic navigation transitions:
</p>
<div class="slds-grid slds-wrap slds-gutters">
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-button
class="slds-size_full"
variant="brand"
label="View Current Account"
icon-name="utility:preview"
onclick={navigateToRecordView}>
</lightning-button>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-button
class="slds-size_full"
variant="neutral"
label="Edit Account Record"
icon-name="utility:edit"
onclick={navigateToRecordEdit}>
</lightning-button>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-button
class="slds-size_full"
variant="neutral"
label="Open Contacts Home"
icon-name="standard:contact"
onclick={navigateToObjectHome}>
</lightning-button>
</div>
<div class="slds-col slds-size_1-of-1 slds-medium-size_1-of-2 slds-m-bottom_small">
<lightning-button
class="slds-size_full"
variant="success"
label="Create New Opportunity"
icon-name="utility:new"
onclick={navigateToNewRecord}>
</lightning-button>
</div>
<div class="slds-col slds-size_1-of-1 slds-m-top_small">
<lightning-button
class="slds-size_full"
variant="destructive-text"
label="Open External Developer Site"
icon-name="utility:new_window"
onclick={navigateToExternalUrl}>
</lightning-button>
</div>
</div>
</div>
</lightning-card>
</template>
- Supported PageReference Types:
standard__recordPage,standard__objectPage,standard__navItemPage(Custom Tabs),standard__component(LWC/Aura), andstandard__webPage. - URL Generation: To populate standard HTML anchor tags (
<a href>) for SEO and open-in-new-tab support, generate URLs asynchronously usingthis[NavigationMixin.GenerateUrl](pageRef). - State Management: Pass optional query parameters under the
statekey (e.g. filter states or default field values).
Step 4: Configure Metadata and Deploy
Update navigationDemo.js-meta.xml to expose the component to Record and App pages:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>60.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
# Deploy component to your authenticated org
sf project deploy start
# Open your default Salesforce org in the browser
sf org open
- In Salesforce Setup, navigate to Lightning App Builder.
- Drop
navigationDemoonto an Account Record Page or Custom App Page, then save and activate. - Click the action buttons to verify smooth page routing across records, modal forms, and external URLs.
NavigationMixin ensures your internal and external transitions remain consistent, responsive, and fully compliant across desktop, mobile, and Experience Cloud deployments without hardcoded URLs.