Next.jsの環境変数設定まとめ

# 環境変数
Node.jsでは環境変数はprocess.envというオブジェクトに格納される
Next.jsでは以下で紹介する`.env*`で定義するとビルド時に`process.env`に設定してくれる

# .envファイルの種類

|ファイル名 |概要(何を定義するか) |読み込み |優先順位 |
|--- |--- |--- |--- |
|.env |環境（開発、本番)に依存しないデフォルト値 |常に読み込まれる |4 |
|.env.local |環境に依存しないシークレットなもの<br />(リポジトリに含めず.ignore定義しておく) |常に読み込まれる |2 |
|.env.development |開発環境で使用するデフォルト値 |`yarn dev`実行時に読み込まれる |3 (開発） |
|.env.development.local |開発環境で使用するシークレットなもの<br />(リポジトリに含めず.ignore定義しておく) |`yarn dev`実行時に読み込まれる |1 (開発) |
|.env.production |本番環境で使用するデフォルト値 |`yarn start`, `next build`実行時に読み込まれる |3 (本番) |
|.env.production.local |本番環境で使用するシークレットなもの<br />(リポジトリに含めず.ignore定義しておく) |`yarn start`, `next build`実行時に読み込まれる |1 (本番) |

表の優先順位とは、もし複数のファイルに同じ環境変数名で定義されていた場合にどのファイルの定義が優先されるかということ

```:.env
TEST=.env
```

```:.env.local
TEST=.env.local
```

```:.env.development
TEST=.env.development
```

```:.env.development.local
TEST=.env.development.local
```
```console:結果
console.log(process.env.TEST)
=> .env.development.local (優先順位１)
```

# Next.jsバージョンによる挙動の違い（v9.4前後で異なる)

## v9.4以上

### `.env*`ファイルを定義すればサーバー、クライアント両方で環境変数を呼び出すことができる

特に設定は必要なく`.env*`ファイル内に環境変数を定義すればサーバー、クライアント両方で環境変数を呼び出すことができる。ただし、クライアントサイドつまり、ブラウザ上で使用するには環境変数名にプレフィックスを付けなければ`process.env`配下に渡されない

### クライアントサイドで使用するには定義する変数名のプレフィックスに`NEXT_PUBLIC_`をつける

プレフィックスがなければNodeJSのサーバー側の処理、つまり、[Data Fetching methods](https://nextjs.org/docs/basic-features/data-fetching) (`getStaticProps`, `getStaticPaths`, `getServerSideProps`)と[API Routes](https://nextjs.org/docs/api-routes/introduction)の中でしか使用できず、プレフィックスのないものをクライアント側で使おうとすると`undefined`が帰ってくる

```:.env
TEST=test
NEXT_PUBLIC_TEST=next_public_test
```
```console:サーバーサイド結果
console.log(process.env.TEST)
=> test

console.log(process.env.NEXT_PUBLIC_TEST
=> next_public_test
```

```console:クライアントサイド結果
console.log(process.env.TEST)
=> undefined (NEXT_PUBLIC_ プレフィックスがないので undefined になっている)

console.log(process.env.NEXT_PUBLIC_TEST
=> next_public_test
```

> https://github.com/vercel/next.js/tree/canary/examples/environment-variables


## v9.4未満(非推奨)

### `dotenv`系のツールを使用することでサーバーサイド、クライアントサイド問わず`値を渡すことができる
`dotenv`系のツールを使用して`next.config.js`の中で次のように定義することで、`.env`から環境変数を読み取り、クライアントサイドに値を渡すことができる.

```:.env
TEST=test
```

```js:next.config.js
require('dotenv').config();

module.exports = {
  env: {
    // この中に定義していく
    TEST: process.env.TEST
  }
};
```

```:サーバーサイド結果
console.log(process.env.TEST)
=> test
```

```:クライアントサイド結果
console.log(process.env.TEST)
=> test
```

> https://github.com/vercel/next.js/tree/canary/examples/with-dotenv


# 早見表

## `yarn dev`起動時

|ファイル |環境変数 |サーバーサイド |クライアントサイド |
|--- |--- |--- |--- |
|.env |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.development |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.development.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.production |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |
|.env.production.local |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |

## `yarn start`起動時

|ファイル |環境変数 |サーバーサイド |クライアントサイド |
|--- |--- |--- |--- |
|.env |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.development |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |
|.env.development.local |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |
|.env.production |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.production.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |

## `yarn build`起動時

|ファイル |環境変数 |サーバーサイド |クライアントサイド |
|--- |--- |--- |--- |
|.env |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.development |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |
|.env.development.local |ENV=env |undefined |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|undefined |undefined |
|.env.production |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |
|.env.production.local |ENV=env |env |undefined |
| |NEXT_PUBLIC_ENV=next_public_env|next_public_env |next_public_env |



# クォーテーションはどちらでも良い

スペースの有無にかかわらずクォーテーションの有無はどちらもよい

```:.env
TEST1=test1
TEST1_1=test1 1
TEST2="test2"
TEST2_1="test2 1"
```

```
console.log(process.env.TEST1)
=> test1
nconsole.log(process.env.TEST1_1)
=> test1 1

console.log(process.env.TEST2)
=> test2
console.log(process.env.TEST2_1)
=> test2 1
```


# デプロイ時の環境変数設定
Vercelでデプロイする場合は`Environment Variables`の機能を使用しましょう。UI上で直接環境変数を設定し、それらの値は暗号化される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449626/f5c2bc3b-873a-c5a5-72e2-497acf7ccdb9.png)