render: unstableTextConversion outputs HTML comments and repeats link URLs in plain text
Los mantenedores suelen responder en 1 día
@lakshya-dhariwal ya está trabajando en esto.
Desde el 6/11/2026.
- #3873 de @lakshya-dhariwal — abierto
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 87/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- react, typescript
Línea de trabajo
Empieza con packages/render/src/shared/utils/unstable-to-plain-text.ts y sigue cómo maneja los comentarios HTML y el texto de los enlaces al convertir la salida renderizada. El issue incluye una reproducción autónoma con render(); ejecútala para ver los fallos y luego añade casos de spec que usen una salida real de render(), como se sugiere. El trabajo está terminado cuando se omitan los comentarios y el texto de los enlaces coincidente y las URL aparezcan solo una vez cada uno.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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:
- React's Suspense markers
<!--$-->and<!--/$-->show up as$and/$at the start and end of every render. <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].- 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
- Lenguaje dominante
- TypeScript
- Estrellas
- 19.9k
- Forks
- 1.1k
- Merge medio
- 1 d 15 h
- PR fusionados (30 d)
- 49
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de resend/react-email
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
resend/react-email#3876 ·
Los mantenedores suelen responder en 1 día
-
<CodeInline> causes duplicated text in body previews in Gmail and other providers due to hacky Orange.fr workaroundPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
resend/react-email#3853 ·
Los mantenedores suelen responder en 1 día
-
Markdown: HTML inside code blocks and inline code isn't escapedPosiblemente ocupada @KishanKanejiya23 la tomó hace 11 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
resend/react-email#3814 ·
Los mantenedores suelen responder en 1 día
-
Tailwind stacked media variants leave nested CSS in rendered emailsPosiblemente ocupada @lakshya-dhariwal la tomó hoy. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
resend/react-email#3874 ·
Los mantenedores suelen responder en 1 día
-
Inspector Text panel omits Uppercase mark toggle (MARK_NAMES missing "uppercase")Posiblemente ocupada @svargas-dev la tomó hace 6 días. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 22/100
resend/react-email#3849 ·
Los mantenedores suelen responder en 1 día
Todos los issues de resend/react-email
Issues similares
-
documentation good first issue roadmap
Dificultad 1/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
siyuan-note/siyuan#21324 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
dmno-dev/varlock#1279 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
himynameisdave/bsky-profanity-counter#59 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100