illyria
illyria

Reputation: 404

Env variables in nextjs

I've really been trying to understand how to go about environment variables in nextjs, but I still don't get it. I am just trying to hide my API key from the code below. From what I understand I can only do it by using either getServerSideProps or getStaticProps. If that's the case though I still have no clue of how I should modify my code accordingly

       import { createContext, useState, useEffect } from 'react';

const WeatherContext = createContext({
  searchLocation: (input) => {},
  btnHandler: (input) => {},
  weather: '',
  isLoading: true,
});

export function WeatherContextProvider(props) {
  const [weather, setWeather] = useState({});
  const [city, setCity] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [unit, setUnit] = useState('metric');
  const [searchInput, setSearchInput] = useState('');
  

  const btnHandler = () => {
    if (unit === 'metric') {
      setUnit('imperial');
    } else {
      setUnit('metric');
    }
  };

  const searchLocation = async (input = searchInput, units = unit) => {
    if (loading) {
      input = 'London';
    }
    try {
      const firstResponse = await fetch(
        `https://api.openweathermap.org/data/2.5/weather?q=${input}&units=${units}&appid=KEY`
      );
      
      const firstData = await firstResponse.json();
      if (!firstResponse.ok) {
        setError(true);
        throw new Error('Something went wrong');
      }

      let lon = firstData.coord.lon;
      let lat = firstData.coord.lat;

      const response = await fetch(
        `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&units=${units}&exclude=&appid=KEY`
      );
      const data = await response.json();

      if (!response.ok) {
        setError(true);
        throw new Error('Something went wrong');
      }
      setWeather(data);
      setCity(firstData.name + ', ' + firstData.sys.country);
      setSearchInput(firstData.name);
      setLoading(false);
      setError(false);
    } catch (error) {
      setError(error.message);
      console.log(error);
    }
  };

  useEffect(() => {
    searchLocation();
  }, [unit, searchInput]);

  const context = {
    searchLocation: searchLocation,
    city: city,
    weather: weather,
    isLoading: loading,
    error: error,
    btnHandler: btnHandler,
    unit: unit,
    searchInput: searchInput,
  };

  return (
    <WeatherContext.Provider value={context}>
      {props.children}
    </WeatherContext.Provider>
  );
}

export default WeatherContext;

Upvotes: 4

Views: 5439

Answers (3)

Kodee McIntosh
Kodee McIntosh

Reputation: 108

Unfortunately you are correct that if you wish to hit the api from the client side, then you'll be exposing the env variable, while any calls made from getServerSideProps or getStaticProps can keep the env variable private on the server-side.

It is also very important to remember that when creating an env variable that will be exposed/accessed on the client side within your react code, you'll want to prepend the env variable name with NEXT_PUBLIC_, so that way nextjs knows to allow the env variable on the client side.

With that said, it looks like the best way for you to handle your api key situation would be to create a .env file at the root of your project and add something like NEXT_PUBLIC_API_KEY=insert-your-api-key-here.

If you absolutely need to keep this api key private, I think your best move would be to create a dynamic route in your pages folder (/pages/[slug].jsx) and within the getServerSideProps for that page you can use the param data to make your api calls on the server side, which would keep your api key contained to the server side.

Upvotes: 6

Mahmud Hasan Jion
Mahmud Hasan Jion

Reputation: 585

Create an .env file and declare your API key value there.

API_KEY: 'YOUR_KEY'

Call the environment-variables in next.config.js file like this:

module.exports = ({
    env: {
        API_KEY: process.env.API_KEY
    }
})

Finally use the env value where you want to in your project like this {process.env.API_KEY}

Upvotes: 2

Lowgy
Lowgy

Reputation: 93

Here is a good reference video that explains environment variables pretty well https://www.youtube.com/watch?v=vS86x_e0zBk as well Next.js has some of the best documentation https://nextjs.org/docs/basic-features/environment-variables

From previous experience, the best an easiest way is through a .env.local file. From there you can set what variables you want to be server side, client side, etc.

Upvotes: 1

Related Questions