Skip to content

Commit f6ee7ba

Browse files
dielduarteclaude
andcommitted
test(preview): guard padding against characters spam filters count as hidden text
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 5dc5bda commit f6ee7ba

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

‎.changeset/quiet-marks-hide.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'react-email': patch
33
---
44

5-
Leave the direction marks U+200E and U+200F out of the `<Preview>` padding, so spam filters such as rspamd no longer score it as hidden text.
5+
Leave the direction marks U+200E and U+200F out of the `<Preview>` padding, so spam filters such as rspamd no longer score it as hidden text. The padding sequence is now `\xa0‌​‍`; if you post-process rendered HTML by matching the old sequence, update it.

‎packages/react-email/src/components/preview/preview.spec.tsx‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ describe('<Preview> component', () => {
1818
);
1919
});
2020

21+
it('pads only with characters spam filters ignore as preview padding', async () => {
22+
const actualOutput = await render(<Preview>Short text</Preview>);
23+
const padding = actualOutput.match(/<div>([^<]*)<\/div>/)?.[1];
24+
25+
// rspamd's HIDDEN_TEXT rule counts any other hidden character, so padding
26+
// made of anything else gets scored as hidden text
27+
expect(padding).toMatch(/^[\s\p{Z}​-‍]+$/u);
28+
});
29+
2130
it('renders correctly with really long text', async () => {
2231
const longText = 'really long'.repeat(100);
2332
const actualOutputLong = await render(<Preview>{longText}</Preview>);

0 commit comments

Comments
 (0)