// Tutorial //

Introduction to Routing Using Stencil

Published on August 31, 2017
    Default avatar
    By Alligator.io
    Developer and author at DigitalOcean.
    Introduction to Routing Using Stencil

    @stencil/router is the NPM package to use with Stencil to make it easy to define routes for your web component-powered PWA. The API for the router is very similar to React Router’s, so you may already be familiar with the syntax.

    In this post we’ll build a simple example where we have global components for an app shell, header and menu, as well as 3 routes: home, about and contact.

    Setup & Configuration

    First, make sure you have the @stencil/router package installed in your project:

    $ npm install @stencil/router
    
    # or, using Yarn
    $ yarn add @stencil/router
    

    Next you’ll want to make sure that your Stencil config file’s config object contains a collections array with the router package:

    stencil.config.js
    exports.config = {
      bundles: [
        { components: ['app-shell', 'app-header', 'app-menu'] }
      ],
      collections: [
        { name: '@stencil/router' }
      ]
    };
    
    
    

    If you’re using Stencil’s starter app to initiate your project, the @stencil/router package and proper config will already be in place.

    Defining Routes

    Routes are defined in a global <stencil-router> element that contains <stencil-route> elements for each individual route definition. Routes will be rendered inside the stencil-router element.

    The <stencil-router> should have an id that the <stencil-route> elements can refer to. Here’s a simple example with our 3 routes:

    <stencil-router id="router">
      <stencil-route
        url="/"
        component="app-home"
        router="#router"
        exact={true}
      />
      <stencil-route
        url="/contact"
        component="app-contact"
        router="#router"
      />
      <stencil-route
        url="/about"
        component="app-about"
        router="#router"
      />
    </stencil-router>
    

    Notice the use of exact={true} on the root / url to match only the root path to the home component.

    We would place such route config in our app’s top level component, here app-shell. Here, our whole app root component could look like this:

    /components/app-shell/app-shell.tsx
    import { Component } from '@stencil/core';
    
    @Component({
      tag: 'app-shell'
    })
    export class AppComponent {
      render() {
        return [
          <app-header title="Fancy Alligator!" />,
    
          <app-menu />,
    
          <stencil-router id="router">
            <stencil-route
              url="/"
              component="app-home"
              router="#router"
              exact={true}
            />
            <stencil-route
              url="/contact"
              component="app-contact"
              router="#router"
            />
            <stencil-route
              url="/about"
              component="app-about"
              router="#router"
            />
          </stencil-router>
        ];
      }
    }
    

    The render method returns multiple top level elements. This can be done using an array of top level elements, like in the above example. Or, it can also be done by wrapping the 3 top level elements in a wrapping div element.

    Linking to a Route

    To link to a route with the app, use the <stencil-route-link> element with the id of the router and the url. Here for example, here’s the render method of our app-menu component:

    /components/app-menu/app-menu.tsx (partial)
    render() {
      return (
        <ul>
          <li>
            <stencil-route-link
              router="#router"
              url="/"
              activeClass="active"
              exact={true}
            >
              Home
            </stencil-route-link>
          </li>
          <li>
            <stencil-route-link
              router="#router"
              url="/about"
              activeClass="active"
            >
              About
            </stencil-route-link>
          </li>
          <li>
            <stencil-route-link
              router="#router"
              url="/contact"
              activeClass="active"
            >
              Contact
            </stencil-route-link>
          </li>
        </ul>
      );
    }
    

    Here we’re also using the activeClass property to set a class name on active routes. The root route also has its exact property set to true so that the active class gets added only on an exact match of the url.

    Passing Data to a Route

    You can also pass props to a route in its configuration using the componentProps property:

    <stencil-route
      url="/contact"
      component="app-contact"
      router="#router"
      componentProps={{ method: 'Walkie-talkie' }}
    />
    

    And then in the component it can be accessed using using the @Prop decorator:

    app-contact.tsx
    import { Component, Prop } from '@stencil/core';
    
    @Component({
      tag: 'app-contact'
    })
    export class ContactComponent {
      @Prop() method: string;
      render() {
        return <p>📞 Getting in touch by {this.method}</p>;
      }
    }
    

    👷‍ The Stencil router is in heavy development and the API is bound to change rapidly. Refer to the official repo for the latest changes.


    Want to learn more? Join the DigitalOcean Community!

    Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

    Sign up
    About the authors
    Default avatar
    Developer and author at DigitalOcean.

    Still looking for an answer?

    Was this helpful?
    Leave a comment