Search code examples
node.jsreactjsreact-routerbrowser-historyreact-routing

Minimum nodejs server setup needed for React using react-router and browserHistory


My current server.js:

let express = require('express');
let harp = require('harp');
let path = require('path');

let app = express();

app.use(express.static(__dirname + "/dist"));
app.use(harp.mount(__dirname + "/dist"));

let port = process.env.PORT || 3333;
app.listen(port, () => console.log("Listening on port " + port) );

// ... other routes for data fetching ...

// For browserHistory: https://github.com/reactjs/react-router/blob/1.0.x/docs/guides/basics/Histories.md
app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});

This works fine when I start navigation at mysite.com/. However, if I enter mySite.com/someRoute, it breaks. Specifically, I see the below in console:

Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:3333/dashboards/styles/normalize-3.0.3.min.css".
...
Uncaught SyntaxError: Unexpected token <
...

My understanding is that to fix this I also need to implement server-side rendering. Is that accurate? If so, what is the minimum setup needed for that? All the guides I've seen are much more in-depth than I would like to go right now.

(I am fine upgrading dependencies if it will help.) react: 0.14.7 react-router: 1.0.3


Solution

  • Assuming your css file is in your static folder and that the path for the file matches the path below __dirname + "/dist" and that you are NOT navigating to /someRoute within your app but directing browser to that address via the address bar, I suspect the problem is you are serving the index.html when you need to serve the css file. (You gave us the error that the browser reported, but not the actual response from server for that request.)

    This is caused by directing the browser towards mySite.com/someRoute. The browser now thinks /someRoute is the root path of all requests when using relative urls. So if the index.html page requires assets/css/mysite.css. The browser will actually send a request for someRoute/assets/css/mysite.css. You can verify this by watching the network tab in your browser.

    To fix this, set the base tag to / in your <head>. This will tell the browser to not prefix any path on relative urls.

    Example:

    <head>
      <base href="/">
      <link >
    </head>