8

I would like to know the best practice for routing in LWC. I mean, how to show a specific component on a specific URL, how to go to another route from a component, etc. If you can show me an example I would be grateful. Thanks!

2 Answers 2

9

There's a demo up on GitHub from the TDX session on using LWC outside of Salesforce.

That uses Navigo for routing in the app module. Here's a slimmed down version of the routing from that example with some comments from my own experience trying to implement this:

import { LightningElement, createElement, track } from 'lwc';
import Navigo from 'navigo'; // import Navigo

export default class App extends LightningElement {

    // instantiate the router class
    router = new Navigo(location.origin, false);

    constructor() {
        super();
       // define your routes. The await functions are for use with chunking but you could remove them and just do a normal import if all of your scripts are loaded at once
        this.router.on({
            '/podcasts': async () => {
                const { default: ViewPodcasts } = await import(/* webpackChunkName: "view-podcasts" */ 'view/podcasts');
                this.setPage('view-podcasts', ViewPodcasts);
            },
            '/podcasts/:id': async ({ id }) => {
                const { default: ViewPodcast } = await import(/* webpackChunkName: "view-podcast" */ 'view/podcast');
                this.setPage('view-podcast', ViewPodcast, {
                    podcastId: parseInt(id, 10),
                });
            },
            '/discover': async () => {
                const { default: ViewDiscover } = await import(/* webpackChunkName: "view-discover" */ 'view/discover');
                this.setPage('view-discover', ViewDiscover);
            },
            '/categories/:id': async ({ id }) => {
                const { default: PodcastList } = await import(/* webpackChunkName: "view-category" */ 'view/category');
                this.setPage('view-category', PodcastList, {
                    categoryId: parseInt(id, 10),
                });
            },
        });

        const navigateToDefault = () => {
            this.router.navigate('/podcasts');
        };

        this.router.notFound(navigateToDefault);
        this.router.on(navigateToDefault);
    }

    renderedCallback() {
        // Resolve the current view only after the container has rendered
        if (!this.isRendered) {
            this.isRendered = true;
            this.router.resolve();
        }
    }

    setPage(tagName, component, props = {}) {
     // when a route is called, create the related component and insert it into the DOM in whatever container you want
        const el = createElement(tagName, {
            is: component,
            fallback: false,
        });

        Object.assign(el, props);

        // Remove previous components from the container if necessary
        const container = this.template.querySelector('.container');
        while (container.firstChild) {
            container.removeChild(container.firstChild);
        }

        container.appendChild(el);
    }
}
4
  • Thanks John. When 'setPage' function is called there is an error: DOMException: Failed to execute 'attachShadow' on 'Element'. The component argument seems to be ok. Do you know why this happens? Thanks! Commented Jun 21, 2019 at 14:46
  • It sounds like maybe the element that you're trying to append to doesn't exist. You should try updating const container = this.template.querySelector('.container'); so it looks for an element in your template or add a div with a class of 'container' to your template. Commented Jun 21, 2019 at 14:53
  • Yes, I did it, but it fails on the first line. On the 'createElement' call, before the query. Commented Jun 21, 2019 at 14:55
  • 1
    I fixed it! The problem was a bad tagName. Thanks! Commented Jun 21, 2019 at 15:23
0

I have some question regarding on this. Since LWC doesn't support createElement we can't use navigo to implement the routing?

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .