← [ BACK_TO_NOTES ]

Next.js 环境变量与 Server-only Secret 边界

解释 Next.js 中服务端环境变量、NEXT_PUBLIC_ 构建时公开变量与 server-only 模块边界,避免 Secret 意外进入客户端 bundle。

#concept #growing #frame #security #react

[!info] related notes

Next.js 环境变量与 Server-only Secret 边界

一句话定义

Next.js 默认把普通环境变量留在服务器;只有显式使用 NEXT_PUBLIC_ 前缀的变量才应进入浏览器可见代码,并且这类值通常在构建阶段被内联进客户端 bundle。

两类变量

DATABASE_URL
AUTH_SECRET
API_KEY
→ server-only

NEXT_PUBLIC_ANALYTICS_ID
NEXT_PUBLIC_SITE_URL
→ public client config

最重要的规则:

NEXT_PUBLIC_
= 可以公开给任何访问网页的人
≠ “前端也能安全保存 Secret”

为什么 NEXT_PUBLIC_ 要谨慎

客户端 bundle 是用户可以下载和检查的代码,所以一旦变量进入浏览器:

public variable
→ assume fully visible

不能把数据库密码、Auth Secret、第三方私钥等放进去。

另外,公开变量通常在 next build 时被内联,因此构建完成后再修改部署环境里的值,不一定能改变已经生成的客户端 JS。

Server-only 模块

即使普通 env 默认不会被暴露,也应该防止含 Secret 的数据模块被误导入 Client Component:

import 'server-only'

典型 server-only 模块包括:

  • 数据库访问
  • Auth secret
  • 私有 API client
  • Repository
  • 内部 Service client

这样可以把“不要在客户端用”从团队约定提升为构建期边界。

Runtime vs Build-time

Server runtime env
→ 服务端请求执行时读取

NEXT_PUBLIC_* client env
→ 常见情况在 build 时固化进 bundle

这意味着同一个 Docker image 跨环境推广时,公开配置的处理方式与 server runtime secret 不一定相同。

与 Server Component 的关系

Server Component 可以读取服务器环境变量,但不能把 Secret 作为 props 传给 Client Component:

Server knows secret
≠ browser should receive secret

正确做法是服务端使用 Secret 完成访问,再只返回 UI 真正需要的数据。

最短记忆

no prefix → server by default
NEXT_PUBLIC_ → browser-visible
browser-visible → not a secret
server-only → protect module boundary
server can read secret ≠ client can receive secret
创建于 2026/9/16 更新于 2026/9/16
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本