keinsell
keinsell

Reputation: 518

React.js (Vite-based) SPA returns 404 when deployed to Vercel within mono-repository

I have boilerplate-like single-page application with wouter-based routing - application is functional in local environment. Goal I'm trying to archive is deployment of mentioned application to vercel, yet there is a problem in application routing - things are ok when I run application locally but it returns Not Found (404) errors when it's deployed to cloud.

Deployment has no problem when it's run through procfile, Docker Container or "bare-metal" - but one it touches Vercel's Edge application do not care about routing at all.

I have tried multiple routing libraries (wouter, react-router) and problem still existed and behaved without any difference.

Implementation of routing is correct, and path rewrites which are required and recommended by Vercel are configured in vercel.json and are provided below.

{
    "github": {
        "silent": true
    },
    "rewrites": [
        {
            "source": "(.*)",
            "destination": "/index.html"
        }
    ]
}

Commonly proposed solution for similar Vercel-related problems was following configuration yet this still do not change outcome at all.

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

My file structure is following, as my project is mono-repository managed by turbo.

.
├── apps/
│   └── web/
│       ├── src
│       └── package.json
└── vercel.json

Upvotes: 8

Views: 12503

Answers (3)

keinsell
keinsell

Reputation: 518

TL;DR

For monorepository configurations vercel.json should be contained under $ROOT/$PROJECT/vercel.json instead $ROOT/vercel.json.

$ROOT/$PROJECT/vercel.json

{
    "github": {
        "silent": true
    },
    "rewrites": [
        {
            "source": "(.*)",
            "destination": "/index.html"
        }
    ]
}

Configuration in vercel.json was correct at the time it was added to question, the issue was not present in project configurations that were single-package repositories with vercel.json at Root Directory along package.json. Yet with monorepository approach same configuration had different behaviour than expected (as one in single-package repository) - solution for such problem was moving vercel.json into Project Directory of repository where package.json was contained (the one which indicates workspace, instead one which indicates given React.js project).

Upvotes: 0

Mohamed Ali Ben Thaier
Mohamed Ali Ben Thaier

Reputation: 180

TLDR

Add an empty 404.html in the public folder (you can put the title in the title tag) with this script in the head section

<script type="text/javascript">
  var pathSegmentsToKeep = 0;

  var l = window.location;
  l.replace(
    l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
    l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
    l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
    (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
    l.hash
  );
    </script>

Then add this script to your index.html

<script type="text/javascript">
  (function(l) {
    if (l.search[1] === '/' ) {
      var decoded = l.search.slice(1).split('&').map(function(s) { 
        return s.replace(/~and~/g, '&')
      }).join('?');
      window.history.replaceState(null, null,
          l.pathname.slice(0, -1) + decoded + l.hash
      );
    }
  }(window.location))
    </script>

This worked perfectly for me after deploying my app to render.com

To handle the "real" not found response, you can add this route

<Route path="*" element={<p>Page not found</p>} />

For more information you can visit this repo spa-github-pages

Credits to @rafgraph

Upvotes: 1

Kaio Dutra
Kaio Dutra

Reputation: 396

You can a create simple rewrites rules in the serve. In my case I use Vercel. Then you can find something similar this.

Create in the project root a file vercel.json

And writer

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

P.S.: Don't forget to enable rewrites in vercel.

Upvotes: 18

Related Questions