// Tutorial //

Introduction to Routing Using Stencil

Published on August 31, 2017
    Default avatar

    By Alligator.io

    Introduction to Routing Using Stencil

    While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

    @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.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about us


    About the authors
    Default avatar
    Alligator.io

    author

    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
     
    Leave a comment
    

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    card icon
    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Sign up
    card icon
    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We’d like to help.

    Learn more
    card icon
    Become a contributor

    You get paid; we donate to tech nonprofits.

    Learn more
    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow – whether you’re running one virtual machine or ten thousand.

    Learn more ->
    DigitalOcean Cloud Control Panel
    Get started for free

    Enter your email to get $200 in credit for your first 60 days with DigitalOcean.

    New accounts only. By submitting your email you agree to our Privacy Policy.

    © 2023 DigitalOcean, LLC.