Next.js App Router中如何结合'use client'与运行时环境变量
解决Next.js 14 App Router中客户端组件获取运行时环境变量的问题
问题根源
加了'use client'的组件会在浏览器端运行,而服务器端的运行时环境变量默认不会暴露给客户端。你看到的短暂显示是服务器预渲染的结果,当客户端完成hydration(水化)后,因为浏览器环境没有这个变量,所以就变成undefined了。
可行解决方案
方案1:服务器组件传参(推荐)
利用服务器组件能访问运行时变量的特性,把变量作为props传递给客户端组件:
- 新建一个无
'use client'的服务器组件,用来获取并传递环境变量:
// app/EnvWrapper.js import { noStore } from 'next/cache'; export default function EnvWrapper({ children }) { noStore(); // 维持动态渲染 // 在这里获取你需要的运行时环境变量 const runtimeVars = { MY_CUSTOM_VAR: process.env.MY_CUSTOM_VAR, // 可添加更多变量 }; return children(runtimeVars); }
- 客户端组件接收props并使用:
// app/MyClientComponent.js 'use client'; import { useState } from 'react'; export default function MyClientComponent({ envVars }) { const [count, setCount] = useState(0); return ( <div> <p>运行时变量值:{envVars.MY_CUSTOM_VAR}</p> <button onClick={() => setCount(prev => prev + 1)}>点击计数:{count}</button> </div> ); }
- 在页面中组合两者:
// app/page.js import EnvWrapper from './EnvWrapper'; import MyClientComponent from './MyClientComponent'; export default function HomePage() { return ( <EnvWrapper> {(vars) => <MyClientComponent envVars={vars} />} </EnvWrapper> ); }
这种方式能保证客户端hydration时拿到正确的变量值,同时维持动态渲染和客户端交互能力。
方案2:API路由获取
如果需要在客户端动态拉取最新的环境变量,可以创建一个API路由来返回变量:
- 新建API路由:
// app/api/runtime-env/route.js import { noStore } from 'next/cache'; export async function GET() { noStore(); return Response.json({ MY_CUSTOM_VAR: process.env.MY_CUSTOM_VAR }); }
- 客户端组件中通过fetch获取:
'use client'; import { useState, useEffect } from 'react'; export default function MyClientComponent() { const [count, setCount] = useState(0); const [envVar, setEnvVar] = useState(''); useEffect(() => { const getEnv = async () => { const res = await fetch('/api/runtime-env'); const data = await res.json(); setEnvVar(data.MY_CUSTOM_VAR); }; getEnv(); }, []); return ( <div> <p>运行时变量值:{envVar}</p> <button onClick={() => setCount(prev => prev + 1)}>点击计数:{count}</button> </div> ); }
关键注意点
- 不要用
NEXT_PUBLIC_前缀的变量来满足运行时需求:这类变量是构建时注入的,无法在docker-compose运行时动态修改。 - 确保docker-compose中的环境变量正确传递给Next.js容器:在
docker-compose.yml的environment字段中定义变量,容器启动时能正常读取。
内容的提问来源于stack exchange,提问作者Maxim VA
相关产品推荐
相关产品推荐

