The Untraceable
The Untraceable2mo ago

Resend with React Email

Is it possible to send emails with react email components via Resends Convex Componentm?
10 Replies
Convex Bot
Convex Bot2mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
The Untraceable
The UntraceableOP2mo ago
[Request ID: 63177c5019f47b1b] Server Error
Uncaught TypeError: n.renderToReadableStream is not a function
at u (../node_modules/@react-email/render/dist/edge/index.mjs:177:6)
at <anonymous> (../node_modules/@react-email/render/dist/edge/index.mjs:176:19)
at fulfilled (../node_modules/@react-email/render/dist/edge/index.mjs:24:6)
[Request ID: 63177c5019f47b1b] Server Error
Uncaught TypeError: n.renderToReadableStream is not a function
at u (../node_modules/@react-email/render/dist/edge/index.mjs:177:6)
at <anonymous> (../node_modules/@react-email/render/dist/edge/index.mjs:176:19)
at fulfilled (../node_modules/@react-email/render/dist/edge/index.mjs:24:6)
"use node";

import { Resend } from "@convex-dev/resend";
import { pretty, render } from "@react-email/render";
import { v } from "convex/values";
import LinkEmail from "../emails/link-email";
import { components } from "./_generated/api";
import { action } from "./_generated/server";

export const resend: Resend = new Resend(components.resend, {
testMode: false,
});

export const sendInviteEmail = action({
args: {
to: v.array(v.string()),
from: v.string(),
inviteId: v.id("invites"),
fileName: v.string(),
},
handler: async (ctx, { to, from, inviteId, fileName }) => {
for (const email of to) {
if (!email) {
throw new Error("Email is required");
}
await resend.sendEmail(ctx, {
from: "no-reply@storage.untraceable.dev",
to: email,
subject: "You've been invited to view a file",
html: await pretty(
await render(
<LinkEmail
fileName={fileName}
from={from}
inviteId={inviteId}
/>
)
),
});
}
},
});
"use node";

import { Resend } from "@convex-dev/resend";
import { pretty, render } from "@react-email/render";
import { v } from "convex/values";
import LinkEmail from "../emails/link-email";
import { components } from "./_generated/api";
import { action } from "./_generated/server";

export const resend: Resend = new Resend(components.resend, {
testMode: false,
});

export const sendInviteEmail = action({
args: {
to: v.array(v.string()),
from: v.string(),
inviteId: v.id("invites"),
fileName: v.string(),
},
handler: async (ctx, { to, from, inviteId, fileName }) => {
for (const email of to) {
if (!email) {
throw new Error("Email is required");
}
await resend.sendEmail(ctx, {
from: "no-reply@storage.untraceable.dev",
to: email,
subject: "You've been invited to view a file",
html: await pretty(
await render(
<LinkEmail
fileName={fileName}
from={from}
inviteId={inviteId}
/>
)
),
});
}
},
});
erquhart
erquhart2mo ago
Update @react-email/render to latest
The Untraceable
The UntraceableOP2mo ago
Still get the same error on v1.3.1
erquhart
erquhart2mo ago
Surprising, maybe node still needs polyfills depending on node version - but you don't actually need node for this, it's fully supported in the Convex runtime.
The Untraceable
The UntraceableOP2mo ago
In the mean time I just fixed it by manually pasting the HTML after "compiling" the JSX email component and passing that directly as a template literal
Shridhar
Shridhar2mo ago
I'm not able to get react-email to work either
erquhart
erquhart2mo ago
If someone can share a repro I can take a look - it definitely works out of the box at this point.
Robby
Robby3w ago
adding import React from "react"; in where i have my action that has the render email worked for me. React 19 as well
metiuzucc
metiuzucc3w ago
I'm sending now all my react emails from the client, but this is not ideal. So importing react can make possible rendering and sending emails from the backend? Confirming here that i renamed my convex file to .tsx (the file which contains all my resend component send email actions) and it works out of the box importing the react components from react-email and the pretty/render functions. Updated @react-email/render to latest and NOT using "use node". Basically I created an "emails.tsx" file on my convex folder that has all the actions for sendings (sendUserWelcomeEmail, sendUserNotificationEmail) and then I call these actions with the scheduler from my mutations across the app. Also importing React is not required for me

Did you find this page helpful?