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

Next.js 13 Server Actions发邮件时客户端组件调用错误求助

解决Next.js 13 Server Actions + Resend + React Email的客户端/服务端组件冲突问题

完整错误

尝试从服务端调用/email/contact-form-email.tsx的默认导出,但它是客户端组件。无法从服务端调用客户端函数,仅能将其作为组件渲染或传递给客户端组件的props。

环境说明

使用Next.js 13的Server Actions发送邮件,依赖包版本:

"resend": "^0.16.0"
"@react-email/components": "^0.0.7"

用于邮件服务和邮件样式设置。

现有代码

sendEmail.ts(Server Action文件)

'use server'

import React from 'react';
import { getErrorMessage, validateData } from '@/lib/utils';
import { Resend } from 'resend';
import ContactFormEmail from '@/email/contact-form-email';

const resend = new Resend(process.env.RESEND_API_KEY);
export const sendEmail = async(formData : FormData) => {
    const senderEmail = formData.get('senderEmail'); 
    const contactMessage = formData.get('contactMessage');

    try {
      console.log('sender email : ' + senderEmail);
      console.log('contact message : ' + contactMessage);
      
      resend.emails.send({
        from: 'Contact form  <onboarding@resend.dev>',
        to: 'test@gmail.com',
        subject: 'Message from contact form of portfolio.',
        reply_to: senderEmail as string,
        react : React.createElement(ContactFormEmail, {
          contactMessage: contactMessage as string, 
          senderEmail : senderEmail as string, 
        })
      });
    } catch (error : unknown) {
      return {
        error: getErrorMessage(error)
      }
    }
}

contact-form-email.tsx(邮件模板文件)

'use client'

import React from 'react'
import {
    Html,
    Body,
    Head, 
    Heading,
    Hr,
    Container,
    Preview,
    Section,
    Text
} from '@react-email/components'
import { Tailwind } from '@react-email/tailwind'

type ContactFormEmailProps = {
    contactMessage : string,
    senderEmail : string, 
}

function ContactFormEmail({contactMessage, senderEmail } : ContactFormEmailProps) {
  return (
   <Html>
    <Head/>
    <Preview>New message from you portfolio site</Preview>
    <Tailwind>
        <Body>
            <Container>
                <Section>
                    <Heading>You received the following message from the contact form</Heading>
                    <Text>{contactMessage}</Text>
                    <Hr/>
                    <Text>The sender's email is : {senderEmail}</Text>
                </Section>
            </Container>
        </Body>
    </Tailwind>
   </Html>
    
  );
}

export default ContactFormEmail

其他错误场景

  • 若不给contact-form-email.tsx设置'use client',会触发:

错误由在'./email/contact-form-email.tsx'中导入'@react-email/tailwind/dist/index.mjs'导致。
可能其中一个文件需要标记为客户端入口"use client":
./email/contact-form-email.tsx ./actions/sendEmail.ts

  • 若不给sendEmail.ts设置'use server',会触发:

Error: Missing API key. Pass it to the constructor new Resend("re_123")


解决方法

核心矛盾是旧版@react-email/tailwind不支持服务端渲染,导致邮件模板必须标记为客户端组件,但Server Action需要在服务端调用它。以下两种方案可解决:

方案1:替换Tailwind为原生内联样式

移除@react-email/tailwind依赖,改用组件内置样式属性,让邮件模板无需标记'use client',直接在服务端渲染:

修改后的contact-form-email.tsx:

import React from 'react'
import {
    Html,
    Body,
    Head, 
    Heading,
    Hr,
    Container,
    Preview,
    Section,
    Text
} from '@react-email/components'

type ContactFormEmailProps = {
    contactMessage : string,
    senderEmail : string, 
}

function ContactFormEmail({contactMessage, senderEmail } : ContactFormEmailProps) {
  return (
   <Html>
    <Head/>
    <Preview>New message from your portfolio site</Preview>
        <Body style={{ fontFamily: 'Arial, sans-serif', backgroundColor: '#f4f4f4', padding: '20px' }}>
            <Container style={{ maxWidth: '600px', margin: '0 auto', backgroundColor: '#fff', padding: '30px', borderRadius: '8px' }}>
                <Section>
                    <Heading style={{ fontSize: '24px', color: '#333', marginBottom: '20px' }}>You received the following message from the contact form</Heading>
                    <Text style={{ fontSize: '16px', color: '#555', lineHeight: '1.6', marginBottom: '20px' }}>{contactMessage}</Text>
                    <Hr style={{ border: 'none', borderTop: '1px solid #eee', margin: '20px 0' }}/>
                    <Text style={{ fontSize: '14px', color: '#666' }}>The sender's email is : {senderEmail}</Text>
                </Section>
            </Container>
        </Body>
   </Html>
    
  );
}

export default ContactFormEmail

方案2:升级@react-email/tailwind到兼容服务端的版本

新版@react-email/tailwind已修复服务端渲染问题,升级后可移除邮件模板的'use client'指令:

  1. 升级依赖:
npm install @react-email/tailwind@latest
  1. 修改contact-form-email.tsx,去掉'use client':
import React from 'react'
import {
    Html,
    Body,
    Head, 
    Heading,
    Hr,
    Container,
    Preview,
    Section,
    Text
} from '@react-email/components'
import { Tailwind } from '@react-email/tailwind'

type ContactFormEmailProps = {
    contactMessage : string,
    senderEmail : string, 
}

function ContactFormEmail({contactMessage, senderEmail } : ContactFormEmailProps) {
  return (
   <Html>
    <Head/>
    <Preview>New message from your portfolio site</Preview>
    <Tailwind>
        <Body className="font-sans bg-gray-100 p-5">
            <Container className="max-w-xl mx-auto bg-white p-6 rounded-lg">
                <Section>
                    <Heading className="text-2xl text-gray-800 mb-4">You received the following message from the contact form</Heading>
                    <Text className="text-base text-gray-600 leading-relaxed mb-4">{contactMessage}</Text>
                    <Hr className="border-gray-200 my-4"/>
                    <Text className="text-sm text-gray-500">The sender's email is : {senderEmail}</Text>
                </Section>
            </Container>
        </Body>
    </Tailwind>
   </Html>
    
  );
}

export default ContactFormEmail

两种方案均可让Server Action正常调用邮件模板,同时保留样式效果,解决服务端/客户端组件的冲突问题。

内容的提问来源于stack exchange,提问作者0_0perplexed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:10:13