Search code examples
reactjsreact-scripts

Pass an argument in some react-scripts scenario


I have a standard react app with the canonical package.json entry

"scripts": {
     "start": "react-scripts start",
     "build": "react-scripts build",
     ...
}

I found that to pass an argument to react-scripts scenario I have simply to prepend it with

 "scripts": {
    "start": "REACT_APP_LOG_URL=http://example.com react-scripts start",
    ...
}

And then in index.js file I can get this argument with

const logUrl = process.env.REACT_APP_LOG_URL;

console.log(`Logging to ${logUrl}`);

But I get an error

'REACT_APP_LOG_URL' is not recognized as an internal or external command,
operable program or batch file.

Where am I wrong?


Solution

  • React-dotenv package can solve the problem. https://github.com/jeserodz/react-dotenv/blob/main/README.md

    npm install react-dotenv
    
    1. Add an .env file to your project root with entry:
    REACT_APP_LOG_URL=http://example.com
    
    1. Add the react-dotenv NPM command to your start command in package.json.
    "scripts": {
        "start": "react-dotenv && react-scripts start"
     ...
    }
    

    Other scenarios shouldn't be changed.

    "scripts": {
        "build": "react-scripts build"
     ...
    }
    

    so we can differentiate this 2 cases (in second case our variable will be undefined)

    1. Add the react-dotenv.whitelist property to package.json to specify which variables you need exposed.
      "react-dotenv": {
        "whitelist": ["REACT_APP_LOG_URL"]
      }
    

    Then you can get this value with env variable:

    import env from "react-dotenv";
    const logUrl = env.REACT_APP_LOG_URL;
    

    then somewhere inside a component:

    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Today is {getDate()}
            </p>
            <p>
              Logging to {logUrl}
            </p>
       ...
          </header>
       </div>)