Skip to content

fix(html): decode character references in static attribute values - #4258

Merged
ryansolid merged 1 commit into
solidjs:nextfrom
NgoQuocViet2001:fix-html-attribute-entities
Oct 25, 2026
Merged

ryansolid merged 1 commit into
solidjs:nextfrom
NgoQuocViet2001:fix-html-attribute-entities

Conversation

@NgoQuocViet2001

Copy link
Copy Markdown

Summary

Static attribute strings in html templates reach setAttribute and component props without entity decoding. For example:

  • html<input placeholder="Search&hellip;" /> shows Search&hellip;.
  • <a href="/search?q=1&amp;page=2"> links to ?q=1&amp;page=2.
  • <${Comp} title="a &amp; b" /> passes "a &amp; b".

Text children in the same template are already decoded, plain HTML decodes these, and the 1.x html runtime decoded element attributes. Compiled JSX also decodes static attribute strings (see #1553, #3127).

This decodes each static prop once, when the template is built, using the HTML parser's quoted-attribute rules, so &region= in a URL stays as written. It applies to attributes baked into the template, props after a spread, and component props.

How did you test this change?

  • Added a test in packages/html/test/tagged-jsx.test.ts. On next it fails with Received: "/search?q=1&amp;page=2&region=eu", and it passes with the fix.
  • pnpm exec vitest run in packages/html: 4 files, 209 tests pass.
  • tsc --project ./tsconfig.json --noEmit in packages/html and prettier --check on the changed files: clean.

Static attribute strings went from the tokenizer to setAttribute and to
component props as raw text, so `placeholder="Search&hellip;"` showed
`&hellip;` and an href with `&amp;` kept it in the URL. Text children
were already decoded.

Decode each static prop once, when the template is built, with the HTML
parser's quoted-attribute rules, so `&region=` in a URL is left alone.
@changeset-bot

changeset-bot Bot commented Oct 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6e73f29

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

This PR includes changesets to release 15 packages
Name Type
@solidjs/html Patch
test-integration Patch
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/signals Patch
solid-js Patch
@solidjs/universal Patch
@solidjs/web Patch
board-example Patch
canvas-example Patch
server-dbmon-example Patch
todos-server-example 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

@codspeed

codspeed Bot commented Oct 25, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 13.37%

2 warnings

⚠️ 3 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 195 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ memo + sync render effect only (reference) 29.6 ms 34.1 ms -13.37%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing NgoQuocViet2001:fix-html-attribute-entities (6e73f29) with next (2a0da2f)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@ryansolid
ryansolid merged commit 916e0eb into solidjs:next Oct 25, 2026
7 of 8 checks passed
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.

2 participants