6

I have a small problem there are few similar questions on SA already but I can't figure out how to fix this. I am using react-router-redux but for this example I don't think there are any differences to using react-router

I have a simple setup:

<Router history={browserHistory}>
  <Route path="/">
    <IndexRoute component={ItemList}/> 
    <Route path='item/:uuid' component={Item}/> 
  <Route>
<Router>

I am using:

  • webpack
  • webpack-dev-server
  • html-webpack-plugin

When i visit localhost:8080 the IndexRoute is rendered. I can then press one of the items which has onClick={() => this.props.dispatch(routeActions.push('/item/' + item.uuid))} set. The history at this stage works fine I can go back and select another item and so on. But...

When I am on a item page for example localhost:8080/item/1234 and when I hit refresh I get:

404 not found - localhost:8080/item/bundle.js

This as well happens when I make some changes to the item page and hot reloading is rerendering it.

After going through few questions I can confirm that I have historyApiFallback: true and when I start the server it is reporting that 404s will fallback to /index.html

Update:

So when I hit refresh after being on localhost:8080/item/1234 chrome inspect say that was 200 response from server which looks like:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Damage Increased</title>
  </head>
  <body> 
    <script src="bundle.js"></script>
  </body>
</html>

And then it is 404 on http://localhost:8080/item/bundle.js

It looks like all the dev server stuff is working fine and the server indeed returns the index file but then the <script src="bundle.js"></script> is looking for a bundle.js file inside of the /item sub.

Kocur4d
  • 6,701
  • 8
  • 35
  • 53

2 Answers2

6

Instead of:

<script src="bundle.js"></script>

Do:

<script src="/bundle.js"></script>

Because when you access directly /item/1234, currently, you have a relative link to bundle.js so the browser will call /item/bundle.js.

If you're using html-webpack-plugin, you can add some rewrite rules to your dev-server (which you will have to add to your production one) - see more here

topheman
  • 7,422
  • 4
  • 24
  • 33
  • this file is generated by html-webpack-plugin – Kocur4d Feb 14 '16 at 16:31
  • @Kocur4d made some edits to my answer - your problem seems to be between the `html-webpack-plugin` and the config of your `webpack-dev-server` – topheman Feb 14 '16 at 16:45
  • yes it looks like as when i remove the /item from both routes and the push state action- and leave justa shallow mapping of /:uuid - it is all working fine. webpack have a publicPath option I try something with it. Never seen anyone mention publicPath before tho. – Kocur4d Feb 14 '16 at 16:53
  • 1
    yes adding `output.publicPath = '/'` to webpack config fix the problem but I am not sure if this is how it needs to be done I never have to set publicPath before into my webpack config. Any thoughts on this? – Kocur4d Feb 14 '16 at 17:02
  • I don't use `html-webpack-plugin` or at least, I provide my own template which gives me full control above that kind of thing (in those cases, most of the time, it's either using hashHistory - so no problem of that kind - or [server-side rendering](https://github.com/topheman/react-es6-isomorphic/blob/master/server/views/layout.ejs) - so the html is rendered by the server based on a template) – topheman Feb 14 '16 at 17:08
  • ye I went a bit of a quick easy road with webpack setup - coming from ruby-on-rails the entire webpack adventure was like a black magic to me. Do you have any good resources on how to setup a universal react app something not too deep and considered best practices? As most of my projects now end up being two separate apps(react in front and rails-api in a backend) as there is so many resources out there on how to set it up that i got lost. – Kocur4d Feb 14 '16 at 17:19
  • 1
    *easy road with webpack setup* > ;-) webpack docs is not the best one ever, lots of people get lost with it. Here are some resources that could be of some use for you [server-side rendering with react](https://github.com/erikras/react-redux-universal-hot-example) - [webpack configuration](https://github.com/petehunt/webpack-howto) + [some webpack tips](http://dev.topheman.com/tag/webpack/). Good luck @Kocur4d – topheman Feb 14 '16 at 17:27
1

my problem was solved by adding historyApiFallback: true in webpack.config devServer section and <base href="/"> in the head

<!DOCTYPE html>
 <html>
  <head>
   <base href="/">

    <link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
    <link
     rel="stylesheet"
     type="text/css"
     href="fonts/font-awesome/css/font-awesome.css"
    />
    <link rel="stylesheet" type="text/css" href="css/style.css" />
  </head>
  <body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top" >
   <div id="root"></div>
   <script type="text/javascript" src="js/jquery.1.11.1.js"></script>
   <script type="text/javascript" src="js/bootstrap.js"></script>
  </body>

 </html>

In this project, I used external resources such as bootstrap and some styles that were added in the head tag, as well as javascript files in the index.html file, but instead of this way it is better to add them in package.json and Imported in components.

Hamed Lohi
  • 540
  • 5
  • 14