Search code examples
reactjscreate-react-app

Issues deploying react under custom root path "/app" with create-react-app and react-router


I'm deploying an app on a host that has the following setup:

I need to deploy under a custom root path /app for my React app that will sit under this umbrella. I'm using react-router v5 and create-react-app.

Problem

When I build the app (I'm using vercel's serve), I get a blank page. When I go to localhost:5000/app/, nothing shows up.

I did all the suggestions from here and here, but still can't get my app to load.

I'm also confused: what's the difference between using react-router's basename and CRA's homepage field? Should I be using both, or one or the other?

EDIT: Potentially found the problem. Setting homepage=/app also changes the paths for my JS bundle, which it wasn't recognizing (hence the blank page). I manually added a app folder inside my build dir, like so: build/app/static and it worked. Shouldn't CRA do this automatically?

My setup

app.tsx

<Router basename={process.env.PUBLIC_URL}>
  ...
</Router>

package.json

scripts: {
  "build-prod": "GENERATE_SOURCEMAP=false REACT_APP_ENVIRONMENT=production react-app-rewired build",
},
...
"homepage": "/app",

Command to serve the prod build locally

> npm run build-prod && serve -s build -l tcp://0.0.0.0:5000

The project was built assuming it is hosted at /app/.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.

Find out more about deployment here:

  bit.ly/CRA-deploy

I navigate to http://0.0.0.0:5000/app/ and get a blank page (no network calls).

What I tried

  • set homepage: "/app" in package.json source
  • set the basename for react-router source
  • The CRA docs shows an example using the full path of the website. That didn't work either:
"homepage": "https://example.com/app",

Solution

  • I got it working, although it's a workaround.

    As Mohit's comment mentions, the homepage field makes it so all the assets are pre-pended by that sub-path defined in homepage. I was getting a blank screen because it couldn't find the new path to my JS bundle, aka it went from serving /build/static/js/.. to /build/app/static/js/...

    Solution (workaround)

    • Create a new folder called app (or whatever your new root path is called) under your build directory.
    • Move your /build/static folder to build/app/static.
    • This is what it looks like with Dockerfile:
    RUN pwd
    RUN echo $(ls -1 $pwd)
    RUN echo $(ls -1 ./build)
    RUN mkdir -p ./build/app
    RUN mv ./build/static ./build/app # now it should be /build/app/static
    RUN echo $(ls -1 ./build)
    

    You can take out the pwd and echo lines, I added it so I could see it working.

    I don't know why CRA doesn't do this by default. It might be because I'm using react-app-rewired, which messes around with CRA's webpack config?