You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:28:18