I’m attempting to use renderToStaticMarkup
in a NextJS 13 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 { 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 });
//... more code
};
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!
2
Answers
the error may be caused by nodejs not recognizing JSX syntax. try use React.createElement instead.
suggestion:
Since you’re using NextJS for SSR, maybe it’s better to let NextJS handle the rendering, then you can make request to NextJS server to get the rendered HTML and send it by email.
The error you’re seeing is likely due to a TypeScript type error.
When you use the
<ResetPasswordEmail>
component in therenderToStaticMarkup
function, TypeScript is treating it as a value instead of a type.to fix this error, you can try importing the
ResetPasswordEmail
component as a type using the typeof keyword.Here’s an example:
this example, used the typeof keyword to import the
ResetPasswordEmail
component as a type. also passed thefirstName
andurl
props directly to the component using object shorthand notation.and you can also try using the
renderToString
function instead ofrenderToStaticMarkup
.renderToString
is a server-side rendering function that is designed to work with Next.js.here’s is:
in this example, used the
renderToString
function to render theResetPasswordEmail
component to a string. also passed thefirstName
andurl
props directly to the component using object shorthand notation.