render: unstableTextConversion outputs HTML comments and repeats link URLs in plain text

Aperta Adatta ai principianti
#3,864 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@lakshya-dhariwal ci sta già lavorando.

Dal 6/11/2026.

  • #3873 di @lakshya-dhariwal — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
87/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
react, typescript
Ambito
backend, testing

Direzione di ricerca

Inizia da packages/render/src/shared/utils/unstable-to-plain-text.ts e segui come gestisce i commenti HTML e il testo dei link durante la conversione dell’output renderizzato. L’issue include una riproduzione autonoma con render(); eseguila per vedere gli errori, poi aggiungi casi di spec che usino un output reale di render(), come suggerito. Il lavoro è completato quando i commenti vengono omessi e il testo dei link corrispondente e gli URL compaiono una sola volta ciascuno.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

What versions are you using? (if relevant)

@react-email/[email protected], [email protected], [email protected]

Describe the Bug

With unstableTextConversion: true, the plain-text output keeps HTML comments and sometimes repeats link URLs:

  1. React's Suspense markers <!--$--> and <!--/$--> show up as $ and /$ at the start and end of every render.
  2. <Button>'s Outlook conditional comments come out as raw text: [if mso]><i style="mso-font-width:0%;mso-text-raise:0px" hidden></i><![endif].
  3. A link whose text equals its URL repeats the URL (Hi [email protected] [email protected]), unless the link is the first thing in its block. The check that drops the URL when it matches the text seems to pick up the space before the link.

The default converter (toPlainText) doesn't do any of these.

What is affected (leave empty if unsure)

Render Utility

Link to the code that reproduces this issue

Self-contained script below (npm i @react-email/render react-email react react-dom tsx, then npx tsx repro.tsx).

import * as React from 'react';
import { render } from '@react-email/render';
import { Button, Text } from 'react-email';

const opts = { plainText: true, unstableTextConversion: true };

console.log(JSON.stringify(await render(<Text>Hi <a href="mailto:[email protected]">[email protected]</a></Text>, opts)));
console.log(JSON.stringify(await render(<Text><a href="https://a.b">https://a.b</a></Text>, opts)));
console.log(JSON.stringify(await render(<Button href="https://a.b">Go</Button>, opts)));
To Reproduce

Run the script. Output:

"$\n\nHi [email protected] [email protected]\n\n/$"
"$\n\nhttps://a.b\n\n/$"
"$[if mso]><i style=\"mso-font-width:0%;mso-text-raise:0px\" hidden></i><![endif]Go[if mso]><i style=\"mso-font-width:0%\" hidden> </i><![endif] https://a.b/$"
Expected Behavior
"Hi [email protected]"
"https://a.b"
"Go https://a.b"

HTML comments are skipped, and a link whose text matches its URL is printed once wherever it appears. In packages/render/src/shared/utils/unstable-to-plain-text.ts the parser seems to treat <!--...--> as a tag named !--, which isn't in SKIPPED_TAGS. I'm happy to open a PR with spec cases built from real render() output.

What's your node version? (if relevant)

v22.15.0

Lingua principale
TypeScript
Stelle
19.9k
Fork
1.1k
Merge medio
1g 15h
PR unite (30g)
49

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di resend/react-email

Tutte le issue di resend/react-email

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.