fluid_27’s blog

勉強した内容をアウトプットするためのブログ

Next.jsの.envとpublicRuntimeConfigについて

状況

Next.jsで初めてアプリを作っていて、Image用のloaderを以下のようなソースで定義した時に.envで設定している値を想定した通りに読み込めてなかった。

// APIを叩いて画像を読み込む表示させるコンポーネント

export const PortfolioGroup = () => {
  const myLoader = ({ src, width, quality }: ImageProps): string => {
    return `${process.env.sampleAPI}${src}?w=${width}&q=${quality || 75}`
  }

  return (
    <Image
      loader={myLoader}
      src={portfolio.attributes.image.data.attributes.formats.small.url}
      width="400"
      height="400"
    />
  )
//.envの内容

sampleAPI=https://xxxxxxxxxx


調べたところ、上記のようなパターンでは.envにAPIのURLを記述してもダメで、下記のようにpublicRuntimeConfigに記載することで解決。

解決したソース

// APIを叩いて画像を読み込む表示させるコンポーネント

export const PortfolioGroup = () => {
  const { publicRuntimeConfig } = getConfig();
  const myLoader = ({ src, width, quality }: ImageProps): string => {
    return `${publicRuntimeConfig.sampleAPI}${src}?w=${width}&q=${quality || 75}`
  }

  return (
    <Image
      loader={myLoader}
      src={portfolio.attributes.image.data.attributes.formats.small.url}
      width="400"
      height="400"
    />
  )
// next.config.jsの内容

/** @type {import('next').NextConfig} */
const nextConfig = {
  publicRuntimeConfig: {
    //下記にURLベタ書きすることも可能だが、next.config.jsはgit管理されているので.envから読み込むようにしている。
    sampleAPI: process.env.sampleAPI
  }
}

module.exports = nextConfig
//.envの内容

sampleAPI=https://xxxxxxxxxx


せっかくなので.envとpublicRuntimeConfigの違いを調べてまとめてみた。

.envとpublicRuntimeConfigとは

env

環境変数を直接process.envオブジェクトから参照する方法。
.envファイルや.env.localファイルに環境変数を設定し、process.env.変数名でアクセスできるようになる。
これらの環境変数は、サーバーサイドでもクライアントサイド(ブラウザ上)でも利用できる。
ただし、process.envの値はビルド時に決定されるため、クライアントサイドでの値の変更や非同期処理には使えない。

publicRuntimeConfig

Next.jsに組み込まれた機能で、サーバーサイド、クライアントサイド(ブラウザ上)で利用可能なランタイム変数を定義することができる。
next.config.jsでpublicRuntimeConfigオブジェクトを設定する。
サーバーサイド、クライアントサイド、どちらのコードでも利用できるが、クライアントサイドではpublicRuntimeConfigの値にアクセスできるものの、実際の値はサーバーサイドで非公開に保たれるらしい。(クライアントサイドで値の保持はしてない。という事みたい)
クライアントサイドのコードにおいて非同期処理や動的な値を取得する際に便利。

使い分け

具体的には、以下のように使い分け可能。
例えば、APIエンドポイントやデータベースの接続情報などの秘密情報は、envを使って設定し、サーバーサイドで利用するのが一般的らしい。
一方で、クライアントサイドで表示する定数や設定値は、publicRuntimeConfigを使って設定することが便利。

結論

サーバーサイドで値取得する変数
→ .envを使う

クライアントサイド(ブラウザ上)で値取得する変数
→ publicRuntimeConfigを使う
  .envは使用不可(ビルド時の値が確定しているため。だが、「NEXT_PUBLIC_」を利用すればブラウザからも値取得可能になる。詳しくは参考記事として添付している公式ページ参照)

参考記事

基本、公式が親切に解説してくれるので、公式を見るのが一番だと思います。
next.config.js: ランタイム設定 | Next.js
Basic Features: 環境変数 | Next.js

認識に間違いありましたら、ご指摘・ご指導いただけると幸いです。