Skip to content

fix(astro): Fix isHTMLString check failing in multi-realm environments#16142

Merged
ematipico merged 13 commits intowithastro:mainfrom
rururux:mdx-escape-issue
Apr 1, 2026
Merged

fix(astro): Fix isHTMLString check failing in multi-realm environments#16142
ematipico merged 13 commits intowithastro:mainfrom
rururux:mdx-escape-issue

Conversation

@rururux
Copy link
Copy Markdown
Contributor

@rururux rururux commented Mar 29, 2026

fixes: #16003

Changes

When using the Astro Container API, passing child elements to a component inside an MDX file could cause those elements to be incorrectly escaped.
This happened because the value instanceof HTMLString check in the isHTMLString function failed to recognize the HTMLString instance correctly.

export function isHTMLString(value: any): value is HTMLString {
return value instanceof HTMLString;
}

renderChild
(if(isHTMLString(child)) does not evaluate to true, so the program proceeds to the next if statement)

Following Erika’s suggestion, I have updated the logic to check for the presence of Symbol.for('astro:html-string') instead of using instanceof HTMLString.

Testing

Added a test to verify that child elements passed to a component inside an MDX file are not incorrectly escaped.

Docs

N/A, bug fix

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

🦋 Changeset detected

Latest commit: e97d963

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

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

@github-actions github-actions bot added pkg: integration Related to any renderer integration (scope) pkg: astro Related to the core `astro` package (scope) labels Mar 29, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 29, 2026

Merging this PR will not alter performance

✅ 18 untouched benchmarks


Comparing rururux:mdx-escape-issue (e97d963) with main (a7e7567)

Open in CodSpeed

@rururux
Copy link
Copy Markdown
Contributor Author

rururux commented Mar 31, 2026

I’ve made a few changes.

  • Following Erika’s suggestion, I’ve changed the method to use Symbol.for(...) for the check instead of Symbol.toStringTag.
  • As a result, Symbol.toStringTag is no longer used in the HTMLString class, so I’ve removed it.
  • I found a check for value instanceof HTMLString in markHTMLString, so I changed it to use isHTMLString instead.
  • I’ve simplified the structure of the test fixture. I’ve confirmed that the test fails as it did with the previous test fixture before the change to the isHTMLString check logic.

@Princesseuh
Copy link
Copy Markdown
Member

Did you get to see if adding virtual: to the server-app module name fixes this without requiring changes to HTMLString?

@rururux
Copy link
Copy Markdown
Contributor Author

rururux commented Mar 31, 2026

I just tested this, and confirmed that even if I change ASTRO_DEV_SERVER_APP_ID to "virtual:astro:server-app", the tests I added this time will not pass unless I apply this PRs change.
I also confirmed that the error with the <Steps> component we discussed on Discord still occurs without this change.

However, regarding the <Steps> component, HMR stopped working properly after this error and the astro:server-app error were resolved, so the issue hasn’t been fully resolved.

@rururux
Copy link
Copy Markdown
Contributor Author

rururux commented Mar 31, 2026

It seems that HMR not working when editing MDX files is by design, my apologies.
So, I think the issue with the <Steps> component can be fixed simply by applying the changes in this PR and updating “virtual:astro:server-app”.

@rururux rururux changed the title fix(container): don't escape slot HTML in renderToString during build fix(astro): Fix isHTMLString check failing in multi-realm environments Mar 31, 2026
@rururux
Copy link
Copy Markdown
Contributor Author

rururux commented Apr 1, 2026

Just to follow up on the HMR mention, by "HMR," I specifically meant changes being applied without a full page reload.
The automatic full reload is still working perfectly fine, so there's no issue with the changes being applied.

'astro': patch
---

Fix HTML escaping in `renderToString` for MDX slots during build
Copy link
Copy Markdown
Member

@ematipico ematipico Apr 1, 2026

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've updated the changeset. does this look good to you?

'astro': patch
---

Fixes HTML content being incorrectly escaped as plain text due to a failed `isHTMLString` check
Copy link
Copy Markdown
Member

@ematipico ematipico Apr 1, 2026

Choose a reason for hiding this comment

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

Suggested change
Fixes HTML content being incorrectly escaped as plain text due to a failed `isHTMLString` check
Fixes HTML content being incorrectly escaped as plain text when rendering a MDX component using the `AstroContainer` APIs.

cc @rururux for future reference

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I appreciate you tidying that up for me. Thanks for the reference!

@ematipico ematipico merged commit 7454854 into withastro:main Apr 1, 2026
12 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Apr 1, 2026
@rururux
Copy link
Copy Markdown
Contributor Author

rururux commented Apr 1, 2026

Thank you! ☺️

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

Labels

pkg: astro Related to the core `astro` package (scope) pkg: integration Related to any renderer integration (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Astro Container API renderToString function has inconsistent HTML escaping behavior between build and dev modes

3 participants