Newton Munene
Newton Munene

Reputation: 165

Nested Stencil Routes/Components

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.

Upvotes: 0

Views: 1741

Answers (3)

tomokat
tomokat

Reputation: 142

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)

Upvotes: 1

davidenke
davidenke

Reputation: 437

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

Upvotes: 1

Titsjmen
Titsjmen

Reputation: 809

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> 
) />

Upvotes: 1

Related Questions