简体   繁体   中英

Setting base href using Environment variables

Need to set the href value for <base href=""/> tag based on build environment configuration.

Eg:

Staging should have <base href="/staging" />

Prod should have <base href="/" />

Current setup:

Build command:

"build": "sh -ac '. .env.${REACT_APP_ENV}; react-scripts build'",

"build:staging": "REACT_APP_ENV=staging npm run build",

"build:prod": "REACT_APP_ENV=production npm run build",

.env.staging.js:

REACT_APP_BASE_HREF=/staging

index.html:

....

<base href="" + process.env.REACT_APP_API_URL />

....

This doesn't seem to work in index.html. While similar setup works for JS files

(Probably because JS files are parsed and bundled into a single file and the bundler reads the values at that point of time)

Things tried:

index.html:

<base href=process.env.REACT_APP_API_URL />

<base href="process.env.REACT_APP_API_URL" />

<base href="%process.env.REACT_APP_API_URL%" /> (similar to PUBLIC_URL variable)

Setting basename property along with Browser Router also does not solve the problem

This problem was solved. Follow these steps:

  1. In package.json Set homepage key to ""
  2. In .env.staging file Set PUBLIC_URL=/survey
  3. No need to use <base href> . Can be removed from HTML file
  4. Change links for stylesheet to

    <link rel="stylesheet" href="%PUBLIC_URL%/vendor/bootstrap/css/bootstrap.min.css">

No need to add process.env

You can do:

    <base href="%PUBLIC_URL%/"> <!-- Note the slash at the end -->
  • PUBLIC_URL is a env variable accessible through process.env .
  • You can set PUBLIC_URL env variable on your terminal export PUBLIC_URL=/subdir , or your .env (check create-react-app on it, it use dotenv under the hood).
  • You can also set homepage in package.json to /subdir , it will also work.
  • PUBLIC_URL , if not set, is taking homepage value.

If you only need to prefix link inside index.html, then you do not need a base tag. The base tag is useful for image link for example, that are inside your components:

If you serve your app in domain.com/ you can do:

<img src="/assets/duck.jpg" />

Instead, if you serve your app in domain.com/subdir/ , you can do:

<img src="/subdir/assets/duck.jpg" />

or if you have set the base tag like above:

<img src="assets/duck.jpg" /> <!-- Base tag only work with relative paths, same as ./assets/duck.jpg -->

Note that the above: src="assets/duck.jpg" will also work on your front page ( /subdir ) without base tag ! The path of the image is relative to the path you are currently on. This mean, that on /subdir/some-route , the web browser will be search at /subdir/some-route/assets/duck.jpg on the server, without a base tag. With a base tag, you can navigate to any route, and each image src path will ignore the path you are currently on, and start from the base tag href prop value.


In case you have background-image in scss (sass) files , I recommend moving it to html, like that:

<section style={{backgroundImage: `url('assets/background-form.jpg')`}}>
 ...

Sass for me, was not compiling with the relative path above. Also, you can try making a relative path to the assets folder ../../public/assets/background-form.jpg , but it will fail due to special restriction ModuleScopePlugin that forbid you to link relative path outside of src folder (see here ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM