Search code examples
reactjsapachereact-routerreact-router-dom

React, BrowserRouter, Apache, and sub-directories


I have a react app that I'm trying to deploy to a subdirectory of a site - e.g., https://example.com/myapp. The server uses Apache. I've configured package.json, BrowserRouter, and .htaccess like this:

package.json:

"homepage": "https://example.com/myapp/"

BrowserRouter:

root.render(
  <React.StrictMode>
    <BrowserRouter basename="/myapp">
      <Routes>
        <Route path="/*" element={<App />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

https://example.com/myapp/.htaccess:

FallbackResource ./index.html

In general, this works exactly as it should, with one major exception.

If I try https://example.com/myapp/users - that works perfectly.

However, if I try https://example.com/myapp/user/{userId}, I get an error.

This is the case even though I have a route specified for that:

<Route path="user/:userId" element={<UserProfile />} />

It does work perfectly when I'm testing in Development mode at localhost:3000.

I think the issue is that, when the user requests https://example.com/myapp/user, Apache applies the .htaccess file in the https://example.com/myapp subdirectory.

But, when the user requests https://example.com/myapp/user/7, it's looking for a sub-sub-sub-folder that doesn't exist, doesn't find the .htaccess file, and so throws an error.

So, long story short - is there a way to handle this case?


Solution

  • According to the Create React App Serving apps with client side routing docs, the .htaccess file in the public directory should look similar to, or contain, the following rules:

    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [QSA,L]
    

    This should return the root index.html file for all page requests into your React app.