react-router: Nested IndexRoute not working

I have this route setup, where I need nested IndexRoutes

<Route path="/admin" component={App}>
    <IndexRoute component={HomeBody}>
       <IndexRoute component={Overview}/>
    </IndexRoute>
    // more routes...
</Route>

But the inner IndexRoute doesn’t ever seem to resolve.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 5
  • Comments: 16 (13 by maintainers)

Most upvoted comments

@ryanflorence Sorry about writing to the closed issue. You’re saying that nesting IndexRoutes does not make sense, but why not? What if I need complex default structure without any redirects just at my root ('/' path)? As long as new api provides component attributes to every route why do you not allow to nest default route component via children?

Like this: (Here App and Authorized components just render their children)

<Route path="/" component={App}>
    <IndexRoute component={Authorized}>
        <IndexRoute component={Feed}/>
    </IndexRoute>
    <Route path="login" component={Login}/>
</Route>

Another way to accomplish the desired behavior would be using just Route components without path specified and inheriting it from parent but that is not working. Like this:

<Route path="/" component={App}>
    <Route component={Authorized}>
        <Route component={Feed}/>
    </Route>
    <Route path="login" component={Login}/>
</Route>

But actually this is just the same as using IndexRoute.

Your second example doesn’t work because it’s trying to express // as a path to navigate to. Each path, even if duplicated, becomes a node in the route tree, separated by slashes (or being a slash itself if there is nothing else in the path).

You’re really close. Here’s what you need:

<Route path="/" component={App}>
    <Route component={Authorized}>
        <IndexRoute component={Feed} />
    </Route>
    <Route component={LoginLayout}>
        <Route path="login" component={Login} />
        <Route path="forgot_password" component={ForgotPassword} />
    </Route>
</Route>

Edit: What @taion said.

That doesn’t make sense, index routes are leaf nodes, can’t be nested.

Should be

<Route path="/" component={App}>
    <Route component={Authorized}>
        <IndexRoute component={Feed} />
        ...
    </Route>
    <Route component={LoginLayout}>
        <Route path="login" component={Login} />
        ...
    </Route>
</Route>

@timdorr I appreciate (and I’m using) the solution you gave. However it seems somewhat non-intuitive to me that a Route could fall through to an IndexRoute that is not an immediate child. It seems odd that the grandparent would be able to figure that one of its path-less children has an IndexRoute, so it should go ahead and fall through. Am I missing something conceptually about React Router?

<Route path="/" component={App}>
    <Route component={Authorized}>
        <IndexRoute component={Feed} />
    </Route>
    <Route path="login" component={Login}/>
</Route>

Does that make sense? We can follow up on Reactiflux or Stack Overflow - the issue tracker is not great for this sort of Q&A thing.

Yeah, so it’s nothing conceptual and at some level it’s a bit sloppy, but in practice it’s really convenient for certain kinds of route definitions.

Maybe I am just confusing myself, but the discrepancies between the following cases are not intuitive:

This works:

<Route component={App}>
    <Route path="/ component={Authorized}>
        <IndexRoute component={Feed} />
        ...
    </Route>
    <Route path="/" component={LoginLayout}>
        <Route path="login" component={Login} />
        ...
    </Route>
</Route>

This does not work:

<Route path="/" component={App}>
    <Route path="/" component={Authorized}>
        <IndexRoute component={Feed} />
        ...
    </Route>
    <Route path="/" component={LoginLayout}>
        <Route path="login" component={Login} />
        ...
    </Route>
</Route>

This also does not work, but I think semantically captures what I am trying to do and should be supported:

<Route path="/" component={App}>
    <IndexRoute component={Authorized}>
        <IndexRoute component={Feed} />
        ...
    </Route>
    <Route path="/" component={LoginLayout}>
        <Route path="login" component={Login} />
        ...
    </Route>
</Route>