Nuxt 4 运行时配置:开发与生产环境优雅切换 API

用 runtimeConfig 管理 Nuxt 4 的公开配置与服务端私密配置,实现本地、测试和生产环境切换,并避开构建后环境变量不生效的问题。

Nuxt 4 运行时配置:开发与生产环境优雅切换 API

同一套 Nuxt 代码通常要运行在本地、测试和生产环境。最容易留下隐患的做法,是在组件里散落 process.env,或把接口域名直接写死。Nuxt 4 提供的 runtimeConfig 可以把配置集中管理,并明确哪些值能够暴露给浏览器。

先分清 public 与私密配置

配置位置 服务端可用 客户端可用 典型用途
runtimeConfig 根级别 API 密钥、内部服务地址
runtimeConfig.public 公共 API 地址、站点域名

只要放进 public,它就会进入页面 payload,用户能够在浏览器里看到。因此数据库密码、签名密钥和第三方私钥绝不能放在 public

在 nuxt.config.ts 中声明默认值

ts
export default defineNuxtConfig({
  runtimeConfig: {
    apiSecret: '',
    internalApiBase: 'http://127.0.0.1:48090',
    public: {
      apiBase: 'http://127.0.0.1:40090/app-api',
      siteUrl: 'http://localhost:3000',
    },
  },
})

声明配置项后,Nuxt 才知道哪些环境变量允许覆盖它们。与其在这里读取名字完全不同的环境变量,更稳妥的方式是使用 Nuxt 约定的变量名。

环境变量命名规则

层级通过下划线连接,并以 NUXT_ 开头:

bash
NUXT_API_SECRET=server-only-secret
NUXT_INTERNAL_API_BASE=http://127.0.0.1:48090
NUXT_PUBLIC_API_BASE=https://www.example.com/app-api
NUXT_PUBLIC_SITE_URL=https://www.example.com

runtimeConfig.public.apiBase 对应 NUXT_PUBLIC_API_BASE。这种命名既能在开发阶段生效,也能在构建后的 Node 服务启动时覆盖配置。

在页面和服务端读取配置

页面、组件和 composable 中:

ts
const config = useRuntimeConfig()

const { data } = await useFetch('/blog/article/page', {
  baseURL: config.public.apiBase,
})

Nitro 服务端路由中建议把 event 传给 useRuntimeConfig

ts
export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig(event)

  return await $fetch('/internal/statistics', {
    baseURL: config.internalApiBase,
    headers: {
      Authorization: `Bearer ${config.apiSecret}`,
    },
  })
})

浏览器只能访问 config.public 与 Nuxt 内部的 app 配置,根级别私密配置只存在于服务端。

开发环境与生产环境如何设置

本地开发可以在项目根目录的 .env 中写:

dotenv
NUXT_PUBLIC_API_BASE=http://127.0.0.1:40090/app-api
NUXT_PUBLIC_SITE_URL=http://localhost:3000

生产环境不要依赖构建目录旁边的 .env。Nuxt 官方文档明确说明:运行构建后的服务时,不会自动读取项目的 .env。应在宝塔、Docker、systemd、PM2 或云平台的环境变量面板中配置,再启动:

bash
NODE_ENV=production \
NUXT_PUBLIC_API_BASE=https://www.example.com/app-api \
NUXT_PUBLIC_SITE_URL=https://www.example.com \
node .output/server/index.mjs

封装统一请求客户端

接口多起来后,可以在插件里集中设置 baseURL:

ts
export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  const api = $fetch.create({
    baseURL: config.public.apiBase,
    timeout: 10_000,
    onResponseError({ response }) {
      console.error('API 请求失败', response.status)
    },
  })

  return { provide: { api } }
})

使用时通过 useNuxtApp().$api 调用,后续增加请求头、错误提示和登录失效处理都有统一入口。

常见问题

  • 修改服务器环境变量后没有重启 Node 进程。
  • 配置未先声明在 nuxt.config.ts 中。
  • 生产运行仍期待 Nuxt 自动读取 .env
  • 把私钥放进 runtimeConfig.public
  • 使用了不符合层级结构的环境变量名。
  • 在客户端请求里写服务器内网地址,导致用户浏览器无法访问。

小结

环境配置的核心不是多准备几个文件,而是把公开配置和私密配置划清边界,并使用可以在运行时覆盖的标准变量名。做到这一点,同一份 .output 就能在不同环境部署,而不需要为了更换 API 地址重新修改业务代码。

参考:Nuxt 4 Runtime Config 官方文档