render: unstableToPlainText ignores mixed-case HTML attributes

Abierto Apto para principiantes
#3,876 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
node.js, react, typescript
Área
backend

Línea de trabajo

Empieza leyendo el límite de conversión compartido y las búsquedas de href, start y data-skip-in-text; el issue no indica rutas de archivos ni pruebas. Normaliza los nombres de los atributos conservando sus valores y, después, verifica que los atributos con mayúsculas y minúsculas mezcladas se comporten igual que los atributos en minúsculas en enlaces, listas ordenadas y anotaciones de omisión. La tarea está terminada cuando esos casos conservan la URL, la numeración y el texto omitido según lo esperado.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

What versions are you using? (if relevant)

Latest stable @react-email/render 2.2.0 and current canary branch 674d8ec2804b86be5d99156383fb1810179847bf both reproduce, with html5parser 3.0.0 and Node 24.13.0 (also reproduced on 22.16.0).

I also checked the published canary dist-tag, which currently resolves to 2.0.7-canary.0. That version predates unstableToPlainText and has no such export, so this feature-specific test is not applicable there. Its default converter handles the sample inputs correctly.

Describe the Bug

unstableToPlainText recognizes attribute names only when they are lowercase. Valid mixed-case HTML attributes lose their behavior: link URLs disappear from plain text, ordered-list start offsets become 1, and data-skip-in-text is not recognized. The default toPlainText handles these inputs correctly.

What is affected (leave empty if unsure)

Render Utility.

Link to the code that reproduces this issue

Self-contained reproduction below uses the public @react-email/render API; no provider credentials or email delivery are needed.

To Reproduce

Save this as repro.mjs:

import * as renderApi from '@react-email/render';

if (typeof renderApi.unstableToPlainText !== 'function') {
  console.log('unstableToPlainText is not available in this version');
}

const cases = [
  '<a HrEf="https://example.com/pay">Pay invoice</a>',
  '<ol StArT="5"><li>Five</li><li>Six</li></ol>',
  '<span DATA-SKIP-IN-TEXT="true">Preview</span>Body',
];

for (const html of cases) {
  console.log(JSON.stringify(renderApi.toPlainText(html)));
  if (typeof renderApi.unstableToPlainText === 'function') {
    console.log(JSON.stringify(renderApi.unstableToPlainText(html)));
  }
}

Run in a disposable directory:

npm init -y
npm install --save-exact @react-email/[email protected] [email protected] [email protected]
node repro.mjs
npm install --save-exact @react-email/[email protected]
node repro.mjs

Actual pairs on 2.2.0 (the older published canary prints the availability notice and stable results only):

"Pay invoice https://example.com/pay"
"Pay invoice"
" 5. Five\n 6. Six"
" 1. Five\n 2. Six"
"Body"
"PreviewBody"

Lowercasing only the attribute names makes the two converters agree in all three examples. The missing URL also occurs through render() with plainText: true, unstableTextConversion: true when a component includes the same HTML through dangerouslySetInnerHTML. Existing React-comment text in that rendering path is the separate issue #3864, not part of this report.

Expected Behavior

Attribute names are case-insensitive in HTML. These inputs should behave like their lowercase equivalents, preserving the URL, list numbering and skip annotation. Attribute values should keep their existing decoding/case behavior.

The parser preserves attribute names in its attributeMap, while the converter looks up only href, start and data-skip-in-text. Normalizing attribute names at the shared conversion boundary appears sufficient; no table-separator or default-converter change is needed. Attribute values should not be lowercased.

What's your node version? (if relevant)

24.13.0; also reproduced on 22.16.0.

Prepared with Codex using GPT-6.1 Sol at high reasoning.

Lenguaje dominante
TypeScript
Estrellas
19.9k
Forks
1.1k
Merge medio
1 d 15 h
PR fusionados (30 d)
49

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de resend/react-email

Todos los issues de resend/react-email

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.