Skip to main content

How to Use Navigation Service (NavigationMixin) in Salesforce LWC

In plain words: The Navigation Service in Salesforce Lightning Web Components (LWC) is a platform utility that redirects users to record pages, list views, standard object homepages, custom tabs, or external URLs using a standardized descriptor called a 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

Generate Component via Salesforce CLI:
# 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'
            }
        });
    }
}
Warning Trap — Forgetting the NavigationMixin Wrapper: If you forget to wrap your class definition with 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>
360 Architecture Summary:
  • Supported PageReference Types: standard__recordPage, standard__objectPage, standard__navItemPage (Custom Tabs), standard__component (LWC/Aura), and standard__webPage.
  • URL Generation: To populate standard HTML anchor tags (<a href>) for SEO and open-in-new-tab support, generate URLs asynchronously using this[NavigationMixin.GenerateUrl](pageRef).
  • State Management: Pass optional query parameters under the state key (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>
Deployment & Testing Procedure:
# 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 navigationDemo onto 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.
Core Takeaway: Using NavigationMixin ensures your internal and external transitions remain consistent, responsive, and fully compliant across desktop, mobile, and Experience Cloud deployments without hardcoded URLs.