Reputation:
In ReactJS I had a project, before the error I get now, everything was working, and I don't remember I Did something wrong. On my dev localhost, the URL is working, but when I publish on the server and run prod only the index page works, others don't even the default 404 Error page.
Here are the dependencies I use:
"dependencies": {
"history": "^5.0.0",
"local-storage-fallback": "^4.1.1",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-helmet": "^6.1.0",
"react-meta-tags": "^1.0.1",
"react-router-dom": "^4.3.1",
"react-scripts": "1.1.4",
"styled-components": "^5.2.1",
"styled-theming": "^2.2.0"
}
Also here is the ViewPort I use to set up routing:
import React, {Component} from 'react';
import {
BrowserRouter as Router,
Route,
Switch,
Redirect
} from 'react-router-dom';
import Home from './pages/Home.js';
import Regulations from './pages/Regulations.js';
import We from './pages/We.js';
import Error from './pages/Error.js';
import List from './pages/List.js';
import Article01 from './stories/Article01.js';
class ViewPort extends Component {
render() {
return <Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/regulations" component={Regulations} />
<Route path="/we" component={We} />
<Route path="/feed" component={List} />
<Route path="/stories/article01" component={Article01} />
<Route path="/404" component={Error} />
<Redirect to="/404" />
</Switch>
</Router>
}
}
export default ViewPort;
Here is the Webpack.config.js:
'use strict';
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.pug$/,
use: [
'pug-loader?self'
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
},
plugins: [
new UglifyJSPlugin()
]
};
ExpressWebServer Code:
const express = require("express");
const bodyParser = require("body-parser");
const Papa = require("papaparse");
const fs = require("fs");
const path = require("path");
const http = require('http');
const https = require('https');
const app = express();
app.use(express.static(path.join(__dirname, "client/build")));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.get("/api", (req, res) => {
const data = [
{
hide: "I remove the data for safety",
},
];
res.json(data);
console.log("Data successfully was sent.");
});
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, '../client/build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
}
if (process.env.NODE_ENV === "production") {
const privateKey = fs.readFileSync('/etc/letsencrypt/live/mysite.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/mysite.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/mysite.com/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
https.createServer(credentials, app).listen(443, () => {
console.log('Server is running on port 443');
});
http.createServer(function (req, res) {
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url});
res.end();
}).listen(80);
} else if (process.env.NODE_ENV === "development") {
app.listen(9000);
} else {
app.listen(9000);
}
It would be nice for someone if can check why this isn't working when I publish, but only on my localhost.
Upvotes: 1
Views: 1098
Reputation: 282050
The reason you do get 404 is because when you are on a nested route, you request the server to serve you your file but it only sends you index.html for /
and hence for other paths it gives you 404 since you haven't configured the response.
The solution here is to serve the index.html
regardless of thee client path so that the routing can then take place on the client side. In case of webpack-dev-server we set historyApiFallback
to true
, for a express server you need to send index.html on app.get('*',
You can use the below code to make that chaange
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, '../client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
}
Upvotes: 1