insitu
insitu

Reputation: 4698

How to inject API server URL when deploying react frontend?

Disclaimer: I am a React noob so perhaps what I am trying to do is not the React Way

I am writing a React front-end that will be deployed to be served statically by some cloud provider, e.g. S3 or Google Storage or whatever. This front-end interacts with several API servers that live somewhere in the cloud, maybe in the same provider, maybe not. Furthermore, while developing the UI or part of it, those servers' addresses might be local or testing instances.

How do I inject the API server(s) URLs into my react application in a flexible so that I can deploy in dev, staging or prod using different addresses?

SOLUTION: I finally ended up using a combination of solutions proposed:

Note this somewhat goes against principles from 12 Factor Apps, e.g. storing env variables in files in version control but it does the job ATM.

Upvotes: 51

Views: 81581

Answers (7)

Manoj Thapliyal
Manoj Thapliyal

Reputation: 577

create a config file

const baseURL =
  process.env.NODE_ENV === "production"
    ? "https://webserver.com/api"
    : "http://localhost:3000/api";


    const Config = async () => {
        return (
          <>
          </>
        );
      };
export default Config;
export { baseURL };

import this file in the code

  import { baseURL } from './config';

in api call

  const res = await fetch(`${baseURL}/PATH`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  });

Upvotes: 0

Israr khan
Israr khan

Reputation: 9

in the app.js file you can create function of this type sessionStorage.setItem("apipathurl","http://localhost:3000/api")

sessionStorage.setItem("apipathurl","https://example.onrender.com/api");

and call this function each file of your app as in login.js

const baseURL = sessionStorage.getItem("apipathurl");

call this baseURL into your API endpoint

const response = await fetch(${baseURL}/user/login, { method: 'POST', body: JSON.stringify({ email, password }), headers: { 'Content-Type': 'application/json', }, });

this is the the way to create live url path for your app

Upvotes: 0

Suman Deol
Suman Deol

Reputation: 384

After creating the .env file. Please restart the app. Like in reactJs use npm start command to restart it. It will work fine.

Upvotes: 0

Giang Le
Giang Le

Reputation: 7044

You can try this:

// http.js
const getBaseUrl = () => {
  let url;
  switch(process.env.NODE_ENV) {
    case 'production':
      url = 'https://stackoverflow.com';
      break;
    case 'development':
    default:
      url = 'https://google.com';
  }

  return url;
}

export default axios.create({
  baseURL: getBaseUrl(),
});

Upvotes: 26

Rizal Ibnu
Rizal Ibnu

Reputation: 443

Using this package https://github.com/toddbluhm/env-cmd you could create an env file for your environment

for example create .env.staging and .env file with this code

// .env.staging file   
API_URL=https://staging.url.com/api/
// .env file
API_URL=https://url.com/api/

How to fetch with API_URL from env variable:

fetch(process.env.API_URL)

Then you can just add some extra scripts in your package.json:

{
  "scripts": {
    "build:staging": "env-cmd .env.staging yarn build",
    "build:prod": "env-cmd .env yarn build"
  }
}

Upvotes: 4

Midhun G S
Midhun G S

Reputation: 957

You can use .env file if the API's are constant for development or production environment. after build you can't change these parameters.

If you want to change the URL after build, add a js file lets say config.js

Include the conf.js in index.html

Add URL in conf.js like

var URL1 = 'https://www.google.com'

You can access the parameter like :

export const {URL1} = window;

Upvotes: 3

Jo&#227;o Cunha
Jo&#227;o Cunha

Reputation: 10307

You can do that making use of environment variables on the build step for example.

You can use something like .env that allows you to define environment variables and load them on your webpack file for example (assuming you use webpack). But you can really use it with any bundler.

.env file:

API=http://localhost:3000

On your webpack you could make use of the DefinePlugin

example taken from docs: add your API env

    ...
    require('dotenv').config()
    ...

    new webpack.DefinePlugin({
      API_ENDPOINT: process.env.API,
      PRODUCTION: JSON.stringify(true),
      VERSION: JSON.stringify('5fa3b9'),
      BROWSER_SUPPORTS_HTML5: true,
      TWO: '1+1',
      'typeof window': JSON.stringify('object')
    });

Anyway, this is just one way. I like this way because it makes my project ready for defining API keys and other useful stuff for different environments.

NOTE: You can even define different .env files for local, staging and production and load the respective one in the webpack depending on the build type.

Upvotes: 2

Related Questions