如何修复NextJS 13.4.12中React-Email与Resend的意外服务器错误?
解决方案:Next.js App Router + Resend ReactServerComponentsError 修复
1. 修正API路由的语法错误
你提供的API路由代码存在语法错误(多余的代码块标签),这会导致运行时异常。正确的app/api/register/route.ts代码如下:
import bcrypt from 'bcrypt'; import prisma from "@/app/libs/prismadb"; import { NextResponse } from 'next/server'; import { resend } from '@/app/libs/resend'; export async function POST(request: Request) { const body = await request.json(); const { email, firstName, lastName, password } = body; // 用户注册逻辑示例 const hashedPassword = await bcrypt.hash(password, 10); const user = await prisma.user.create({ data: { email, firstName, lastName, hashedPassword, }, }); // 发送邮件(添加错误捕获) try { await resend.emails.send({ from: "onboarding@resend.dev", to: email, subject: "Welcome", html: "<h1>Thanks for signing up!</h1>" }); } catch (err) { console.error('邮件发送失败:', err); // 可选:根据业务需求返回错误响应 // return NextResponse.json({ error: '邮件发送失败' }, { status: 500 }); } return NextResponse.json(user); }
2. 确保Resend初始化文件为纯服务端模块
检查app/libs/resend.ts的代码,确保它仅包含服务端初始化逻辑,不要添加"use client"指令:
import { Resend } from 'resend'; // 直接初始化Resend实例,仅在服务端环境运行 export const resend = new Resend(process.env.RESEND_API_KEY);
3. 排查导入范围,避免客户端导入Resend
错误的核心原因是Resend模块被客户端代码意外导入。请检查所有代码:
- 仅在服务端代码(API路由、Server Actions、无"use client"的Server Components)中导入
@/app/libs/resend - 如果客户端组件需要触发注册/发送邮件,通过Server Action或API路由间接调用,不要直接导入Resend实例
4. 移除冲突的Next.js配置
如果你之前在next.config.js中添加了serverComponentsExternalPackages: ['resend'],请移除该配置——Resend官方包已适配Next.js,额外配置会导致模块加载异常。
5. 正确使用React-Email模板(如果用到)
若使用React-Email编写邮件模板,确保模板文件为Server Component(无"use client"),并通过@react-email/render在服务端渲染为HTML:
// app/emails/WelcomeEmail.tsx(Server Component) export default function WelcomeEmail({ firstName }: { firstName: string }) { return ( <html> <body> <h1>Welcome, {firstName}!</h1> <p>Thanks for joining our platform.</p> </body> </html> ); }
在API路由中调用:
import WelcomeEmail from '@/app/emails/WelcomeEmail'; import { render } from '@react-email/render'; // ... await resend.emails.send({ from: "onboarding@resend.dev", to: email, subject: "Welcome", html: render(<WelcomeEmail firstName={firstName} />), });
6. Server Action 方式的正确写法(如果使用)
若用Server Action处理注册,确保Action文件标记为'use server',且仅在服务端运行:
// app/actions/registerAction.ts 'use server'; import bcrypt from 'bcrypt'; import prisma from "@/app/libs/prismadb"; import { resend } from '@/app/libs/resend'; export async function registerUser(formData: FormData) { const email = formData.get('email') as string; const firstName = formData.get('firstName') as string; const lastName = formData.get('lastName') as string; const password = formData.get('password') as string; const hashedPassword = await bcrypt.hash(password, 10); const user = await prisma.user.create({ data: { email, firstName, lastName, hashedPassword } }); await resend.emails.send({ from: "onboarding@resend.dev", to: email, subject: "Welcome", html: `<h1>Welcome, ${firstName}!</h1>` }); return user; }
客户端组件中调用时,仅导入并执行该Action即可,无需直接接触Resend实例。
内容的提问来源于stack exchange,提问作者Kersmo
相关产品推荐
相关产品推荐

