Skip to content

Commit 035549a

Browse files
committed
fixup! fixup! Upgrade to Next.js@15 and React@19
1 parent 7ac7a66 commit 035549a

File tree

2 files changed

+23
-34
lines changed

2 files changed

+23
-34
lines changed

jest.setup.ts

+16
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ global.IntersectionObserver = jest.fn();
4040
defaultFallbackInView(false);
4141
beforeEach(() => {
4242
setupIntersectionMocking(jest.fn);
43+
44+
// react-dom/server.edge is apparently needed instead of react-dom/server
45+
// to avoid this error:
46+
// > Uncaught ReferenceError: MessageChannel is not defined
47+
// See https://github.com/jsdom/jsdom/issues/2448#issuecomment-1581009331
48+
window.MessageChannel = jest.fn().mockImplementation(() => {
49+
return {
50+
port1: {
51+
postMessage: jest.fn(),
52+
},
53+
port2: {
54+
addEventListener: jest.fn(),
55+
removeEventListener: jest.fn(),
56+
},
57+
};
58+
});
4359
});
4460
afterEach(() => {
4561
resetIntersectionMocking();

src/emails/renderEmail.ts

+7-34
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,19 @@
44

55
import "../app/functions/server/notInClientComponent";
66
import mjml2html from "mjml";
7-
import { Transform } from "node:stream";
87
import { ReactNode } from "react";
98

109
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> {
2010
// Importing react-dom/server dynamically here is a workaround for the following error:
2111
//
2212
// Error: react-dom/server is not supported in React Server Components.
2313
//
2414
// 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;
4922
}

0 commit comments

Comments
 (0)