在 next.js

Next.js 对环境变量的访问有严格的作用域隔离机制:默认情况下,.env.local 中定义的变量(如 MONGODB_URI、DB_NAME)仅在 Node.js 服务端环境可用,不会被注入到浏览器中。而你在 UI 设计阶段访问授权页面时,很可能依赖某些环境变量(例如用于条件跳转、权限标识或 mock 数据开关)在客户端动态判断登录状态——若这些变量未显式声明为公共变量,Next.js 会在服务端渲染时读取 undefined(因客户端无该变量),而客户端水合(hydration)时却尝试用 undefined 渲染真实 DOM,从而触发经典的 “Text content does not match server-rendered HTML” Hydration 错误。
✅ 正确做法是:所有需在浏览器中使用的环境变量,必须以 NEXT_PUBLIC_ 为前缀。例如:
# .env.local —— 正确写法(客户端可用) NEXT_PUBLIC_APP_ENV=staging NEXT_PUBLIC_REQUIRE_AUTH=true NEXT_PUBLIC_LOGIN_REDIRECT_URL="/dashboard"
# .env.local —— ❌ 错误示例(客户端不可见,仅服务端可用) MONGODB_URI=mongodb://localhost:27017/myapp # → 客户端读不到,可能导致逻辑不一致 DB_NAME=myapp
⚠️ 注意事项:
? 快速验证是否生效:
在组件中打印变量,确认客户端可读取:
// components/AuthGate.tsx
export default function AuthGate() {
const isAuthRequired = process.env.NEXT_PUBLIC_REQUIRE_AUTH === 'true';
console.log('Client-side auth required:', isAuthRequired); // ✅ 应输出 true/false
if (isAuthRequired && !localStorage.getItem('mock-auth-token')) {
return ;
}
return Protected UI Content;
}? 总结:Hydration 错误本质是 SSR 与 CSR 渲染结果不一致。在 Next.js 中,这往往源于环境变量作用域误用。请始终遵循「客户端用 NEXT_PUBLIC_*,服务端用普通变量」的原则,并确保 UI 层逻辑不意外依赖服务端专属配置。完成配置后重启服务,即可顺利进入受保护页面开展 UI 设计工作。