Clement
Clement

Reputation: 4811

React-Router Nested Routes not working

Steps to reproduce

client.js (entry file)

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxThunk from 'redux-thunk';

import reducers from './reducers';
import routes from './routes.js';

const storeWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = storeWithMiddleware(reducers);

ReactDOM.render(
  <Provider store={store}>
    <Router history={browserHistory} routes={routes} />
  </Provider>, document.getElementById('app')
);

routes.js (ver 1)

import React from 'react';
import { Route, IndexRoute } from 'react-router';

import App from './components/bases/app.js';
import Login from './components/app/authentication/login.js';

export default(
  <Route path="/" component={App}>
    <Route path="signup" component={Login}/>
  </Route>
)

routes.js (ver 2)

let routes = {
  path: '/',
  component: App,
  childRoutes: [
    { path: 'signup', component: Login }
  ]
}

export default routes;

Expected Behavior

Expect to have /signup route avail.

Actual Behavior

react-router cannot find the route /signup but can find /

Having a look at the chrome dev-tools source-tab, this is what I find:

When looking at "/"

sources
--------
dist/prod
|     bundle.js
index.html

When looking at "/signup"

sources
--------
signup

Upvotes: 1

Views: 2029

Answers (2)

Paul S
Paul S

Reputation: 36827

The giveaway is the files that are being served when you are looking at the sources. When you are trying to load the /signup page, your browser is trying to load a signup page.

When you use browserHistory, you need to serve your index.html (and any scripts included in it) for all possible routes. This means that you need to have a server which accepts all possible routes and responds accordingly.

For example, if you are running a node server using express, you would need to have a wildcard route handler:

// define static handler first for .js, etc.
app.use(express.static(path.join(__dirname, 'public')));

// all other routes should server your index.html file
app.get("/", handleRender);
app.get("*", handleRender);

function handleRender(req, res){
  res.sendFile(__dirname + '/index.html');
}

Upvotes: 1

Lucas Katayama
Lucas Katayama

Reputation: 4580

If you changed to hashHistory and it worked it probably be your backend which serves the html...

Since hashHistory works like this:

example.com/#/signup

The browser doesn't understand as a new GET, if you use browseHistory, this:

example.com/signup

Makes the browser request for index.html again but on path /signup ... but the webpack dev server probably don't understand.. Try adding historyApiFallback: true to webpack config LIke this

https://github.com/amacneil/react-router-webpack-history-example

Upvotes: 2

Related Questions