在 NextJS 中,如果想让浏览器上的 JS 代码使用一个环境变量,需要为其增加 NEXT_PUBLIC_ 前缀,就可以通过 process.env.NEXT_PUBLIC_XXX 访问到。
一般在开发阶段,我们会将这些变量写到 .env.local 文件中,但需要注意的是,在生产环境下通过 standalone 模式运行时,,这一类变量无法从 .env 文件中读取,而是要在 build 时就传递过去。
这是因为 NEXT_PUBLIC_ 变量是通过写入 js bundle 的方式传递给浏览器的运行环境的。官方文档对此的解释如下 [^1]:
> In order to make the value of an environment variable accessible in the browser, Next.js can "inline" a value, at build time, into the js bundle that is delivered to the client, replacing all references to process.env.[variable] with a hard-coded value.
如果你的 NextJS 应用是通过 docker image 部署,务必确保以某种方式让 docker build 访问到这些变量。这里有一篇博客可以参考: https://www.tomoliver.net/posts/nextjs-docker-public-env-vars, 也可以在 GitHub 论坛里找到更多全世界开发者们贡献的解决方案 [^2]。
我的 Next app 是通过 GitHub Actions 构建镜像,因此我个人的做法是将 NEXT_PUBLIC_ 前缀的变量单独拿出来,放在 Actions secrets 中,并在 workflow yaml 里取出 secret 写入 .env 文件,使得 Dockerfile 可以利用它。
[^1]: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
[^2]: https://github.com/vercel/next.js/discussions/17641
一般在开发阶段,我们会将这些变量写到 .env.local 文件中,但需要注意的是,在生产环境下通过 standalone 模式运行时,,这一类变量无法从 .env 文件中读取,而是要在 build 时就传递过去。
这是因为 NEXT_PUBLIC_ 变量是通过写入 js bundle 的方式传递给浏览器的运行环境的。官方文档对此的解释如下 [^1]:
> In order to make the value of an environment variable accessible in the browser, Next.js can "inline" a value, at build time, into the js bundle that is delivered to the client, replacing all references to process.env.[variable] with a hard-coded value.
如果你的 NextJS 应用是通过 docker image 部署,务必确保以某种方式让 docker build 访问到这些变量。这里有一篇博客可以参考: https://www.tomoliver.net/posts/nextjs-docker-public-env-vars, 也可以在 GitHub 论坛里找到更多全世界开发者们贡献的解决方案 [^2]。
我的 Next app 是通过 GitHub Actions 构建镜像,因此我个人的做法是将 NEXT_PUBLIC_ 前缀的变量单独拿出来,放在 Actions secrets 中,并在 workflow yaml 里取出 secret 写入 .env 文件,使得 Dockerfile 可以利用它。
[^1]: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
[^2]: https://github.com/vercel/next.js/discussions/17641