Next.js生产环境Resend邮件发送失败,开发环境正常
Next.js + Resend 邮件功能:环境变量API密钥无法生效(开发/生产/Vercel部署均失败)
我在Next.js项目中用Resend实现邮件发送,开发环境下硬编码API密钥可以正常运行,但改用process.env.RESEND_API_KEY或process.env.NEXT_PUBLIC_RESEND_API_KEY(已在.env.local配置)后,开发和生产环境都失效,部署到Vercel后完全无法使用。
以下是相关代码:
API路由代码(/app/api/send/route.ts):
import { EmailTemplate } from "@/components/email-template"; import { Resend } from "resend"; const resend = new Resend("myApiKey"); // 仅开发环境有效 // const resend = new Resend(process.env.NEXT_PUBLIC_RESEND_API_KEY); // 完全无效 // const resend = new Resend(process.env.RESEND_API_KEY); // 完全无效 export async function POST(request: Request) { const { name, numberPhone, address, productsInCart} = await request.json(); try { const data = await resend.emails.send({ from: "Contact Form <onboarding@resend.dev>", to: ["someoneemail@gmail.com"], subject: "New order from your ecommerce app.", react: EmailTemplate({ name: name, numberPhone: numberPhone, address: address, productsInCart: productsInCart }), }); return Response.json(data); } catch (error) { return Response.json({ error }); } }
前端调用代码:
const handleSendDataViaEmailResend = async () => { try { setLoading(true); const response = await fetch("/api/send", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: formData.name, email: formData.email, numberPhone: formData.numberPhone, address: formData.address, productsInCart: productsInCart, }), }); if (response.ok) { console.log("Order placed successfully!"); router.push("/success"); } else { console.error("Error placing order:", response.statusText); } } catch (error) { console.error("Error placing order:", error); } finally { setLoading(false); } };
需要解决生产环境(包括Vercel部署)的邮件发送问题。
解决方案
1. 环境变量的正确配置
- 服务器端变量规则:API路由运行在服务器端,无需暴露给前端,必须使用不带
NEXT_PUBLIC_前缀的环境变量RESEND_API_KEY。NEXT_PUBLIC_前缀的变量会被打包到前端代码,既不安全也不适用于服务器端逻辑。 - 本地开发配置:在项目根目录的
.env.local文件中添加:
注意:修改RESEND_API_KEY=你的Resend API密钥.env.local后必须重启Next.js开发服务器,否则环境变量不会加载。 - Vercel部署配置:进入Vercel项目的「Settings」→「Environment Variables」,添加
RESEND_API_KEY变量并填入密钥,确保变量作用范围包含「Production」。
2. API路由代码修正
修改API路由,添加环境变量校验,避免未定义导致初始化失败:
import { EmailTemplate } from "@/components/email-template"; import { Resend } from "resend"; // 校验环境变量是否存在,提前抛出错误便于调试 const resendApiKey = process.env.RESEND_API_KEY; if (!resendApiKey) { throw new Error("RESEND_API_KEY 环境变量未配置,请检查.env.local或Vercel环境变量"); } const resend = new Resend(resendApiKey); export async function POST(request: Request) { const { name, numberPhone, address, productsInCart } = await request.json(); try { const data = await resend.emails.send({ from: "Contact Form <onboarding@resend.dev>", to: ["someoneemail@gmail.com"], subject: "New order from your ecommerce app.", react: EmailTemplate({ name, numberPhone, address, productsInCart }), }); return Response.json(data); } catch (error) { // 返回具体错误信息,便于调试生产环境问题 return Response.json( { error: (error as Error).message }, { status: 500 } ); } }
3. 调试与验证步骤
- 本地开发调试:在API路由中临时添加
console.log(process.env.RESEND_API_KEY)(生产环境前删除),重启开发服务器后触发邮件请求,查看终端日志确认变量是否正确加载。 - Vercel生产调试:部署后进入Vercel控制台的「Functions」→「Logs」,查看
/api/send函数的运行日志,检查是否有环境变量未找到、Resend密钥无效或权限错误等信息。 - 参数校验:确保前端发送的参数与API路由接收的参数匹配(比如API路由未接收
email参数,不影响但可以统一参数列表)。
4. 额外注意事项
- 绝对不要将Resend API密钥设为
NEXT_PUBLIC_前缀,这会导致密钥泄露给所有访问网站的用户,引发安全风险。 - 确认Resend API密钥有效:登录Resend控制台,检查密钥是否未过期、未被禁用。
- 生产环境建议使用Resend验证过的自定义域名发送邮件,避免默认
onboarding@resend.dev域名可能出现的投递限制。
内容的提问来源于stack exchange,提问作者roudlek
相关产品推荐
相关产品推荐

