Glund Glund - 1 month ago 7
React JSX Question

Express + Webpack error after page reload

I have deployed a React app to Heroku. It works fine and all, but whenever I refresh a page that it's not the index ('/'), I keep getting an error: Cannot GET /project/post1.

I have no idea why this is happenning. I configured my express server to serve my static files on all routes, but its not working.

My file structure looks something like this:

-dist
- bundle.js
- index.html
-server.js


This is my server.js file:

var express = require('express');
var path = require('path');

var app = express();

var isProduction = process.env.NODE_ENV === 'production';
var port = isProduction ? process.env.PORT : 3000;
var publicPath = path.resolve(__dirname, './dist');

app.use(express.static(publicPath));

app.get('*', function(request, response) {
response.sendFile(path.join(publicPath))
});

// And run the server
app.listen(port, function () {
console.log('Server running on port ' + port);
});


This is my webpack.prod.config file:

var webpack = require('webpack');

module.exports = {
entry: {
main: './src/index.js'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: __dirname + '/dist',
publicPath: '/dist/',
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel'
},
{
test: /\.scss$/,
loader: 'style!css!sass'
}]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
})
]
};


I call my bundle.js file in the index.html like this:

<body>
<div id="app"></div>

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

Answer

Your routing happens on the client, not the server. Express doesn't know what it should do on a GET request on /project/post1.

So we send all requests to the client, where you have react-router running. We can do that by configuring a fallback in the server.js file, for example like this:

import fallback from 'express-history-api-fallback';
import express from 'express';
import http from 'http';

// Set up express
const app = express();
const server = http.createServer(app);
const root = `${__dirname}`;

// History Fallback for express
app.use(express.static(root));
app.use(fallback('index.html', { root }));

// Listen
server.listen(8080, '0.0.0.0');