まくろぐ

Next.js で環境変数を扱う (.env, NEXT_PUBLIC)

更新:
作成:

Next.js アプリ内での環境変数の振る舞い

process.env の振る舞い

Node.js の process.env による環境変数の参照が有効なのは、基本的には次のようなサーバーサイドで実行されるコード内のみです。

  • ビルド時あるいはアクセス時に呼び出される getStaticPathsgetStaticProps
  • 必ずアクセス時に呼び出される getServerSideProps
  • 必ずアクセス時に呼び出される API ルートのハンドラ関数 (handler)
src/pages/sample.tsx
export const getStaticProps: GetStaticProps<PageProps> = async context => {
  // このコードはビルド時に実行されるので環境変数を参照できる
  console.log(process.env.VAR_NAME)
  return { props: {} }
}

NEXT_PUBLIC プレフィックス

ただし、例外として、NEXT_PUBLIC_ で始まる環境変数を process.env.NEXT_PUBLIC_XXX のように参照すると、next build によるビルド時に変数値がインライン展開されるので、クライアントサイドで実行されるコード(コンポーネントの実装内)から参照できます。

src/pages/sample.tsx
const SamplePage: FC = () => {
  return <>
    <p>Public env: {process.env.NEXT_PUBLIC_ANALYTICS_ID}</p>
    <p>Private env: {process.env.API_SECRET_KEY} (必ず空っぽ)</p>
  </>
}

上記のようにすると、process.env.NEXT_PUBLIC_ANALYTICS_ID の部分には、ビルド時の環境変数 NEXT_PUBLIC_ANALYTICS_ID の値がそこに埋め込まれ、process.env.API_SECRET_KEY の方は必ず undefined になります(何も表示されない)。

サーバーサイドでしか参照しない環境変数(シークレットキーなど)には、NEXT_PUBLIC_ プレフィックスを付けないように注意してください。

.env (.env.local) ファイル

Next.js サーバーは、デフォルトでプロジェクトルートに配置した .env.env.local といった名前のファイルを読み込んで、process.env.XXX で参照可能な状態にしてくれます。 ローカル開発中に、一時的にテスト用のリソースサーバーに繋ぎたいときなどに便利です。

.env.local
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

これらの設定ファイルの中では、次のように $VAR という形の変数展開を行えるようになっています。

HOSTNAME=localhost
PORT=8080
HOST=http://$HOSTNAME:$PORT

.local サフィックスが付いている方のファイルは、「Git などにコミットしないファイルですよ」という Next.js での取り決めですね。 Next.js は他にも実行環境に応じて色々な名前の環境設定ファイルを読み込むようになっています。 下記は、どのファイルがどの環境で読み込まれるかの一覧です。

ファイル本番環境
(next start)
開発環境
(next dev)
テスト環境
(jest など)
Git コミット
するか?
優先度
(1が最大)
.envする4
.env.localしない2
.env.productionする3
.env.production.localしない1
.env.developmentする3
.env.development.localしない1
.env.testする3
.env.test.localしない1

複数のファイルに同じ環境変数が定義されている場合は、.local が付いたものが優先的に使われます。 例えば、本番環境 (next start) では、.env.production.local.env.local.env.production.env という優先度になります。

末尾に .local が付いたファイルには秘密鍵などの情報を記述することを想定しているので、間違えて Git にコミットしないように .gitignore ファイルに登録しておきましょう。

.gitignore
# local env files
.env.local
.env.production.local
.env.development.local
.env.test.local

config.ts に環境変数の値を反映させる

アプリ全体のコンフィグ用に config.ts のようなファイルを作成しているケースは多いと思います。 この中で環境変数を参照するようにしておくと、環境 (production or development) に応じてリソースを使い分けるといったことが簡単にできます。 これは、Next.js が前述のように複数のファイルを読み分けてくれるおかげです。

src/libs/config.ts
export const config = {
  userPoolId: process.env.NEXT_PUBLIC_USER_POOL_ID ?? 'default-user-pool',
  identityPoolId: process.env.NEXT_PUBLIC_IDENTITY_POOL_ID ?? 'default-id-pool',
}

ちなみに、?? という演算子は Nullish coalescing という仕組みで、左側が undefined だったときに右側の値が使われるようになります。 つまり、上記のように記述しておくと、環境変数が設定されていればその値を使い、設定されていなければ後ろに書いたデフォルト値を使う、という振る舞いになります。

例えば、本番環境で接続先の情報を変えたいときは、次のような環境変数ファイルを作成するだけで済みます。 next start で Next.js サーバーを起動したときや、Vercel でホスティングするときはこの設定が使われるようになります。

.env.production
NEXT_PUBLIC_USER_POOL_ID=xxxxxxxxxxxxx
NEXT_PUBLIC_IDENTITY_POOL_ID=yyyyyyyyyyyyy

関連記事

まくろぐ
サイトマップまくへのメッセージ