Search code examples
javascriptreactjsreact-routerreduxreact-router-redux

react-router ignoring nested routes when providing url with path


I'm playing around with the react and redux trying to put together a basic app with react-routes. At the moment I have managed to put the following together which works for the Wrapper and the Home page, however the 'apps' page doesn't seem to load if I go to localhost:8080/apps. I just get a 404 every time.

Any ideas where I may have gone wrong here?

There are no errors or warnings in the console and I've tried looking through several examples online however none of them seemed to be particularly different to what I have,

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import { browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';

import Routes from './routes/routes';
import { configureStore } from './store/configureStore';

const rootElem = document.getElementById('mount');

const store = configureStore(browserHistory);
const history = syncHistoryWithStore(browserHistory, store);

const provider = <Provider store={store}><Routes history={history} /></Provider>;

ReactDOM.render(provider, rootElem);

routes/routes.js

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

import { Wrapper, Home, Apps } from './../views';

class Routes extends React.Component {

    render () {

        const { history } = this.props;

        return(
            <Router history={history}>
                <Route path='/' component={Wrapper}>
                    <IndexRoute component={Home}/>
                    <Route path='apps' component={Apps}/>
                </Route>
            </Router>
        );
    }
}

Routes.propTypes = {
    history: React.PropTypes.object.isRequired
};

export default Routes;

store/configureStore.js

import { createStore, applyMiddleware, compose } from 'redux';
import { routerMiddleware } from 'react-router-redux'
import createLogger from "redux-logger";
import thunk from 'redux-thunk';

import rootReducer from './../reducers'

export function configureStore(history, initialState = {}) {

    const logger = createLogger();
    const middleware = routerMiddleware(history);

    const store = createStore(
        rootReducer,
        initialState,
        compose(
            applyMiddleware(thunk, middleware, logger),
            window.devToolsExtension ? window.devToolsExtension() : f => f
        )
    );

    return store;
}

reducers/index.js

import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';

export default combineReducers({
    //...reducers,
    routing: routerReducer
});

Solution

  • You're using browserHistory from react-router, so your server needs to be able to handle deep links and still serve the correct file. Since you're connecting to port 8080, I assume you are probably using webpack-dev-server.

    You could just switch to hashHistory and everything will work. The react-router docs explain setting up the server to work with browserHistory: https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md

    For webpack-dev-server you simply need to pass an extra option in the config object: historyApiFallback: true. This will make the dev-server return the index.html for any deeply-linked requests, using connect-history-api-fallback.

    ...
    devServer: {
      historyApiFallback: true
    }
    ...