0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nuxt3のruntimeConfigとenv設定の使い分け比較|AI実務ノート 編集部

Last updated at Posted at 2026-01-03

1. 結論(この記事で得られること)

Nuxt3のruntimeConfigと環境変数(.env)の違い、正直よく分からないまま使っていませんか?私も最初はそうでした。

この記事で得られる実務知識:

  • runtimeConfigとenvの根本的な違いと、使い分けの明確な判断基準
  • 「クライアント側に漏れてはいけない値」を守る安全な設計方法
  • ビルド時 vs ランタイム時の挙動差異とパフォーマンス影響
  • AIを活用した環境変数の問題切り分け最速フロー
  • 本番環境で死活問題になる失敗パターン(実例付き)

レビューで「これクライアントに秘密鍵漏れますよ」と指摘される前に、この記事で正しい知識を身につけましょう。

2. 前提(環境・読者層)

想定環境:

  • Nuxt3(3.8以降推奨)
  • Node.js 18以降
  • SSR / SSGどちらでも対応

想定読者:

  • Nuxt3でAPI連携を始めたが、環境変数の扱いに不安がある方
  • 「import.meta.env」と「useRuntimeConfig()」の違いが曖昧な方
  • セキュリティレビューで秘密情報の扱いを指摘された方

3. Before:よくあるつまずきポイント

実務でよく見る危険なパターンを3つ挙げます。昔の私もやらかしました。

3-1. 秘密鍵をpublicに置いてしまう

// ❌ 危険:これは絶対ダメ
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      apiSecret: process.env.API_SECRET // クライアントに漏れる!
    }
  }
})

このコードをビルドすると、API_SECRETがブラウザのJavaScriptバンドルに含まれます。開発者ツールで誰でも見られる状態です。

3-2. サーバー側の値をクライアントで参照しようとする

<script setup>
// ❌ これはクライアントでundefinedになる
const config = useRuntimeConfig()
const secret = config.apiSecret // public以外はクライアントで取れない
</script>

「ローカルでは動いたのに本番で動かない」の典型パターン。SSRとクライアントハイドレーションの境界を理解していないと起きます。

3-3. import.meta.envとruntimeConfigの混在

// ❌ 混乱の元
const apiUrl = import.meta.env.VITE_API_URL // Vite由来
const config = useRuntimeConfig() // Nuxt由来

両方使えるが故に、チームで統一されず、後からメンテナンスできなくなります。

4. After:基本的な解決パターン

4-1. 正しい使い分けの判断基準

シンプルな原則:

秘密(DB接続情報、外部API秘密鍵)
 使う場所: 「runtimeConfig.xxx」
 アクセス方法: サーバーのみ

公開OK(APIエンドポイント、GA ID)
 使う場所: 「runtimeConfig.public.xxx」
 アクセス方法: サーバー・クライアント両方

ビルド時に固定したい値
 使う場所: 「.env」 + 「import.meta.env」
 アクセス方法: Viteビルド時

4-2. 安全な設定例

nuxt.config.ts:

export default defineNuxtConfig({
  runtimeConfig: {
    // サーバー専用(秘密情報)
    dbUrl: process.env.DATABASE_URL,
    apiSecret: process.env.API_SECRET_KEY,
 
    // publicは省略可能な公開情報
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE || 'https://api.example.com',
      gtmId: process.env.NUXT_PUBLIC_GTM_ID
    }
  }
})

.env:

# サーバー専用(runtimeConfigで受け取る)
DATABASE_URL=postgresql://user:pass@localhost:5432/db
API_SECRET_KEY=super_secret_key_12345
 
# クライアントでも使う(NUXT_PUBLIC_プレフィックス)
NUXT_PUBLIC_API_BASE=https://api.example.com
NUXT_PUBLIC_GTM_ID=GTM-XXXXXX

重要な命名規則:

  • 「NUXT_PUBLIC_」プレフィックスは自動的に「runtimeConfig.public」にマッピングされる
  • プレフィックスなしは「runtimeConfig」のルートに入る

4-3. 使用例

サーバーサイド(server/api/users.ts):

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()
 
  // ✅ サーバーでは秘密情報にアクセスできる
  const db = await connectDB(config.dbUrl)
  const users = await db.query('SELECT * FROM users')
 
  return users
})

クライアントサイド(pages/index.vue):

<script setup>
const config = useRuntimeConfig()
 
// ✅ クライアントではpublicのみアクセス可能
const { data } = await useFetch(`${config.public.apiBase}/users`)
 
// ❌ これはundefined(クライアントでは見えない)
console.log(config.dbUrl) // undefined
</script>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?