Modern web applications rely on external APIs for added functionality. Some APIs use identifiers like keys and secrets to associate requests with a particular application. These keys are sensitive and you should not push them to GitHub as anyone might use them to send a request to the API using your account.

This tutorial will teach you how to safely store and access API keys in a React application.

Adding Environment Variables in a CRA App

A React application that you create using create-react-app supports environment variables out of the box. It reads variables that begin with REACT_APP and makes them available through process.env. This is possible because the dotenv npm package comes installed and configured in a CRA app.

To store the API keys, create a new file called .env in the root directory of the React application.

Then, prefix the API key name with REACT_APP like this:

        REACT_APP_API_KEY="your_api_key"

You can now access the API key in any file in the React app using process.env.

        const API_KEY = process.env.REACT_APP_API_KEY

Ensure you add .env to the .gitignore file to prevent git from tracking it.

Why You Should Not Store Secret Keys in .env

Anything you store in a .env file is publicly available in the production build. React embeds it in the build files, which means anyone can find it by inspecting your app’s files. Instead, use a backend proxy that calls the API on behalf of your front-end application.

Storing Environment Variables in the Backend Code

As mentioned above, you must create a separate backend application to store secret variables.

For example, the API endpoint below fetches data from a secret URL.

        const apiURL = process.env.API_URL

app.get('/data', async (req, res) => {
const response = await fetch(apiURL)
const data = response.json()
res.json({data})
})

Call this API endpoint to fetch and use the data in the front end.

        const data = await fetch('http://backend-url/data')

Now, unless you push the .env file to GitHub, the API URL will not be visible in your build files.

Using Next.js to Store Environment Variables

Another alternative is to use Next.js. You can access private environment variables in the getStaticProps() function.

This function runs during build time on the server. So the environment variables you access inside this function will only be available in the Node.js environment.

Below is an example.

        export async function getStaticProps() {
    const res = await fetch(process.env.API_URL)
    const data = res.json()
    return {props: { data }}
}

The data will be available on the page via props, and you can access it as follows.

        function Home({ data }) {
  return (
    <div>
      // render data
    </div>
  );
}

Unlike in React, you don’t have to prefix the variable name with anything and you can add it to the .env file like this:

        API_URL=https://secret-url/de3ed3f

Next.js also allows you to create API endpoints in the pages/api folder. Code in these endpoints runs on the server, so you can mask secrets from the front end.

For example, the above example can be rewritten in the pages/api/getData.js file as an API route.

        export default async function handler(req, res) {
   const response = await fetch(process.env.API_URL)
   const data = response.json()
   return res.json({data})
}

You can now access the returned data through the /pages/api/getData.js endpoint.

Keeping API Keys Secret

Pushing APIs to GitHub is not advisable. Anyone can find your keys and use them to make API requests. By using an untracked .env file, you prevent this from happening.

However, you should never store sensitive secrets in a .env file in your frontend code because anyone can see it when they inspect your code. Instead, fetch the data on the server side or use Next.js to mask private variables.