Skip to main content

Next.js 환경 변수 설정

환경 변수는 넥스트로 만든 애플리케이션을 배포할 때 알아두면 좋은 개념입니다. 상황에 따라서 필요한 값을 편하게 세팅할 수 있게 도와주기 때문이죠. 하나씩 살펴볼까요.

환경 변수를 써야 하는 이유?

대부분의 회사에서는 애플리케이션을 개발할 때 쓰는 내부 서버와 사용자에게 애플리케이션을 제공하는 외부 서버로 나뉘어져 있습니다. 예를 들면, 아래와 같이 말이죠.

# 내부 개발 서버
http://dev.booking.com/

# 사용자가 접속하는 사이트
http://booking.com/

위와 같이 서버가 나뉘게 된다면 프런트엔드 입장에서는 API를 호출하는 주소가 달라져야 할 겁니다. 이때 환경 변수를 이용해서 API 호출 주소를 유연하게 바꿀 수 있습니다.

환경 변수 기본

넥스트 프로젝트의 루트 레벨에 .env.local 파일을 추가합니다.

package.json
.env.local
.gitignore

그리고 파일 안에 다음 내용을 작성합니다.

.env.local
API_URL=http://localhost:4000/api/v1

환경 변수는 이렇게 키=값 형태로 작성합니다. 중간에 공백 같은 건 넣지 않아야 합니다. 주석은 원한다면 #로 추가할 수 있습니다.

이렇게 작성한 환경 변수는 코드에서 다음과 같이 접근할 수 있습니다.

async function fetchProducts() {
await fetch(`${process.env.API_URL}/products`);
}

process.env라는 건 노드(Node.js) 환경 변수를 의미합니다. 넥스트는 노드 기반으로 동작하기 때문에 노드에서 제공하는 기본적인 기능을 사용할 수 있습니다.

서버별 환경 변수 설정

방금 살펴본 코드는 로컬 서버의 API 호출 주소를 입력한 것입니다. 그리고, 이 API_URL 값은 로컬 서버 시작 명령어를 실행했을 때만 유효합니다. 달리 말해, 애플리케이션을 배포하기 위해 빌드하고 서버를 실행할 때는 의미가 없다는 말이죠. 애플리케이션을 빌드할 때는 다음과 같이 .env.production 파일을 사용합니다.

.env.production
API_URL=http://booking.com/api/v1

이 파일도 마찬가지로 프로젝트 루트 레벨에 추가하고 npm run build와 같은 빌드 명령어를 수행하면, 애플리케이션 코드에 process.env.API_URL로 정의된 값이 모두 http://booking.com/api/v1로 변경됩니다.

이처럼 빌드 명령어를 실행할 때 주입할 값들은 모두 .env.production으로 관리합니다.

환경 변수 유효 범위 관련 주의 사항

빌드용 환경 변수(.env.production)를 사용할 때 주의할 점이 있습니다. 바로 환경 변수의 값이 서버 컴포넌트에만 적용된다는 점인데요. 브라우저에서 실행되는 클라이언트 컴포넌트는 process.env 값에 접근하지 못합니다. 따라서, 아래와 같은 코드에서는 undefined 값이 나옵니다.

CartButton.jsx
'use client';

function CartButton({ product }) {
const addCart = () => {
console.log(process.env.NEXT_PUBLIC_API_URL); // undefined
}

return <button onClick={addCart}></button>
}

환경 변수 기본에서 설명했듯이 process.env는 노드에서만 유효하기 때문에 어떻게 보면 당연합니다. 그럼, 클라이언트에서도 쓸 수 있는 환경 변수 설정 방법은 없을까요?

바로 NEXT_PUBLIC_ 접두사를 붙이면 됩니다. 아래와 같이 말이죠.

.env.production
NEXT_PUBLIC_API_URL=http://booking.com/api/v1

이렇게 하면 노드와 브라우저에서 모두 접근할 수 있는 환경 변수 값이 됩니다.

환경 변수 우선순위

여러 개의 환경 변수를 다룰 때 한가지 더 주의할 점이 있습니다. 바로 환경 변수 우선순위인데요. 앞에서 배운 내용들로 빠르게 환경 변수 체계를 구성하다가 만약 다음과 같이 해버린다면 문제가 발생합니다.

.env.local
.env.production

환경 변수를 로컬과 프로덕션 두개만 관리하게 되면 각 파일에 값을 구분해서 두어도 애플리케이션을 빌드할 때 .env.production에 저장한 값이 인식되지 않게 됩니다. 그 이유는 다음과 같이 넥스트에서 환경 변수를 인식하는 순서가 있기 때문이죠.

  1. process.env
  2. .env.$(NODE_ENV).local
  3. .env.local
  4. `.env.$(NODE_ENV)
  5. .env

npm run build 명령어로 빌드를 실행해도 위 우선순위에 의해서 .env.local이 먼저 인식됩니다. 이를 해결하려면 기본적으로 .env.local 보다는 .env.development 등을 사용하면 됩니다.

.env.development ← 로컬에서 `npm run dev`를 실행해도 인식됨
.env.production
tip

노드에서 기본적으로 지원하는 NODE_ENV의 종류에는 development, test, production 세개가 있습니다.