Skip to main content

How to Navigate Between Lightning Web Components in Salesforce Using NavigationMixin

In plain words: Navigating from one LWC to another in Salesforce means programmatically redirecting the user to a target component or custom Lightning tab using the standard NavigationMixin service from the lightning/navigation module.

In modern Salesforce applications, directing users between screens with custom state and parameters is essential. By applying the NavigationMixin class decorator to your Lightning Web Component, you can generate dynamic page references and trigger smooth page transitions directly inside Lightning Experience and the Salesforce Mobile App.

Prerequisites

  • A Salesforce Developer Edition org, Scratch Org, or Sandbox environment.
  • Salesforce CLI (sf) installed and authenticated.
  • Basic understanding of LWC JavaScript classes, getters, and standard event handling.

Step 1: Set Up the Source and Target Components

Create Components via Salesforce CLI:
# Create source component
sf lightning generate component -n firstComponent -d force-app/main/default/lwc --type lwc

# Create target destination component
sf lightning generate component -n secondComponent -d force-app/main/default/lwc --type lwc

Step 2: Build the Target Component (secondComponent)

To read dynamic parameters passed during navigation, the target component imports CurrentPageReference from the navigation module:

JavaScript Controller (secondComponent.js):

import { LightningElement, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';

export default class SecondComponent extends LightningElement {
    receivedMessage = 'No data received yet.';

    @wire(CurrentPageReference)
    getStateParameters(currentPageReference) {
        if (currentPageReference && currentPageReference.state) {
            // Read the dynamic query parameter
            this.receivedMessage = currentPageReference.state.c__customMessage || 'Default landing message';
        }
    }
}

Template (secondComponent.html):

<template>
    <lightning-card title="Target Component (Second Screen)" icon-name="standard:destination">
        <div class="slds-p-around_medium">
            <p class="slds-text-body_regular">
                Payload Received: <strong class="slds-text-color_success">{receivedMessage}</strong>
            </p>
        </div>
    </lightning-card>
</template>
Warning Trap: When using standard__component or standard__navItemPage, always prefix custom state parameters with c__ (e.g., c__customMessage). Salesforce reserves unprefixed state parameters for platform-level routing; omitting the prefix will cause your query parameters to be ignored or stripped at runtime.

Step 3: Implement Navigation Logic in the Source Component

Open firstComponent.js. Extend your class with NavigationMixin(LightningElement) and trigger programmatic navigation using this[NavigationMixin.Navigate]:

JavaScript Controller (firstComponent.js):

import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class FirstComponent extends NavigationMixin(LightningElement) {
    messageInput = 'Hello from Source Component!';

    handleInputChange(event) {
        this.messageInput = event.target.value;
    }

    navigateToSecondComponent() {
        this[NavigationMixin.Navigate]({
            type: 'standard__component',
            attributes: {
                componentName: 'c__secondComponent'
            },
            state: {
                c__customMessage: this.messageInput
            }
        });
    }
}

Template (firstComponent.html):

<template>
    <lightning-card title="Source Component (First Screen)" icon-name="standard:source">
        <div class="slds-p-around_medium">
            <lightning-input 
                type="text" 
                label="Custom Payload to Pass" 
                value={messageInput} 
                onchange={handleInputChange}>
            </lightning-input>

            <lightning-button 
                class="slds-m-top_medium" 
                variant="brand" 
                label="Navigate to Second Component" 
                onclick={navigateToSecondComponent}>
            </lightning-button>
        </div>
    </lightning-card>
</template>
360 Architecture Summary:
  • PageReference Types: Use standard__component for direct component routing, or standard__navItemPage to navigate to a Custom Tab.
  • Target Naming: The componentName attribute requires the format c__<componentName> (e.g., c__secondComponent).
  • URL Generation: To generate a valid URL string instead of immediately navigating, use this[NavigationMixin.GenerateUrl](pageRef).

Step 4: Configure Metadata and Deploy

Update firstComponent.js-meta.xml and secondComponent.js-meta.xml to expose the components to the Lightning Platform:

<?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>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>
Deployment & Testing:
# Deploy components to the default org
sf project deploy start

# Open target org in browser
sf org open
  • In Salesforce Setup, navigate to Lightning App Builder.
  • Place firstComponent onto an App or Record Page, then save and activate.
  • Enter a custom string in the input field and click Navigate to Second Component to verify seamless redirection and state delivery.
Core Takeaway: Leveraging NavigationMixin alongside CurrentPageReference ensures clean, platform-standard page redirection and data transfer across Lightning Web Components.