Vercel环境变量在Next.js应用中无法正常工作的问题排查
问题分析与解决方案
核心原因
Next.js 对环境变量的处理规则很明确:
- 带
NEXT_PUBLIC_前缀的变量会被打包到客户端代码中,浏览器能直接访问,但必然会暴露给所有用户。 - 不带这个前缀的变量(比如你设的
API_KEY),只能在服务端环境中访问,客户端组件直接调用process.env.API_KEY肯定返回undefined——因为这些变量根本不会被注入到客户端打包产物里。
你的情况就是因为在客户端组件里直接尝试读取服务端专属的环境变量,自然拿不到值。
正确的做法
不要让客户端直接调用外部天气API,而是通过 Next.js 的API Route做中间层:
- 在项目的
pages/api目录下新建一个文件(比如weather.js),在这个文件里编写服务端逻辑:export default async function handler(req, res) { const apiKey = process.env.API_KEY; // 这里能正常拿到Vercel上配置的非NEXT_PUBLIC变量 const { city } = req.query; // 调用外部天气API,用apiKey做鉴权 const response = await fetch(`https://外部天气API地址?city=${city}&key=${apiKey}`); const data = await response.json(); res.status(200).json(data); } - 客户端组件里不再直接调用外部API,而是请求这个内部的API Route:
async function fetchWeather(city) { const response = await fetch(`/api/weather?city=${city}`); const data = await response.json(); return data; }
这样一来,API密钥只会在服务端的API Route里使用,完全不会暴露给客户端,同时也能正常获取天气数据。
补充说明
不管是客户端组件还是服务端组件,只要是在浏览器环境执行的代码,都无法访问非 NEXT_PUBLIC_ 前缀的环境变量——这是Next.js的安全设计,目的就是防止敏感密钥泄露。所以核心思路就是把密钥的使用逻辑放到服务端,客户端只和自己的API Route交互。
内容的提问来源于stack exchange,提问作者onelegtony
相关产品推荐
相关产品推荐

