|
4 | 4 |
|
5 | 5 | import "../app/functions/server/notInClientComponent"; |
6 | 6 | import mjml2html from "mjml"; |
7 | | -import { Transform } from "node:stream"; |
8 | 7 | import { ReactNode } from "react"; |
9 | 8 |
|
10 | 9 | export async function renderEmail(emailTemplate: ReactNode): Promise<string> { |
11 | | - return mjml2html(await renderToString(emailTemplate), { |
12 | | - validationLevel: "strict", |
13 | | - beautify: false, |
14 | | - minify: false, |
15 | | - ignoreIncludes: true, |
16 | | - }).html; |
17 | | -} |
18 | | - |
19 | | -async function renderToString(node: ReactNode): Promise<string> { |
20 | 10 | // Importing react-dom/server dynamically here is a workaround for the following error: |
21 | 11 | // |
22 | 12 | // Error: react-dom/server is not supported in React Server Components. |
23 | 13 | // |
24 | 14 | // https://github.com/vercel/next.js/issues/43810#issuecomment-2437931415 |
25 | | - const { renderToPipeableStream } = await import("react-dom/server"); |
26 | | - // It looks like we can't use `renderToStaticMarkup`, as that results in the following error: |
27 | | - // |
28 | | - // Internal Error: do not use legacy react-dom/server APIs. If you encountered this error, please open an issue on the Next.js repo. |
29 | | - // |
30 | | - // Hence this `renderToPipeableStream` mess. |
31 | | - const { pipe } = renderToPipeableStream(node); |
32 | | - return new Promise((resolve, reject) => { |
33 | | - const parts: string[] = []; |
34 | | - // It's not clear to me if there's a better to `pipe` a rendered `node` to a string, |
35 | | - // but this works and at this point I'm fed up, so leaving it at this. |
36 | | - // Feel free to replace by a better way. |
37 | | - const transformer = new Transform({ |
38 | | - transform: (chunk, encoding, callback) => { |
39 | | - callback(null, chunk.toString()); |
40 | | - }, |
41 | | - }); |
42 | | - transformer.on("data", (part) => parts.push(part)); |
43 | | - transformer.on("error", reject); |
44 | | - transformer.on("end", () => { |
45 | | - return resolve(parts.join("")); |
46 | | - }); |
47 | | - pipe(transformer); |
48 | | - }); |
| 15 | + const { renderToStaticMarkup } = await import("react-dom/server"); |
| 16 | + return mjml2html(renderToStaticMarkup(emailTemplate), { |
| 17 | + validationLevel: "strict", |
| 18 | + beautify: false, |
| 19 | + minify: false, |
| 20 | + ignoreIncludes: true, |
| 21 | + }).html; |
49 | 22 | } |
0 commit comments