ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Next.js 环境变量公开化:用 NEXT_PUBLIC_ 前缀把变量安全暴露给浏览器端代码

2026/10/7 20:24:51 拓冰建站 浏览量
Next.js 环境变量公开化:用 NEXT_PUBLIC_ 前缀把变量安全暴露给浏览器端代码 文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载导读在 Next.js 应用中.env.development、.env.production等环境变量文件为不同环境开发、测试、生产提供了无缝切换配置的能力但默认情况下这些变量不会进入浏览器端的客户端代码。本文基于 til 仓库的实战笔记讲解为什么process.env.API_BASE_URL在客户端组件中会得到undefined以及如何通过NEXT_PUBLIC_前缀把非敏感变量如 API 基础地址公开暴露给前端同时结合仓库中的相关笔记补充.env*文件的加载顺序、变量优先级与真实迁移场景让你彻底掌握 Next.js 环境变量的公开化机制。从.env文件说起按环境切分配置在 Next.js 项目中环境变量的常见做法是把它写在 dotenv 格式的文件里并按运行环境拆分。你可以在.env.development和.env.production中分别定义变量从而让同一份代码在不同环境下读取到不同的值。一个典型场景就是 API 请求的基础地址base URL开发环境指向本地服务器生产环境指向线上服务器。可以这样定义API_BASE_URLlocalhost:3000/api/v1例如在.env.development中写入上述内容开发环境的服务就能读到它同理在.env.production中写入线上地址生产构建就使用线上地址。这是 dotenv 文件作为“环境级配置载体”的核心价值。注意上例中的localhost:3000/api/v1只是笔记中的示意写法实际使用时应包含协议例如http://localhost:3000/api/v1或https://api.example.com/api/v1否则请求方无法正确解析。客户端代码读不到环境变量默认被排除在构建之外把变量写进.env.development/.env.production后问题很快就会出现从任何客户端页面或组件里都取不到这个值。process.env.API_BASE_URL // undefined这是 Next.js 有意为之的安全设计。环境变量里存放的往往是私钥private keys、密钥secrets等敏感信息如果默认就把所有环境变量打进公开的客户端代码client code包等于把密钥直接暴露给任何能查看页面源码的人。因此服务端Server Components、API Routes、getServerSideProps等可以读取全部环境变量客户端浏览器端执行的组件与页面代码默认读不到任何环境变量Next.js在构建时默认将所有环境变量排除出客户端 bundle。换句话说不是变量没定义而是 Next.js 出于安全考虑刻意不让它进入浏览器可见的作用域。用 NEXT_PUBLIC_ 前缀公开变量如果某个变量的值并非机密比如 API 基础地址你希望它出现在浏览器端代码里办法就是给变量名加上NEXT_PUBLIC_前缀NEXT_PUBLIC_API_BASE_URLlocalhost:3000/api/v1加上前缀之后这个变量在任何客户端和服务端代码中都可以访问process.env.NEXT_PUBLIC_API_BASE_URL // localhost:3000/api/v1这背后的机制是Next.js 在构建时会对代码中出现的process.env.NEXT_PUBLIC_*进行静态替换inline——它不是在运行时去读系统环境而是在编译阶段就把字面量直接写入产出的 JavaScript 文件里。这也带来两个重要推论公开变量在构建时固化NEXT_PUBLIC_变量的值取自构建build那一刻的环境而不是运行时环境。如果你改了.env.production中的值需要重新构建部署才能让线上生效。只适用于非敏感信息任何加了NEXT_PUBLIC_的变量都会以明文形式出现在浏览器可下载的 bundle 中绝对不要用它存放 API 密钥、数据库密码、签名密钥等机密。命名约定一览变量类别示例客户端可读用途普通环境变量API_BASE_URL否返回undefined服务端密钥、内部配置公开环境变量NEXT_PUBLIC_API_BASE_URL是需要进入浏览器 bundle 的非敏感值结合仓库笔记.env 文件如何被加载与覆盖要让NEXT_PUBLIC_变量真正“按环境生效”还需要理解 Next.js 加载.env*文件的顺序。仓库中的另一篇笔记 precedence-of-dot-env-files.md 给出了完整的规则一个活跃开发中的项目里.env*文件往往会有很多变体$ ls -a -1 .env* .env .env.development .env.development.local .env.development.local.example .env.local .env.production .env.testNext.js 的加载逻辑是始终尝试加载.env与.env.localtest环境除外测试中不加载.env.local根据NODE_ENV取值development、test、production再加载对应的环境专用文件例如开发环境会加载.env.development与.env.development.local像.env.development.local.example这类文件并不在加载清单里它只是 dotenv 模板文件的社区约定命名提供一份可复制的示例模板。变量覆盖优先级从高到低为系统环境即已经存在于process.env中的变量最高其次是按下列顺序查找文件找到即用、不再继续.env.$(NODE_ENV).local.env.local.env.$(NODE_ENV).env把这些规则与本文主题结合可以得出一个实战要点如果你希望开发环境使用http://localhost:3000/api/v1、生产环境使用线上地址可以在.env.development和.env.production中分别定义NEXT_PUBLIC_API_BASE_URL而.env.local中定义的公开变量会覆盖同名变量适合本地临时调试。仓库中的真实场景全局批量迁移 NEXT_PUBLIC_ 变量仓库里还有一篇与NEXT_PUBLIC_直接相关的实战笔记 negative-look-ahead-search-with-ripgrep.md记录了一次真实的重构过程在一个大型 monorepo 中需要把大量NEXT_PUBLIC_SANITY_DATASET变量统一改名为NEXT_PUBLIC_SANITY_DATASET_ID注意末尾追加了_ID。如果直接搜索NEXT_PUBLIC_SANITY_DATASET会返回一大堆已经改过名的结果难以定位“还剩下哪些旧变量”。笔记给出的方案是使用正则的负向前瞻negative look-ahead匹配“后面不跟_ID”的旧变量$ rg --pcre2 NEXT_PUBLIC_SANITY_DATASET(?!_ID) --hidden --glob !node_modules/** --glob !.git/**关键点在于默认的 ripgrep 正则引擎Rust 正则库不支持 look-around直接执行会报regex parse error错误信息会明确提示需要使用--pcre2标志加上--pcre2后就可以精确列出所有仍在使用旧变量名的文件与行号例如.env.development中的NEXT_PUBLIC_SANITY_DATASETproduction。这个场景恰好展示了NEXT_PUBLIC_变量常见的生命周期它们广泛散落在.env*配置文件、服务端脚本和前端代码中重命名或迁移时需要精确的检索手段。实战检查清单综合本文内容使用NEXT_PUBLIC_变量时建议遵循以下清单确认值非敏感要公开的变量绝不能在浏览器 bundle 中泄露机密信息统一前缀命名客户端需要读取的变量一律以NEXT_PUBLIC_开头例如NEXT_PUBLIC_API_BASE_URL按环境拆分文件在.env.development/.env.production或带.local的优先级更高变体中定义不同取值记住构建时替换修改NEXT_PUBLIC_变量后必须重新构建next build并重新部署浏览器端才会拿到新值服务端变量不加前缀仅供服务端使用的密钥保持普通命名避免误入客户端 bundle迁移时精确检索批量重命名NEXT_PUBLIC_变量时可用rg --pcre2配合负向前瞻只命中旧变量。小结Next.js 出于安全考虑默认不把环境变量打进客户端代码process.env.API_BASE_URL在浏览器端返回undefined是预期行为而非 bug。要让非敏感变量公开可见只需给变量名加上NEXT_PUBLIC_前缀它就会被构建器静态内联进客户端 bundle从而在页面、组件与服务端代码中统一通过process.env.NEXT_PUBLIC_*读取。结合 til 仓库中关于.env*加载顺序与 ripgrep 迁移的笔记你可以在真实项目中正确组织、覆盖并维护这些公开环境变量。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐给 Vane 接上外部 SearXNG2 处配置跑通搜索给 Vane 接上外部 SearXNG2 处配置跑通搜索 Vane 是一个 AI 问答引擎它的联网检索能力全部依赖外部 SearXNG 实例。接入 Sear人工智能大模型AI 应用本地部署后端前端papers-notebook揭秘5个必读的分布式调度器论文及其核心思想papers notebook揭秘5个必读的分布式调度器论文及其核心思想 在分布式系统领域高效的资源调度是提升集群性能的关键。 papers notebooCMake PackageName_ROOT 环境变量详解用环境变量为 find_package 指定搜索前缀CMake PackageName _ROOT 环境变量详解用环境变量为 find_package 指定搜索前缀 PackageName _ROOT 是构建工具开发工具CLI上一篇如何3步完成黑苹果智能配置OpCore Simplify终极指南下一篇终极AtlasOS网络共享配置指南3种方法快速恢复局域网文件共享创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考