mirror of
https://github.com/resend/react-email.git
synced 2026-09-14 14:18:02 +08:00
fix(render): prevent react hydration markers on large emails (#2383)
Co-authored-by: Gabriel Miranda <gabrielmfern@outlook.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@react-email/render": patch
|
||||
---
|
||||
|
||||
fix hydration markers on React canary/Next.js latest when rendering large email templates
|
||||
File diff suppressed because one or more lines are too long
@@ -146,4 +146,36 @@ describe('render on the browser environment', () => {
|
||||
const element = createElement(undefined);
|
||||
await expect(render(element)).rejects.toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a large email that would trigger React's streaming optimization
|
||||
* if progressiveChunkSize wasn't set to Infinity
|
||||
*
|
||||
* @see https://github.com/resend/react-email/issues/2353
|
||||
*/
|
||||
it('should render large emails without hydration markers', async () => {
|
||||
const LargeEmailTemplate = () => {
|
||||
const largeContent = Array(100)
|
||||
.fill(null)
|
||||
.map((_, i) => (
|
||||
<p key={i}>
|
||||
This is paragraph {i} with some content to make the email larger.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
|
||||
ad minim veniam, quis nostrud exercitation ullamco laboris.
|
||||
</p>
|
||||
));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Large Email Test</h1>
|
||||
{largeContent}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const actualOutput = await render(<LargeEmailTemplate />);
|
||||
|
||||
expect(actualOutput).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +51,7 @@ export const render = async (node: React.ReactNode, options?: Options) => {
|
||||
onError(error: unknown) {
|
||||
reject(error);
|
||||
},
|
||||
progressiveChunkSize: Number.POSITIVE_INFINITY,
|
||||
})
|
||||
.then(readStream)
|
||||
.then(resolve)
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -107,4 +107,36 @@ describe('render on the edge', () => {
|
||||
`"THIS SHOULD BE RENDERED IN PLAIN TEXT"`,
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a large email that would trigger React's streaming optimization
|
||||
* if progressiveChunkSize wasn't set to Infinity
|
||||
*
|
||||
* @see https://github.com/resend/react-email/issues/2353
|
||||
*/
|
||||
it('should render large emails without hydration markers', async () => {
|
||||
const LargeEmailTemplate = () => {
|
||||
const largeContent = Array(100)
|
||||
.fill(null)
|
||||
.map((_, i) => (
|
||||
<p key={i}>
|
||||
This is paragraph {i} with some content to make the email larger.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
|
||||
ad minim veniam, quis nostrud exercitation ullamco laboris.
|
||||
</p>
|
||||
));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Large Email Test</h1>
|
||||
{largeContent}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const actualOutput = await render(<LargeEmailTemplate />);
|
||||
|
||||
expect(actualOutput).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -133,4 +133,36 @@ describe('render on node environments', () => {
|
||||
`"THIS SHOULD BE RENDERED IN PLAIN TEXT"`,
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a large email that would trigger React's streaming optimization
|
||||
* if progressiveChunkSize wasn't set to Infinity
|
||||
*
|
||||
* @see https://github.com/resend/react-email/issues/2353
|
||||
*/
|
||||
it('should render large emails without hydration markers', async () => {
|
||||
const LargeEmailTemplate = () => {
|
||||
const largeContent = Array(100)
|
||||
.fill(null)
|
||||
.map((_, i) => (
|
||||
<p key={i}>
|
||||
This is paragraph {i} with some content to make the email larger.
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
|
||||
ad minim veniam, quis nostrud exercitation ullamco laboris.
|
||||
</p>
|
||||
));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Large Email Test</h1>
|
||||
{largeContent}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const actualOutput = await render(<LargeEmailTemplate />);
|
||||
|
||||
expect(actualOutput).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,9 @@ export const render = async (node: React.ReactNode, options?: Options) => {
|
||||
let html!: string;
|
||||
if (Object.hasOwn(reactDOMServer, 'renderToReadableStream')) {
|
||||
html = await readStream(
|
||||
await reactDOMServer.renderToReadableStream(suspendedElement),
|
||||
await reactDOMServer.renderToReadableStream(suspendedElement, {
|
||||
progressiveChunkSize: Number.POSITIVE_INFINITY,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -27,6 +29,7 @@ export const render = async (node: React.ReactNode, options?: Options) => {
|
||||
onError(error) {
|
||||
reject(error as Error);
|
||||
},
|
||||
progressiveChunkSize: Number.POSITIVE_INFINITY,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user