Axios custom instance not working properly with next JS

Viewed 12466

So firstly i create custom axios instance with baseurl and export it like this:

import axios from 'axios';

const instance = axios.create({
  baseURL: process.env.BACKEND_URL,
});

instance.defaults.headers.common['Authorization'] = 'AUTH TOKEN';
instance.defaults.headers.post['Content-Type'] = 'application/json';

export default instance;

The problem is in my saga or in any component in general (ONLY client side) when importing this custom axios instance. I use next-redux-wrapper, and when i prefetch data (using getStaticProps) for my component everything works fine and the axios.defaults.baseURL property works just fine. However the problem is on client-side, whenever i import the same axios instance in any component or in saga but i call it from lets say componentDidMount, the same axios.default.baseURL is undefined, so if i want to make get request i have to type in the full backend + queries URL. What could the problem be? EXAMPLE:

export function* fetchTPsSaga() {
  try {
    console.log(axios.defaults.baseURL); 
    const url = `/training-programs`;
    const res = yield axios.get(url);
    const tPs = res.data.data;
    yield put(fetchTrainingProgramsSuccess(tPs));
  } catch (err) {
    yield put(fetchTrainingProgramsFail(err));
  }
}

// The first time it renders (on server side), it's the valid baseURL property, however if i call the same saga from client-side (when component is rendered) it's UNDEFINED, so i have to type the full url

2 Answers

process.env only work on server-side. You can use publicRuntimeConfig to access environment variables both on client and server-side.

next.config.js

module.exports = {
  publicRuntimeConfig: {
    // Will be available on both server and client
    backendUrl: process.env.BACKEND_URL,
  },
}

axios instance file

import axios from 'axios';
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();

const instance = axios.create({
  baseURL: publicRuntimeConfig.backendUrl,
});

By the way, if you are using Next.js versions 9.4 and up, the Environment Variables provide another way.

Loading Environment Variables Rules

In order to expose a variable to the browser you have to prefix the variable with

NEXT_PUBLIC_

. For example: NEXT_PUBLIC_BACKEND_URL='http://localhost:3000'

Then you can access this env variable in Axios as its client-side rendering

import axios from 'axios';

const instance = axios.create({
  baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
});

*Note: You have to use process.env.NEXT_PUBLIC_BACKEND_URL instead of process.env.BACKEND_URL

Related