Not verified hands-on. This article was written from primary documentation rather than reproduced in an org, so it carries no tested-release badge. If you run it and something differs, say so in the comments and it gets tested and corrected.

Briefly: apply NavigationMixin to your class, build a page reference object that describes where you want to go, and pass it to this[NavigationMixin.Navigate](). Never build a URL by concatenating the org domain with a record id, because the result breaks in Experience Cloud, in the mobile app, and in any sandbox with a different domain. The mixin exists so that one description of a destination works everywhere the component runs.

Applying the mixin

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

export default class OpenRecord extends NavigationMixin(LightningElement) {
    @api recordId;

    handleOpen() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: this.recordId,
                objectApiName: 'Account',
                actionName: 'view'
            }
        });
    }
}

The square-bracket syntax is unusual and it is not optional. NavigationMixin.Navigate is a symbol, so this.Navigate(...) does not exist. The mixin wraps LightningElement in the class declaration. Extending LightningElement directly and then trying to use the symbol gives an undefined function.

The page references you will actually use

standard__recordPage opens a record. actionName takes view, edit or clone. The objectApiName is optional for view and required for clone, and supplying it makes the navigation faster because the platform does not have to resolve the prefix.

standard__objectPage opens an object’s home or a list view:

this[NavigationMixin.Navigate]({
    type: 'standard__objectPage',
    attributes: { objectApiName: 'Case', actionName: 'list' },
    state: { filterName: 'My_Open_Cases' }
});

The list view goes in state, not attributes, and filterName accepts the list view’s developer name or its id. An unknown name lands the user on the default list rather than throwing.

standard__webPage opens any URL, internal or external:

this[NavigationMixin.Navigate]({
    type: 'standard__webPage',
    attributes: { url: 'https://status.salesforce.com' }
});

This is also how you trigger a file download, by pointing at the file’s download URL. Be aware that on mobile a standard__webPage may open in an in-app browser rather than the device browser.

Others worth knowing: standard__navItemPage for a custom tab, addressed by its apiName; standard__recordRelationshipPage for a related list; standard__component for an Aura component, which needs the component in the c__ namespace form and is the escape hatch when nothing else fits.

GenerateUrl, and why links matter

A button that calls Navigate is fine. A link that a user might want to open in a new tab should be a real anchor with a real href, and GenerateUrl produces one.

this[NavigationMixin.GenerateUrl]({
    type: 'standard__recordPage',
    attributes: { recordId: this.recordId, actionName: 'view' }
}).then((url) => {
    this.recordUrl = url;
});

It returns a promise. Middle-click, right-click and copy-link all work on the resulting anchor, and keyboard users get a focusable element that announces itself as a link. A div with an onclick gives none of that.

What differs in an Experience Cloud site

This is where most navigation bugs live. A site is not Lightning Experience, and the set of supported page reference types is smaller.

  • standard__navItemPage is not the way to reach a site page. Custom tabs are a Lightning Experience concept.
  • Use comm__namedPage for a page created in Experience Builder, addressed by its API name.
  • standard__recordPage works only if the object has a record detail page published in the site, and only if the user’s profile can see it. Otherwise the user gets an error page rather than a navigation failure you can catch.
  • The site’s base path sits in front of every URL, which is exactly why hand-built links break there.

Between LWR and Aura sites the behaviour also differs in places, so a component that navigates should be tested in the template the site actually uses rather than assumed to work from a Lightning Experience test.

One general limitation: navigation does not report success. There is no promise to catch and no error event when a destination cannot be reached. If the user lacks access, they see the platform’s error page. Check permissions before offering the link.

Frequently asked

How do I open a record in a new tab? Use GenerateUrl and render an anchor with target="_blank". Navigate replaces the current view by design.

Can I pass parameters to the destination? Yes, through state. Keys on a custom page must begin with c__, and values arrive as strings.

Why does my navigation do nothing? Most often the mixin was not applied, or Navigate was called without the bracket syntax. Both fail quietly.

Does it work in a quick action? Yes, and you should close the action afterwards with CloseActionScreenEvent, otherwise the modal can linger over the new page.