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

Next.js集成react-email遇导入错误:renderToReadableStream未导出

Next.js注册功能中React-Email导入错误问题

错误信息

点击注册提交按钮时触发以下导入错误:

Import trace for requested module:
./node_modules/@react-email/components/node_modules/@react-email/render/dist/index.mjs
./node_modules/@react-email/components/dist/index.mjs
./emails/VerificationEmail.tsx
./src/helpers/sendVerificationEmail.ts
./src/app/api/sign-up/route.ts
⨯ ./node_modules/@react-email/components/node_modules/@react-email/render/dist/index.mjs
Attempted import error: 'renderToReadableStream' is not exported from 'react-dom/server' (imported as 'renderToReadableStream').

相关代码

VerificationEmail.tsx(React-Email组件代码)

import {
    Html,
    Head,
    Font,
    Preview,
    Heading,
    Row,
    Section,
    Text,
} from '@react-email/components';

interface VerificationEmailProps {
    username: string;
    otp: string;
}

export default function VerificationEmail({ username, otp }: VerificationEmailProps) {
    return (
        <Html lang="en" dir="ltr">
            <Head>
                <title>Verification Code</title>
                <Font
                    fontFamily="Roboto"
                    fallbackFontFamily="Verdana"
                    webFont={{
                        url: 'https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2',
                        format: 'woff2',
                    }}
                    fontWeight={400}
                    fontStyle="normal"
                />
            </Head>
            <Preview>Here&apos;s your verification code: {otp}</Preview>
            <Section>
                <Row>
                    <Heading as="h2">Hello {username},</Heading>
                </Row>
                <Row>
                    <Text>
                        Thank you for registering. Please use the following verification
                        code to complete your registration:
                    </Text>
                </Row>
                <Row>
                    <Text>{otp}</Text>
                </Row>
                <Row>
                    <Text>
                        If you did not request this code, please ignore this email.
                    </Text>
                </Row>
                {/* <Row>
            <Button
              href={`http://localhost:3000/verify/${username}`}
              style={{ color: '#61dafb' }}
            >
              Verify here
            </Button>
          </Row> */}
            </Section>
        </Html>
    );
}

注册API路由代码(src/app/api/sign-up/route.ts)

import dbConnect from '@/lib/dbConnect';
import UserModel from '@/model/User';
import bcrypt from 'bcryptjs';
import { sendVerificationEmail } from '@/helpers/sendVerificationEmail';

export async function POST(request: Request) {
  await dbConnect();

  try {
    const { username, email, password } = await request.json();

    const existingVerifiedUserByUsername = await UserModel.findOne({
      username,
      isVerified: true,
    });

    if (existingVerifiedUserByUsername) {
      return Response.json(
        {
          success: false,
          message: 'Username is already taken',
        },
        { status: 400 }
      );
    }

    const existingUserByEmail = await UserModel.findOne({ email });
    const verifyCode = Math.floor(100000 + Math.random() * 900000).toString();

    if (existingUserByEmail) {
      if (existingUserByEmail.isVerified) {
        return Response.json(
          {
            success: false,
            message: 'User already exists with this email',
          },
          { status: 400 }
        );
      } else {
        const hashedPassword = await bcrypt.hash(password, 10);
        existingUserByEmail.password = hashedPassword;
        existingUserByEmail.verifyCode = verifyCode;
        existingUserByEmail.verifyCodeExpiry = new Date(Date.now() + 3600000);
        await existingUserByEmail.save();
      }
    } else {
      const hashedPassword = await bcrypt.hash(password, 10);
      const expiryDate = new Date();
      expiryDate.setHours(expiryDate.getHours() + 1);

      const newUser = new UserModel({
        username,
        email,
        password: hashedPassword,
        verifyCode,
        verifyCodeExpiry: expiryDate,
        isVerified: false,
        isAcceptingMessages: true,
        messages: [],
      });

      await newUser.save();
    }

    // Send verification email
    const emailResponse = await sendVerificationEmail(
      email,
      username,
      verifyCode
    );
    if (!emailResponse.success) {
      return Response.json(
        {
          success: false,
          message: emailResponse.message,
        },
        { status: 500 }
      );
    }

    return Response.json(
      {
        success: true,
        message: 'User registered successfully. Please verify your account.',
      },
      { status: 201 }
    );
  } catch (error) {
    console.error('Error registering user:', error);
    return Response.json(
      {
        success: false,
        message: 'Error registering user',
      },
      { status: 500 }
    );
  }
}

依赖版本

{
  "@react-email/components": "0.0.7",
  "@react-email/render": "^1.0.3",
  "react-email": "^3.0.4",
  "react-dom": "^19.0.0",
  "react": "^19.0.0"
}

已尝试操作

  • 更新所有依赖到最新版本,问题仍未解决

预期结果

提交注册信息后,页面跳转到用户对应的页面


解决方案

问题原因

  1. 依赖版本冲突:@react-email/components@0.0.7是老旧版本,内部自带的@react-email/render版本与你单独安装的@react-email/render@1.0.3不一致,导致嵌套依赖引发导出错误。
  2. React版本适配问题:React 19目前为预览版,react-email系列工具尚未完全适配,renderToReadableStream的导出逻辑在React 19中存在变动,旧版react-email包仍按React 18规则导入。

修复步骤

  1. 统一更新react-email相关依赖
    先卸载所有相关包避免冲突:

    npm uninstall @react-email/components @react-email/render react-email
    

    重新安装最新稳定版:

    npm install @react-email/components @react-email/render react-email
    
  2. 降级React到稳定版(推荐)
    React 19未正式发布,生态适配不完善,暂时降级到React 18稳定版:

    npm install react@^18.2.0 react-dom@^18.2.0
    
  3. 清理缓存并重启服务
    删除依赖缓存和锁文件,避免残留问题:

    rm -rf node_modules package-lock.json
    npm install
    npm run dev
    
  4. 检查邮件渲染逻辑
    确保sendVerificationEmail使用正确的渲染方式,示例:

    import { render } from '@react-email/render';
    import VerificationEmail from '../../emails/VerificationEmail';
    
    export async function sendVerificationEmail(email: string, username: string, otp: string) {
      const emailContent = render(<VerificationEmail username={username} otp={otp} />);
      // 添加发送邮件逻辑(如Nodemailer)
      return { success: true, message: '邮件发送成功' };
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:09:55