I’ve been trying to implement nested routes/components. Can someone just please explain to me how to nest routes/components. The stencil route docs aren’t of much help.
Say In my component I have on the left a sidenav with a couple of stencil-route-link
then on the right I should show the routed component.

- 145
- 3
- 12
3 Answers
StencilJS docs state:
You should have one single stencil-router component in your project. This component controls all interactions with the browser history and it aggregates updates through an event system.
So there's going to be one place to define your routes. There's also an example on their webpage:
<stencil-router>
<stencil-route url="/" component="landing-page" exact={true}/>
<stencil-route url="/demos" component="demos-page"/>
<stencil-route url="/demos/rendering" component="fiber-demo"/>
</stencil-router>
Entering /demos/rendering
would render both demos-page and fiber-demo components. They won't be nested though.
The docs also mention the routeRender
attribute, which can be used to do some sort of nesting. For example:
<stencil-route url="/" exact={true} routeRender={(props) => (
<app-root history={props.history}>
<app-sidebar />
<app-content />
</app-root>
) />

- 789
- 6
- 15
As the Stencil team has still not released a wiki entry for this, here's a little update to this topic using @stencil/core: 1.3.2
and @stencil/router: 1.0.1
.
The trick is to use the routeRender
property in combination with slot
s and inline child routes:
<stencil-router>
<stencil-route-switch>
<stencil-route url="/"
exact={ true }
component="app-home"
/>
<stencil-route url="/me"
routeRender={ () => (
<app-me>
<stencil-route url="/me/login"
component="app-login"
/>
<stencil-route url="/me/profile"
component="app-profile"
/>
</app-me>
) }
/>
</stencil-route-switch>
</stencil-router>;
If you define the child routes inside your component (in this example app-me
) the route may not be recovered after a reload or by navigating directly to it. Thus you have to define them inside your global stencil-route-switch
.

- 436
- 6
- 13
-
Very nice. I'll give it a try. – Newton Munene Sep 04 '19 at 14:50
I know this is kind of old question but took me some time to figure this out, so I want to share here in case someone run into similar issues.
<stencil-router>
<stencil-route-switch scrollTopOffset={0}>
<stencil-route url="/" component="app-home" exact={true} />
<stencil-route url="/profile/:name" component="app-profile" />
<stencil-route>
<stencil-route-switch scrollTopOffset={0}>
<stencil-route url="/" component="app-home" exact={true} />
<stencil-route url="/profile/:name" component="app-profile" />
<stencil-route url="/docs" routeRender={()=>
<div>
<div>Document Heading</div>
<stencil-route-link url="/docs/setup">Setup</stencil-route-link>
<stencil-route-link url="/docs/todo">TODO</stencil-route-link>
<stencil-route-link url="/docs/profile">Profile</stencil-route-link>
<stencil-route url="/docs/setup" routeRender={()=>
<div>Set up document</div>}>
</stencil-route>
<stencil-route url="/docs/todo" routeRender={()=>
<div>TODO document</div>}>
</stencil-route>
<stencil-route url="/docs/profile" component="app-home" />
</div>
}>
</stencil-route>
</stencil-route-switch>
</stencil-router>
Some quick explanation:
- As titsjmen shared, looks like it is important to have only one component within your app
- You can, however nest "stencil-route" and hopefully with the code example above you can see it how it works. I tested it with both using routeRender as well as component approach (both works!)
Hopefully this will be useful to someone :)
EDIT (additional note): In case this is not clear, this code block represents the area where you want to swap components based on the URL - back to original question, to achieve what you want, side nav can be just a matter of having bunch of "stencil-router-link" (which doesn't have to be placed in the same component - I have separate component called "sidenav-item" and seem to work well)

- 142
- 1
- 8