Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-router not returning content for nested routes on page load

My react app works as expected for first level routes such as /, /foo, and /bar, both when using the apps navigation menu or when typing the url directly into the browsers address bar.

However deeper urls such as /foo/bar only work when using the apps navigation menu but not when the url is directly input into the browsers address bar.

For depper URLs, When refreshing the page or typing the url directly into the address bar the sites index.html is displayed (a white screen as no content or styles are loaded), but it appears to not be being rendered by react as no errors are present in the console, and the react dev tools show a blank screen.

I am using react-router 4.0.0, and webpack-dev-server with the --history-api-fallback option set. I have tried switching the server to express and setting up a catch all to redirect all routes to the index.html, as well as downgrading to react-router 3.0.2 however the problem persisted in both instances.

I cut my code down to a bare minimum of just the router and a few bare bone components I am trying to route to.

App Entry Point (index.js)

import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

// import components
import AppContainer from './components/AppContainer';

render(
    <LocaleProvider>
        <BrowserRouter>
            <AppContainer/>
        </BrowserRouter>
    </LocaleProvider>, 
    document.querySelector('#main')
);

AppContainer component

import React from 'react';
import { Route, Switch, Link } from 'react-router-dom';

// import components
import Home from './Home';
import About from './About';
import Test from './Test';
import NotFound from './NotFound';

class AppContainer extends React.Component {
    render() {
        return (
            <div>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/about">About</Link></li>
                    <li><Link to="/asdasdhuahfisd">404 Test</Link></li>
                    <li><Link to="/about/test">About/Test</Link></li>
                </ul>

                <Switch>
                    <Route path="/" exact component={Home} />
                    <Route path="/about/test" component={Test} />
                    <Route path="/about" component={About} />
                    <Route component={NotFound} />
                </Switch>
            </div>
        );
    }
}

export default AppContainer;
like image 511
Jeemusu Avatar asked Mar 17 '17 07:03

Jeemusu


1 Answers

I managed to narrow down the issue to the html-webpack-plugin that I was using to inject a <script> tag for the generated js file into the body of the app. The script tags src was being generated as a relative url src="main.js", so refreshing the page on deep urls causes the javascript file to not be found, and thus the react app was not loading.

A quick look at html-webpack-plugin code shows that the url for the javascript file is generated from the webpack config variable output.publicPath which I hadn't set in my app. Adding the below code to my webpack.config.js fixed the issue.

output: {
    publicPath: '/'
},
like image 166
Jeemusu Avatar answered Sep 21 '22 20:09

Jeemusu