Describe the Bug
In Astro 5.16.9, React components with mouse event handlers (e.g., onMouseDown, onMouseMove, onMouseUp) stop working when nested inside HTML elements in MDX files. This is a regression introduced by PR #15150.
Steps to Reproduce
In an MDX file:
<div className="wrapper">
<InteractiveComponent
onMouseDown={(e) => console.log('mousedown')}
onMouseMove={(e) => console.log('mousemove')}
client:load
/>
</div>
InteractiveComponent.tsx:
export const InteractiveComponent = ({ onMouseDown, onMouseMove }) => {
return (
<div
onMouseDown={onMouseDown}
onMouseMove={onMouseMove}
>
Drag me
</div>
);
};
Expected Behavior
- ✅ 5.16.8 and earlier: Mouse events work correctly
- ✅ 5.16.6: Mouse events work correctly
Actual Behavior
- ❌ 5.16.9: Mouse events do not fire, component renders static HTML without hydration
Root Cause Analysis
PR #15150 modified the array rendering logic in packages/astro/src/runtime/server/jsx.ts:
Before (5.16.8):
case Array.isArray(vnode):
return markHTMLString(
(await Promise.all(vnode.map((v: any) => renderJSX(result, v)))).join(''),
);
After (5.16.9):
case Array.isArray(vnode): {
const renderedItems = await Promise.all(vnode.map((v: any) => renderJSX(result, v)));
let instructions: RenderInstruction[] | null = null;
let content = '';
for (const item of renderedItems) {
if (item instanceof SlotString) {
content += item;
instructions = mergeSlotInstructions(instructions, item);
} else {
content += item; // ← Components treated as plain strings
}
}
// ...
}
The problem: When React components are nested in HTML elements within MDX, the children array processing now treats non-SlotString items as plain HTML strings, stripping the hydration mechanism (no <astro-island> tags are output).
Workaround
Move the className to the component props instead of wrapping in a div:
<InteractiveComponent
className="wrapper"
onMouseDown={(e) => console.log('mousedown')}
client:load
/>
This avoids the array processing logic that causes the issue.
Impact
- Breaks all React components with event handlers when nested in MDX
- Affects third-party components that cannot be easily modified
- Workaround is not always feasible (semantic HTML structure, layout requirements)
Environment
Suggested Fix
The array rendering logic should preserve hydration for all rendered components, not just SlotString instances. The fix for MDX slots inadvertently broke non-slot scenarios.
Describe the Bug
In Astro 5.16.9, React components with mouse event handlers (e.g.,
onMouseDown,onMouseMove,onMouseUp) stop working when nested inside HTML elements in MDX files. This is a regression introduced by PR #15150.Steps to Reproduce
In an MDX file:
InteractiveComponent.tsx:
Expected Behavior
Actual Behavior
Root Cause Analysis
PR #15150 modified the array rendering logic in
packages/astro/src/runtime/server/jsx.ts:Before (5.16.8):
After (5.16.9):
The problem: When React components are nested in HTML elements within MDX, the children array processing now treats non-
SlotStringitems as plain HTML strings, stripping the hydration mechanism (no<astro-island>tags are output).Workaround
Move the className to the component props instead of wrapping in a div:
This avoids the array processing logic that causes the issue.
Impact
Environment
Suggested Fix
The array rendering logic should preserve hydration for all rendered components, not just
SlotStringinstances. The fix for MDX slots inadvertently broke non-slot scenarios.