Skip to content

fix: replace HTML_LOWER_CASE regex with Set to prevent false matches …#452

Open
baspinarenes wants to merge 4 commits intopreactjs:mainfrom
baspinarenes:fix/html-lower-case-set
Open

fix: replace HTML_LOWER_CASE regex with Set to prevent false matches …#452
baspinarenes wants to merge 4 commits intopreactjs:mainfrom
baspinarenes:fix/html-lower-case-set

Conversation

@baspinarenes
Copy link

@baspinarenes baspinarenes commented Mar 11, 2026

Fixes #451

Summary

  • Replace HTML_LOWER_CASE regex with an explicit Set of known camelCase HTML attribute names
  • Update .test() calls to .has() in both src/index.js and src/pretty.js

Problem

The regex ^(?:accessK|auto[A-Z]|cell|ch|col|...) uses broad prefixes that can falsely match custom element properties. For example, channelId matches the ch prefix (intended for charSet) and gets incorrectly lowercased to channelid.

Solution

Replace the regex with an explicit Set so only known HTML attributes are lowercased. Custom element properties are no longer affected.

@changeset-bot
Copy link

changeset-bot bot commented Mar 11, 2026

🦋 Changeset detected

Latest commit: 04e12ea

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
preact-render-to-string Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

…on custom elements

The regex could incorrectly match custom element properties (e.g. channelId
matching the `ch` prefix, resulting in `channelid`). Using an explicit Set
ensures only known HTML attributes are lowercased.

Fixes preactjs#451
@baspinarenes baspinarenes force-pushed the fix/html-lower-case-set branch from 2de1537 to cff3239 Compare March 11, 2026 10:10
src/pretty.js Outdated
: name.replace(/([A-Z])/g, '-$1').toLowerCase();
}
} else if (HTML_LOWER_CASE.test(name)) {
} else if (HTML_LOWER_CASE.has(name)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we instead check whether this is a custom-element by doing isCustomElement && .test to avoid breakages because of forgetting properties in the Set

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though, I supposed it'd also be a breaking change if a custom element used any of the aforementioned properties, expecting them to be serialized as HTML attrs.

I don't have any immediate answer, just thinking out loud

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the feedbacks. i refactored it to work specifically with the native element 🙏

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeping static sets seems like the safest method. it also seems like we can't do it through a property that only exists in native elements. i'm open to different ideas 🙏

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You did the inverse, we mainly want to align the logic. I.e. keep the regex and check whether or not you are dealing with a custom element.

Ref: https://github.com/preactjs/preact/blob/main/compat/src/render.js#L129

Copy link
Author

@baspinarenes baspinarenes Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a microfrontend framework in our company, and here we store pages as JSX. we use a custom fragment named <Fragment to retrieve microfrontend components. we also render this JSX file as HTML (ssr render output) using preact-render-to-string (<Fragment -> <fragment). that's what I meant by custom element. when we check with a hyphen, we end up ignoring these cases. do you think the package should consider these cases?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw thanks for the guidance. this is my first open source contribution 😄

Copy link
Member

@rschristian rschristian Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's what I meant by custom element

It sounds like you're actually referring to a component, going by the casing. Custom elements are something fairly different and must always have a hyphen in their names.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, no, we should not support non-standard html tags that aren't custom elements. I would not merge that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML_LOWER_CASE regex incorrectly lowercases custom element properties

3 participants