Mastering NavigationMixin in Lightning Web Components (LWC)

Introduction

In Salesforce Lightning Web Components (LWC), navigation between different Salesforce pages, objects, and external links is crucial for providing a smooth user experience. The NavigationMixin allows us to achieve seamless navigation in LWC by enabling developers to create handlers for various navigation scenarios. In this blog, we’ll explore how to use NavigationMixin effectively to navigate to home pages, record views, external sites, and even custom LWC pages.

Explanation of Navigation Scenarios

  • Navigate to Home and Chatter Pages: These handle navigation to predefined Salesforce pages like Home and Chatter using standard__namedPage.

  • Navigate to a New Record for a Custom Object (Blog__c): Navigate to create a new record using standard__objectPage.

  • Setting Default Values for Record Creation: Uses encodeDefaultFieldValues for pre-populating fields in a new Contact record.

  • Navigate to List Views and Files: Uses standard__objectPage with an action name of list or home to access list views and files.

  • Record Page Navigation for View and Edit Modes: Uses standard__recordPage to navigate to specific records in view and edit modes.

  • Navigate to Related Lists: Uses standard__recordRelationshipPage to display related lists (e.g., Contacts for an Account).

  • Navigating to Tabs and External Web Pages: Accesses custom tabs or external URLs with standard__navItemPage and standard__webPage.

  • Custom LWC Navigation: Uses JSON encoding to load another LWC component in Salesforce by defining the component path.

<template>
    <div class="slds-grid slds-wrap">
        <template for:each={UiData} for:item="obj">
            <div key={obj.title} class="slds-size_1-of-3 slds-p-around_small">
                <lightning-card title={obj.title}>
                    <lightning-button 
                        class="slds-m-around_medium" 
                        variant="brand" 
                        label="Click" 
                        onclick={obj.functionHandler}>
                    </lightning-button>
                </lightning-card>
            </div>
        </template>
    </div>
</template>
import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import { encodeDefaultFieldValues } from 'lightning/pageReferenceUtils';

export default class NavigationMixinHandson extends NavigationMixin(LightningElement) {
    // Define an array of navigation options with their respective titles and handlers
    UiData = [
        { title: "Navigate to home", functionHandler: this.handleHomeClick },
        { title: "Navigate to chatter", functionHandler: this.handleChatterClick },
        { title: "Navigate to Object Page", functionHandler: this.handleObjectPageClick },
        { title: "Navigate to List View", functionHandler: this.handleListClick },
        { title: "Navigate to Files", functionHandler: this.handleFileClick },
        { title: "Navigate to RecordPage view mode", functionHandler: this.handleViewModeClick },
        { title: "Navigate to RecordPage edit mode", functionHandler: this.handleEditModeClick },
        { title: "Navigate to RecordPage related list mode", functionHandler: this.handleRelatedListViewModeClick },
        { title: "Navigate To Tab", functionHandler: this.handleTabClick },
        { title: "Navigate To External Web Page", functionHandler: this.handleWebPageClick },
        { title: "Navigate To LWC Web Page", functionHandler: this.handleNavigateToLWC },
        { title: "Navigation Mixin with default values", functionHandler: this.handleCreateContactClick }
    ];

    // Navigate to the home page
    handleHomeClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__namedPage',
            attributes: {
                pageName: 'home'
            }
        });
    }

    // Navigate to the Chatter page
    handleChatterClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__namedPage',
            attributes: {
                pageName: 'chatter'
            }
        });
    }

    // Navigate to a new Object Page (Blog__c)
    handleObjectPageClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Blog__c',
                actionName: 'new'
            }
        });
    }

    // Navigate to a new Contact record with default values
    handleCreateContactClick() {
        const defaultValues = encodeDefaultFieldValues({
            FirstName: "Harsh",
            LastName: "Verma"
        });

        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Contact',
                actionName: 'new'
            },
            state: {
                defaultFieldValues: defaultValues
            }
        });
    }

    // Navigate to the List View of Blog__c
    handleListClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'Blog__c',
                actionName: 'list'
            },
            state: {
                filterName: 'Recent'
            }
        });
    }

    // Navigate to the Files page
    handleFileClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: 'ContentDocument',
                actionName: 'home'
            }
        });
    }

    // Navigate to view mode of a specific Account record
    handleViewModeClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: '0012t00000TDJ5dAAH', // Replace with actual recordId as needed
                objectApiName: 'Account',
                actionName: 'view'
            }
        });
    }

    // Navigate to edit mode of a specific Account record
    handleEditModeClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: '0012t00000TDJ5dAAH', // Replace with actual recordId as needed
                objectApiName: 'Account',
                actionName: 'edit'
            }
        });
    }

    // Navigate to related list view of a specific Account record
    handleRelatedListViewModeClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordRelationshipPage',
            attributes: {
                recordId: '0012t00000TDJ5dAAH', // Replace with actual recordId as needed
                objectApiName: 'Account',
                relationshipApiName: "Contacts",
                actionName: 'view'
            }
        });
    }

    // Navigate to a specific tab
    handleTabClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__navItemPage',
            attributes: {
                apiName: 'Publish_a_blog'
            }
        });
    }

    // Navigate to an external web page
    handleWebPageClick() {
        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: 'https://forcedev.hashnode.dev/'
            }
        });
    }

    // Navigate to a custom LWC page
    handleNavigateToLWC() {
        const definition = {
            componentDef: 'c:memoryGame'
        };

        this[NavigationMixin.Navigate]({
            type: 'standard__webPage',
            attributes: {
                url: '/one/one.app#' + btoa(JSON.stringify(definition))
            }
        });
    }
}

Conclusion

The NavigationMixin provides a powerful way to control navigation in Salesforce applications, making user flows smoother and more interactive. Experiment with these techniques in your own components to bring even more functionality to your LWC applications.