5

This SO thread explains how to bundle a react app for deployment to a specific subdirectory on a web server. I would like to bundle my react app to work on any subdirectory on my webserver. In other words: Is it possible to build a react app, such that I can move it from

http://server/foo

to

http://server/bar

or

http://server/foo/bar

without rebuilding or changing anything?

Marc
  • 12,706
  • 7
  • 61
  • 97

3 Answers3

2

in package.json

"homepage": ".",
Kani
  • 135
  • 1
  • 12
1

If you are using react-router-dom, If you know your directory name you could set basename to "/directory-name" in the router

or

If you want to set the base name to be dynamic, use

(Note: This won't be useful if you are using sub routing)

or

Incase of sub routing, set a standard string to your routes

Example:

 let basename_path = null;
   var url = window.location.pathname.toLowerCase();
   if(url.indexOf("react") === -1){    // If string(react) not available
            basename_path = "/";
   }
    else{
       var array = url.split("react");
       basename_path = array[0]+"react/";
     }


 <Router basename={basename_path}>   
   <Route exact path="/react/home" component={home}/>
   <Route exact path="/react/contactus" component={contactus}/>
   <Route exact path="/react/aboutus" component={aboutus}/>               
 </Router> 
  • How is the production app version built in your example when using CRA (create React app), using `"homepage": "."`? If I'm not mistaken, then the original question was asking for not having to build the production app for a specific path. – TheDiveO Nov 05 '20 at 21:43
0

Answers to this and similar questions seem to neglect that, if using client-side routing (like React Router) there are some back-end changes that should be made when serving from a subdirectory.

There are several approaches to this. One is to use <HashRouter>; that approach is described well here, or in the React Router docs.

Another approach is to use <BrowserRouter> with Express. Here are the steps for that:

In your app:

    <BrowserRouter basename={process.env.PUBLIC_URL}>
        <Route path="/your_route">
          ...
        </Route>
        <Route exact path="/">
          ...
        </Route>
    </BrowserRouter>

Then, in package.json, add:

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

(Note that "." will not work, if you're using client-side routing.)

Then, in Express, try the connect-history-api-fallback package (which is recommended in the Vue Router docs).

const express = require('express');
const historyFallback = require('connect-history-api-fallback');

const app = express();
app.use(historyFallback);

Without this, users will not be able to directly enter https://example.com/mySubdirectory/my_route in the browser's url bar; they'll get a cannot GET error.

You can see an example of the above with Apache here.

Andrew
  • 3,825
  • 4
  • 30
  • 44