How is it possible to access homepage from package.json in a react app?

Viewed 2523

I created a react app that will be served from /example-path. I defined it in the package.json like this:

"homepage":"/example-path"

It has worked so far, but now I would like to add routing with react-router-dom, and it incorrectly detects /example-path as the part of the URL.

This is my code:

<Router>
  <Switch>
    <Route path="/product/:id" children={<DisplayProduct />} />
  </Switch>
</Router>

Unfortunately react-router-dom tries to match the full URL /example-path/product/10. How is it possible to avoid that? Is it possible to access the homepage variable somehow?


I could use <Router basename="/example-path">, but in that way, this parameter is a duplicate. I would like to define it in only one place.

5 Answers

How is it possible to access homepage from package.json in a react app?

We can access the URL set in package.json's homepage field using PUBLIC_URL environment variable.

We sometimes use a relative URL to deploy the application in subdirectories for example we are deploying the application in https://myhostname.com/example-path.

In order to do that, we can either set the environment variable PUBLIC_URL=/example-path for the application build or set the package.json homepage attribute to "/example-path". In your case, you have set the

"homepage": '/example-path/'

then the PUBLIC_URL would be set to /example-path/. Now you can access this environment variable anywhere in your react application.

<Router basename={process.env.PUBLIC_URL}>
  <Switch>
    <Route path="/product/:id" children={<DisplayProduct />} />
  </Switch>
</Router>

After running the npm run build, you can check in the build/index.html that all the places where you used the %PUBLIC_URL% is set to /example-path/ like below;

<script type="text/javascript" src="/example-path/static/js/main.ec7f1972.js">

The Router doesn't know anything about your package.json. It just looks at the browser location. You can set a basename if you use BrowserRouter:

import {BrowserRouter as Router} from 'react-router';
<Router basename="/example-path">
    {/* ... */}
</Router>

Assuming you are using create-react-app, this is actually pretty straightforward:

Add the following to public/index.html:

<script>
  window.PUBLIC_URL = "%PUBLIC_URL%";
</script>

now you can reference the homepage from JavaScript! Simply access it via

const myPublicUrl = window.PUBLIC_URL;

Note: The variable will be an empty string if no homePage field is set in the package.json, so we have to compensate for that:

<Router basename={window.PUBLIC_URL && window.PUBLIC_URL.length > 0 ? window.PUBLIC_URL : "/"}>
    {/* ... */}
</Router>

Since you are using create-react-app package you can use environment variable instead of "homepage":"/example-path" in your package.json:

  1. create .env file in the root of your project.

  2. add REACT_APP_HOME_PAGE='/example-path/' to the .env file

  3. now you can access your env variable through process.env.REACT_APP_HOME_PAGE in your app like the following:

    <Router basename={process.env.REACT_APP_HOME_PAGE}>
    

I don't know where is the location of your Router file but you can try to import it as json in src/index.js file that created by create-react-app cli app like below;

import myPackageJson from '../package.json';

or

import { homepage } from '../package.json';
Related