'Why does react-router not works at vercel?
I am trying to publish a serverless web to vercel. I want to use react-router and this works good on my computer but when I deploy it It doesn't works Can somebody help me?
(I want to do it without server)
// My main code
import React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import Main from './routes/Main'
import Tos from './routes/Tos'
import Privacy from './routes/Privacy'
import NotFound from './routes/NotFound'
import Recruit from './routes/Recruit'
const App = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path = '/' component = {Main} />
<Route exact path = '/recruit' component = {Recruit} />
<Route exact path = '/tos' component = {Tos} />
<Route exact path = '/privacy' component = {Privacy} />
<Route component = {NotFound} />
</Switch>
</BrowserRouter>
)
}
export default App
Solution 1:[1]
Add a vercel.json
file at the root of your project, and use "rewrites" to rewrite all incoming paths to refer to your index path.
For example:
{
"rewrites": [
{"source": "/(.*)", "destination": "/"}
]
}
Check here for further information: https://vercel.com/docs/configuration#project/rewrites
Solution 2:[2]
Specifying each Route
In order to make the React Router work in Vercel I had to specify each route in the vercel.json
file, as mentioned in Surbina's answer. (Thanks btw, I used this solution for a quite some time)
{
"routes": [
{ "src": "/", "dest": "/" },
{ "src": "/recruit", "dest": "/" }
{ "src": "/tos", "dest": "/" }
// ....
]
}
But this may not be optimal depending on how many routes your application has, and honestly sometimes I forget to add new routes.
The "Match all" regex problem in Vercel
I tried the "match all" Regex as the source route [{ "src": "/*", "dest": "/" }]
, like I used to do in other hosting services, but for some Reason, Vercel server uses this routing for all requests, even when index.html
needs to request a file like bundle.js
, breaking the application.
Solution: Match routes but ignore files
And the solution I've found is using a Regex that matches all routes, except for routes that include a dot (.), which are usually files, like bundle.js
. Then you can request a url like /recruit
and it gets routed to /
since it doesn't have a dot.
The regex is /[^.]+
(Turns into ^/[^.]+$
on Vercel).
Please note that this is a very simple Regex and may not cover all cases, however, I haven't got any issues with it to the moment of this comment.
So my vercel.json
file looks like this:
{
"routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }]
}
I hope it is useful for you!
Solution 3:[3]
Maybe you need the server to redirect all requests to index.html. If Apache then you can use mod_rewrite and you would need some code like this:
RewriteCond %{REQUEST_URI} !^/index\.html
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/.*$ /index.html [L,PT]
Solution 4:[4]
It sounds like Vercel is looking in the wrong place for your files. Check the "homepage"
field in your package.json
; I've found that they're finicky, and sometimes what works when using localhost
doesn't work on a Vercel deployment. If you don't have a `"homepage" field, start by adding
"name": "my-app",
"homepage": ".",
...
in package.json
. That usually works for me, but if it doesn't, try the actual url of your deployment, i.e., https://something.vercel.app
. I have had to do that for certain setups.
If that still doesn't work, check the Network tab in devtools and find your request, and check what url it's actually looking for resources with. That might give you some clues.
Solution 5:[5]
Simply add this to your vercel.json, this will route all your routes to the index.html except for the js file
{
"routes": [
{
"src": "/[^.]+",
"dest": "/"
}
]
}
Solution 6:[6]
In vercel hosting service you can either deploy the whole project by selecting create-react-app in framework preset :
or you can deploy only the build folder after you've built the project by running npm run build
and select Other as Framework preset :
Note
If you're using react-router-dom with BrowserRouter you should have vercel.json file at the root of your project folder or your build folder :
{
"rewrites": [
{
"source": "/((?!api/.*).*)",
"destination": "/index.html"
}
]
}
This configuration will prevent your web application to have 404 error when you refresh the page or when you open other routes .
Hope it helped you .
Solution 7:[7]
I'm using Create React App and react-scripts for building the project and I had an issue similar issue. The problem was the sub-routes content wasn't loading when I click browser refresh on the vercel's deployed site but locally it works fine.
ex. if you go directly to this sub route it would failed
https://mysite/top/second
It turns out that the problem is in my package.json I had "homepage": "."
I simply fixed it by changing it "homepage": ""
(removing the dot)
react-scripts build
will read package.json
homepage
property and it will append the value from homepage
to all the paths that links the js and css bundled code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | broofa |
Solution 2 | Cristian Macedo |
Solution 3 | andriusain |
Solution 4 | |
Solution 5 | Ayub |
Solution 6 | Mahdi Faraji |
Solution 7 |