React-router app works in dev but not after Vercel deployment

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

The result is a 404 NOT_FOUND error

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

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!

1

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": "/"
    }
  ]
}

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 .

create vercel.json file in root directory and paste the code

{
   "rewrites":  [
       {"source": "/(.*)", "destination": "/"}
    ]
}

Here is something that worked for me

{
  "rewrites": [
    {
      "source": "/:path((?!api/).*)",
      "destination": "/index.html"
    },
    {
      "source": "/:path(api/.*)",
      "destination": "/api"
    }
  ]
}

docs : https://vercel.com/docs/concepts/projects/project-configuration#rewrites

Since I had the same issue and none of the above fixed it, I created a medium post to explain how to solve this issue.

Step 1: In the root of your project, you need a vercel.json file. This is the configuration file Vercel uses to understand how to handle your project.

Step 2: Update the vercel.json file with the following content:
(this vercel.json file is for a frontend React app with a nodejs backend)

{
  "version": 2,
  "builds": [
    {
      "src": "api/index.js",
      "use": "@vercel/node"
    },
    {
      "src": "client/package.json",
      "use": "@vercel/static-build",
      "config": {
        "distDir": "build"
      }
    }
  ],
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "/api/index.js"
    },
    {
      "src": "^/static/(.*)",
      "dest": "/client/static/$1"
    },
    {
       "src": "/(.*)\.png",
       "dest": "/client/$1.png"
     },
    {
      "src": "/(.*)",
      "dest": "/client/index.html"
    }
  ]
}

Here’s how this configuration works:

“src”: “api/index.js” tells Vercel to use @vercel/node to handle serverless functions in the /api directory.
“src”: “client/package.json” tells Vercel to use @vercel/static-build to build your React App located in the /client directory.
“src”: “/api/(.)”, “dest”: “/api/index.js” handles all API requests and directs them to the appropriate serverless function under the /api directory.
“src”: “^/static/(.
)”, “dest”: “/client/static/$1” ensures that static assets under the /static directory are served correctly.
“src”: “/(.*)”, “dest”: “/client/index.html” handles all other routes by serving the index.html file. This allows React Router to take over and render the appropriate component based on the route.

1

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.

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.

You can also run (your production build) like

yarn serve build -s

-s option redirects all not found paths to index.html, so you don’t even need the serve.json/vercel.json file


{
  "routes": [
    { "src": "/[^.]+", "dest": "/", "status": 200 }
  ]
}

This solution worked and the redirects worked.

I also tried the first solution where there are too many infinite redirects.

I don’t have any reputation to answer directly to Andrew, but this is some very important information! Assigning the vercel homepage URL to the homepage was what worked for me! I was having a problem where any dynamic route (using params) would not be recognized in vercel production build, yet working flawlessly in localhost. After many tries, this is what worked for me!

package.json:

{
name: 'yourapp',
homepage: 'https://yourapp.vercel.app'
/*...*/
}

if you having same issue try this:

create vercel.json in your project route
and write this code. This code work for especially you use react router

{ "routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }] }

This is the best answer I got. So when ever you refereshed on any route like “/admin” so it first take you to “/” route and then from your code, allow user to Navigate to Admin.

{
  "routes": [
    { "src": "/[^.]+", "dest": "/", "status": 200 }
  ]
}

Yes I also faced the same problem, let’s see the best solution for this.

Here I have some routes in App.js file

<BrowserRouter>
  <Routes>
    <Route path="/login" element={<SignIn />} />
    <Route path="/login/phone-verification" element={<PhoneVerification 
     />} />
    <Route path="/" element={<LandingPage />} />
    <Route path="/topics" element={<LandingTopics />} />
  </Routes>

</BrowserRouter>

For this routes need to fix the issue
create vercel.json file at root projects and add following objects in that file

{
"routes": [
  { "src": "/login", "dest": "/" },
  { "src": "/login/phone-verification", "dest": "/" },
  { "src": "/topics", "dest": "/" },
  { "src": "/", "dest": "/" }
]
}

You can change according your routes.

In my case I added the following code inside vercel.json in project folder(not inside src)

{
 "rewrites": [{ "source": "/(.*)", 
 "destination": "/" }]
}

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]

0

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật