Alligator.io
@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.
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:
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.
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:
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.
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:
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.
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:
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.
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.
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!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.