I\'m using React-router and it works fine while I\'m clicking on link buttons, but when I refresh my webpage it does not load what I want.
For instance, I am in
The answers here are all extremely helpful, what worked for me was configuring my Webpack server to expect the routes.
devServer: {
historyApiFallback: true,
contentBase: './',
hot: true
},
The historyApiFallback is what fixed this issue for me. Now routing works correctly and I can refresh the page or type in the URL directly. No need to worry about work arounds on your node server. This answer obviously only works if you're using webpack.
EDIT: see my answer here for a more detailed reason why this is necessary: https://stackoverflow.com/a/37622953/5217568
I used create-react-app to make a website just now and had the same issue presented here. I use BrowserRouting
from the react-router-dom
package. I am running on a Nginx server and what solved it for me was adding the following to /etc/nginx/yourconfig.conf
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
}
Which corresponds to adding the following to the .htaccess
in case you are running Appache
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
This also seems to be the solution suggested by Facebook themselves and can be found here
Production stack: React, React Router v4, BrowswerRouter, Express, Nginx
1) User BrowserRouter for pretty urls
// app.js
import { BrowserRouter as Router } from 'react-router-dom'
const App = () {
render() {
return (
<Router>
// your routes here
</Router>
)
}
}
2) Add index.html to all unknown requests by using /*
// server.js
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
})
3) bundle webpack with webpack -p
4) run nodemon server.js
or node server.js
EDIT: You may want to let nginx handle this in the server block and disregard step 2:
location / {
try_files $uri /index.html;
}
I found the solution for my SPA with react router (Apache). Just add in .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
source: https://gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042
you can try reading this all though it's not mine:
https://www.andreasreiterer.at/fix-browserrouter-on-apache/
Fixing the app’s routing Now here’s how to finally fix the routing. To tell Apache to redirect requests to index.html where our app lives, we have to modify the .htaccess file. If there is no such file in your app’s folder yet, just create it.
Then be sure that you put in those 4 lines that will magically make your routing work.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
After we put that .htaccess file into the same directory as the index.html, Apache will redirect each new request directly to your app.
Bonus: Deploying the React app to a sub directory
If you’re deploying your app into a sub directory, so it’s accessible e.g. via https://myapp.com/the-app, you’ll soon notice that there is another issue. Each click to a new route will transform the URL to something like https://myapp.com/route-abc – which will break again after a reload. But there is a simple fix for that:
BrowserRouter has a prop called basename where you can specify your sub-directory path:
From now on, each Route like /contacts will result in an URL like http://myapp.com/the-app/contacts.
You can change your .htaccess
file and insert this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
I am using react: "^16.12.0"
and react-router: "^5.1.2"
This method is the Catch-all and is probably the easiest way to get you started.