VercelのNEXT_PUBLIC環境変数を変更してもブラウザーに反映されないとき

VercelのNEXT_PUBLIC環境変数を変更しても既存Deploymentに反映されない理由と、新しいDeploymentでの確認方法を整理します。

AIものさし編集部

環境変数を保存しただけでは、すでに作成済みのDeploymentの設定は通常更新されません。まず変更した変数がどのProject・Environmentに適用されるかを確認し、対象のDeploymentより後に作られた新しいDeploymentで反映を確かめます。ブラウザーへビルド時に埋め込まれる NEXT_PUBLIC_ の値は、ビルド後に変数だけを変更しても書き換わりません。

最初に確認する順番は、①対象ProjectとTeam、②変数名とEnvironmentの選択、③Branch固有のPreview設定、④Deploymentの作成時刻、⑤アプリが値を読むタイミングです。値そのものをログや画面に出して確認する必要はありません。秘密値は表示せず、値の有無や安全なテスト結果で確認します。

先に「何が古いか」を切り分ける

「設定した値が反映されない」という症状は、設定範囲の取り違え、既存Deploymentを見ている、ビルド時に確定する値、または別のキャッシュやデータ更新遅延から起きます。Deploymentをすぐ再実行する前に、変数名・対象環境・反映を期待しているURLをメモし、Vercel DashboardのProject、Environment Variables、Deploymentsで同じProjectを見ていることを確認します。

表は横にスクロールできます

見えている症状最初に照合すること判断の目安
ProductionのURLだけ古い変数のEnvironmentにProductionが含まれるか、現在のProduction Deploymentが変数変更より後に作成されたか古いDeploymentなら、そのDeploymentは変更前の環境変数で動いている可能性が高い
Previewだけ古いPreview全体か特定Branch向けか、Branch固有値があるか同名のBranch固有値は一般のPreview値を上書きすることがある
ブラウザー内の表示だけ古い変数名が NEXT_PUBLIC_ で始まるか、値をクライアント用bundleに埋め込んでいるかNext.jsでは公開変数がビルド時にbundleへ置換されるため、新しいビルドが必要
サーバー処理も古い実際にリクエストを処理するDeployment、環境、変数名、コードが読む場所を確認サーバー側変数でも既存Deploymentには自動で差し替わらない
一部Projectだけ古いTeamレベルかProjectレベルか、Team変数のLink to Projects対象Team変数は複数Projectに関係する場合がある
Deploymentは新しいのに古い変更した環境・Project・Branch、ビルドログ、アプリ側の別設定、外部サービスのキャッシュを確認ここで初めてアプリ固有の読込タイミングやデータキャッシュを調べる

この表は診断の入口です。画面に同じ変数名が見えても、別Team・別Project・別Environmentの値を見ている場合があります。実際のVercelアカウントをこちらで確認したわけではないため、該当のDashboardでProject名、Team、Environment、Branch、Deployment URLを一つずつ照合してください。

設定範囲とDeploymentの時系列を確認する

環境変数はTeamまたはProjectの設定として管理でき、Production、Preview、Developmentなど、適用先Environmentを選べます。Previewでは全Branch向けの値とBranch固有の値を使い分ける構成があります。同じ名前の変数が複数の範囲にある場合は、どの値が対象Deploymentに適用されるかをProjectの設定とEnvironmentの指定から確認します。名前だけで「Production用」と判断しないでください。

次に、環境変数を保存した日時と対象Deploymentの作成日時を並べます。対象Deploymentが変更より前なら、設定保存後に新しいDeploymentが作られたかを確認してください。Vercelの説明では環境変数の変更は以前のDeploymentへ遡って適用されず、新しいDeploymentに適用されます。以前のPreview URLや過去のProduction Deployment URLを開いている場合、画面が変わらないこと自体は設定保存の失敗を意味しません。

確認用メモは次の列で作ると、見間違いを減らせます。

表は横にスクロールできます

項目記録例(値は秘密にしない)
Team / ProjectDashboardに表示されたTeam名、Project名
変数名例:API_BASE_URL。秘密の値は記録しない
変数の範囲TeamまたはProject
EnvironmentProduction / Preview / Development / Custom
Branch条件全Previewか、対象Branch固有か
設定変更時刻Dashboardの履歴などで確認できる場合に記録
Deployment対象URL、環境、作成時刻、状態
アプリでの読み方ブラウザーbundle、サーバー起動時、リクエスト時など

Custom Environmentを使っている場合は、どの環境から値を引き継ぎ、独立した値にしているかも確認します。PreviewのBranch固有値が存在するなら、意図したBranchを対象にした設定かを見ます。Developmentのローカル値はVercel上のProduction Deploymentの値とは別です。

ビルド時の値と実行時の値を区別する

Next.jsで NEXT_PUBLIC_ を付けた環境変数は、クライアント側JavaScriptへ公開してよい値としてビルド時に埋め込まれます。生成済みbundleでは値が固定されるため、Vercelの設定画面で値を変更しても、既存のbundleを書き換えることはできません。変更後の値を含めるには、その値を使って新しくBuild・Deploymentを作る必要があります。

一方、NEXT_PUBLIC_ のない変数は通常サーバー側で利用します。ただし、それだけで必ずリクエストごとに最新設定を読むとは限りません。アプリがビルド時に値を使って静的生成しているのか、サーバーの動的処理で読むのか、起動時に読み込んでいるのかは実装によって異なります。プロジェクトのコードやFrameworkの実行方式を見ずに「サーバー変数なら設定変更だけで即時反映」と断定しないでください。

クライアントへ公開する値と秘密値も区別します。接頭辞を付ければ秘密値を安全にできるわけではなく、NEXT_PUBLIC_ の値はブラウザーへ届くbundleに含まれ得ます。API key、token、passwordなどを公開変数として設定してはいけません。すでに公開bundleへ出た値を秘密に戻すことはできないため、漏えいの疑いがあれば単なる再Deploymentではなく、発行元サービスでの失効・再発行を含むインシデント対応が必要です。

変更後に安全な新規Deploymentで確認する

変更が必要だと判断した場合は、対象のProjectとEnvironmentだけを選んで新しいDeploymentを作る計画にします。Production変更は実トラフィックに影響する操作です。権限とリリース手順に従い、検証目的ならPreviewなど適切な環境から確認してください。今回の記事は一般的な切り分け手順であり、特定ProjectのProduction再Deploymentを勧めるものではありません。

  1. 変更前に対象URL、Project、Environment、Branch、現在のDeploymentを記録する。

  2. 変数の名前、適用範囲、Environment、Branch条件をDashboardで再確認する。値を画面録画・チャット・Issueへコピーしない。

  3. 変更後のDeploymentが必要な理由を確認する。既存Deploymentの再割当やrollbackが新しいBuildを行うとは限らない。

  4. 最初はリスクの低いPreview Deploymentを選び、変更がそのEnvironmentに適用される条件を確認してBuildする。

  5. Deploymentが成功したら、Deploymentの状態・作成時刻・Preview URLを確認し、期待する機能の非秘密な結果を試す。

  6. 問題があればログの該当エラーを確認する。ただしtokenや環境変数値を出力するログを追加しない。

  7. 既存の本番手順・承認に従ってProductionへ反映する必要がある場合は、変更範囲・rollback先・確認項目を準備してから実施する。

Vercelの「Promote」と「Redeploy」やRollbackを同じ操作として扱わないことも重要です。既存Deploymentへ即時にDomainを付け替えるRollbackなどは完全な再Buildを行わず、Build時に使う環境変数を更新しない場合があります。PreviewからProductionへの昇格方法も操作によって再Buildの有無が異なるので、環境変数の更新を取り込む目的なら、対象の公式手順でその操作が新しいBuildを作るかを確認してください。既存のBuild成果物を昇格させるだけなら、新しく保存した環境変数が含まれるとは限りません。

Secretをローテーションする場合

API keyやtokenの入れ替えでは、環境変数の更新と旧credentialの失効を一度に行わない方が安全です。Vercelの公式手順は、新しいcredentialを発行し、Vercel側の正しいProject・Environmentへ登録し、依存Deploymentを更新して正常性を確認してから旧credentialを失効させる流れを示しています。Teamレベルの変数を複数Projectが使っているなら、依存Projectを洗い出し、対象Deploymentをすべて確認する必要があります。

ただし、旧値を残す期間や切替方法は発行元サービスの仕様と組織のセキュリティルールによって異なります。侵害が疑われるcredentialは「安全な切替のため」と無期限に有効化しておかず、セキュリティ対応を優先します。旧値を残すのが安全か判断できない場合は、サービス所有者・Security担当へ確認してください。具体的なsecret値を記事、スクリーンショット、ログ、サポート依頼へ貼り付けないでください。

確認しても解決しない場合の診断

新Deploymentでも以前の値に見える

Deploymentが本当に新しいBuildか、正しいEnvironment・Branchで作られたかを再確認します。Build logに値そのものを出さず、必要なら「値が設定されているか」「既知の安全なテスト値と一致するか」だけを検査する仕組みを使います。変数名がコードで一致しているか、大小文字や空白の誤りがないかも確認します。外部サービスの設定画面を変えたのに応答が古い場合は、Vercelの環境変数ではなく、外部サービス側やアプリケーションキャッシュが原因の可能性があります。

Buildは成功したが、機能が失敗する

Build成功は、外部APIの認証・権限・ネットワーク接続まで保証しません。アプリが使う外部サービスでcredentialが有効か、対象環境に必要な権限があるか、APIの許可OriginやIP制限が一致しているかを、秘密値を露出させずに確認します。エラー本文を共有するときはtoken、個人情報、接続文字列を必ず除去します。

古いURLを開いている可能性がある

Production Domain、Deployment固有URL、Preview URLを区別します。ブックマークや固定リンクが過去Deploymentを指していないか、DashboardでURLとDeploymentの対応を照合します。ブラウザーやアプリのキャッシュを消す前に、別の新規Deployment URLで同じ挙動か確認すれば、どの層に差があるかを切り分けやすくなります。キャッシュ削除を行っても、build時にbundleへ固定された値は更新されません。

変更対象を特定できない

同名変数がTeamとProject、ProductionとPreview、Branch固有Previewに存在する場合は、変更前に対象構成を一覧化します。既存値を消したり、全Environmentへ一括適用したりする前に、利用Project・Branch・Deploymentを確認してください。設定を広範囲に変えると、無関係なPreviewや他Projectへ影響する可能性があります。

迷ったときの判断フロー

  • 以前のDeploymentを開いているか? はいなら、まず対象Deploymentの作成時刻とEnvironmentを確認する。

  • 変更したEnvironmentがアクセス先と一致するか? いいえなら、必要なEnvironmentだけを修正する。

  • PreviewのBranch固有値がないか? あるなら、そのBranchで適用される値を確認する。

  • 値が NEXT_PUBLIC_ か、Build時に使われるか? はいなら、新しいBuildが必要かを確認する。

  • 既存DeploymentのPromote / Rollbackだけを実行したか? その操作が再Buildしたか公式仕様で確認する。再Buildなしなら新しい値を取り込んだと決めつけない。

  • 新しいBuildでも変わらないか? 変数名、アプリの読み取り方法、外部サービス、キャッシュ、実際に見ているURLを順に調べる。

  • Productionやcredential失効に影響するか? 影響範囲と復旧手順を確認し、必要な承認・Security手順を通してから実施する。

最終確認では、変更対象と同じProject・Environment・Branchの新しいDeploymentを使い、秘密値を画面やログに出さず期待する機能をテストします。反映を確認した記録には、変数名、Environment、Branch条件、Deployment URLと時刻、テスト結果を残し、変数値そのものは残しません。

この記事で確認できていないこと

ここでは一般的なVercel・Next.jsの仕様を整理しています。読者のVercel ProjectがTeam変数を使っているか、Custom EnvironmentやBranch固有値があるか、現在どのDeploymentにDomainが割り当てられているか、アプリのコードが値をどの時点で読み込むかは個別確認が必要です。これらはProjectのDashboardと実装を見ずに確定できないため、本文から特定の設定を推定しません。

Sources