render: unstableToPlainText ignores mixed-case HTML attributes

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

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

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

Direzione di ricerca

Inizia leggendo il confine di conversione condiviso e le ricerche di href, start e data-skip-in-text; l’issue non indica percorsi di file né test. Normalizza i nomi degli attributi preservandone i valori, quindi verifica che gli attributi con maiuscole e minuscole miste si comportino come quelli in minuscolo per link, elenchi ordinati e annotazioni di esclusione. Il lavoro è completato quando questi casi preservano l’URL, la numerazione e il testo escluso come previsto.

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

Descrizione

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.

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.