fix(core): allow invalid harmless tag nesting#8809
Conversation
🦋 Changeset detectedLatest commit: c1ce97d The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
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 |
@qwik.dev/core
@qwik.dev/router
eslint-plugin-qwik
create-qwik
@qwik.dev/optimizer
@qwik.dev/devtools
commit: |
There was a problem hiding this comment.
Pull request overview
This PR adjusts Qwik SSR’s HTML tag nesting enforcement to be lenient for authoring-invalid markup that browsers keep unchanged during parsing, warning in dev instead of throwing when it is safe to continue.
Changes:
- Adds a “parser-retained invalid nesting” classification (
isRetainedWhenInvalid,closesPTag) to distinguish harmless invalid markup from cases that would be rewritten by the HTML parser. - Updates SSR container nesting validation to warn (once per parent>child combo per render) and proceed for parser-retained invalid nesting.
- Extends unit/spec coverage for textarea text-only content and the new leniency behavior, and adds a changeset for
@qwik.dev/core.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/qwik/src/server/tag-nesting.unit.ts | Adds tests for textarea text-only content and leniency classification helpers. |
| packages/qwik/src/server/tag-nesting.ts | Adds parser-leniency helpers and adjusts textarea nesting state. |
| packages/qwik/src/server/ssr-container.ts | Warns (dev) and continues SSR for parser-retained invalid nesting; adds scope checks to keep throwing when DOM would be rewritten. |
| packages/qwik/src/server/ssr-container.spec.ts | Adds SSR regression tests to confirm warn-once behavior and continued throwing for DOM-rewriting cases. |
| .changeset/lenient-tag-nesting.md | Publishes the behavior change as a patch changeset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case 'div': | ||
| case 'dl': | ||
| case 'fieldset': |
| case 'menu': | ||
| case 'nav': | ||
| case 'ol': | ||
| case 'p': |
| case 'button': | ||
| return TagNesting.BUTTON; | ||
| case 'input': | ||
| case 'textarea': | ||
| return TagNesting.PHRASING_INSIDE_INPUT; | ||
| case 'picture': | ||
| return TagNesting.PICTURE; |
| case 'style': | ||
| case 'noscript': | ||
| case 'noframes': | ||
| case 'textarea': // rawtext element; element children would be parsed as text |
| '@qwik.dev/core': patch | ||
| --- | ||
|
|
||
| fix: ssr does not throw for invalid html nesting that browsers keep as-is, but only warns |
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
Varixo
left a comment
There was a problem hiding this comment.
Even if all the browser around behave here the same the implementation is wrong imo. You just need to remove these tags from config
|
@Varixo you mean, don't even warn for invalid-spec but valid-parsing HTML? |
We should only refuse DOM structures that change when the browser parses the HTML.
<div>inside<button>is retained by the browser.