render: unstableToPlainText ignores mixed-case HTML attributes

Đang mở Phù hợp với người mới
#3,876 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Lĩnh vực
backend

Hướng nghiên cứu

Bắt đầu bằng cách đọc ranh giới chuyển đổi dùng chung và các chỗ tra cứu href, start và data-skip-in-text; issue không nêu đường dẫn tệp hay bài kiểm thử. Chuẩn hóa tên thuộc tính nhưng giữ nguyên giá trị của chúng, sau đó xác minh rằng các thuộc tính có chữ hoa và chữ thường xen kẽ hoạt động giống như thuộc tính viết thường đối với liên kết, danh sách có thứ tự và chú thích bỏ qua. Hoàn tất khi các trường hợp đó giữ nguyên URL, số thứ tự và văn bản bị bỏ qua như mong đợi.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
TypeScript
Star
19.9k
Fork
1.1k
Merge trung bình
1 ngày 15 giờ
Pull request đã merge (30 ngày)
49

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của resend/react-email

Tất cả issue của resend/react-email

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.