Use renderToStaticMarkup to send an email in a server action
Unanswered
American black bear posted this in #help-forum
American black bearOP
Hi everyone!
I'm attempting to use
However I'm getting the following error in the backend:
And in VSCode I get red squigly lines and when I hover it says:
The
Any idea how I can fix this, or some other way to send HTML emails in server actions? Thanks!
I'm attempting to use
renderToStaticMarkup
in a server action to send the generated HTML via email.import { renderToStaticMarkup } from "react-dom/server";
import { sendEmail } from "@/infra/email";
import { ResetPasswordEmail } from "@/infra/email/templates";
import { zhrLog } from "@/infra/logging";
import { userRoutes } from "@/routes";
interface SendPasswordResetLink {
email: string;
firstName: string;
passwordResetToken: string;
}
export const sendPasswordResetLink = async ({ email, firstName, passwordResetToken }: SendPasswordResetLink): Promise<void> => {
const url = userRoutes.resetPassword.generateUrl(passwordResetToken);
const subject = `Password reset`;
const html = renderToStaticMarkup(<ResetPasswordEmail firstName={firstName} url={url} />);
const result = await sendEmail({ html, subject, toEmail: email, toName: firstName });
if (result === `error`) {
zhrLog(`Error sending password reset link to ${email}`);
throw new Error();
}
};
However I'm getting the following error in the backend:
Error:
× Expected '>', got 'firstName'
And in VSCode I get red squigly lines and when I hover it says:
'ResetPasswordEmail' refers to a value, but is being used as a type here. Did you mean 'typeof ResetPasswordEmail'?ts(2749)
The
ResetPasswordEmail
component doesn't have any interactivity, and its filename ends in .tsx
.Any idea how I can fix this, or some other way to send HTML emails in server actions? Thanks!
13 Replies
Cause TypeScript thinks you are crafting a generic type
you would need the file to be tsx, because it must be first compiled to normal JS
<ResetPasswordEmail is a shortcut to smth like "ReactDOM.render(...)" (ok it's totally not that but you get the point, it is translated to a function call in JS)
maybe give a shot at just changing the file type
I've tried that in the past (before server actions, in an API route), it wasn't rendering properly but I think it was working
I've tried that in the past (before server actions, in an API route), it wasn't rendering properly but I think it was working
honestly you'd be better of by just creating normal functions, you don't have much benefit from using React components, your email client won't run JavaScript like a browser
American black bearOP
The
renderToStaticMarkup
function will convert the React into normal HTML without any JS. What I like about this is that I can preview the emails I send in an admin page, something like /admin/previews/emails
The ResetPasswordEmail file is already tsx, and I attempted to change
sendPasswordResetLink.ts
to sendPasswordResetLink.tsx
but this didn't fix ityou can still preview if using play JavaScript function
you can shove the result into a div with "dangerouslySetInnerHTML"
you could try jsx too to avoid ts issues
I mean technically you should be able to output something, it's not an approach I recommend but you are right you could make soemthign that compiles
I remember having smth that works with TS but JSX would avoid any issue
American black bearOP
True, I'll give it a try to see what is output