[combobox] Disabled Trigger omits native disabled during SSR and causes a hydration mismatch
Bug report
Current behavior
A disabled Combobox.Trigger produces different native button attributes during SSR and hydration.
The component receives disabled={true} during both SSR and the first client render. However, the server HTML contains:
<button type="button" data-disabled="">Open</button>while the first client render expects:
<button type="button" data-disabled="" disabled>Open</button>React reports:
<button
type="button"
data-disabled=""
+ disabled={true}
- disabled={null}
>The full warning is:
A tree hydrated but some attributes of the server rendered HTML
didn't match the client properties. This won't be patched up.Expected behavior
When disabled={true}, Combobox.Trigger should produce the same native disabled attribute during SSR and the first client render.
Hydrating the component should not produce a warning.
Reproducible example
This is the minimal component that reproduces the problem in my TanStack Start SSR application:
import { Combobox } from "@base-ui/react/combobox";
export function Example() {
return (
<Combobox.Root disabled>
<Combobox.Trigger>Open</Combobox.Trigger>
</Combobox.Root>
);
}I do not currently have a hosted reproduction, but I can create one if the issue cannot be reproduced from this example.
Base UI version
v1.8.0
Which browser are you using?
Chrome
Which OS are you using?
Linux
Which assistive tech are you using (if applicable)?
This was created with the help of Microsoft Copilot (GPT 5.6 Think deeper)
Additional context
Relevant versions:
react: 19.2.5
react-dom: 19.2.5
@base-ui/react: 1.8.0
@tanstack/react-start: 1.168.25I confirmed that the logical state is the same during SSR and the first client render:
SSR:
disabled = true
First client render:
disabled = trueI also tested the following:
- Passing
disableddirectly toCombobox.Root - Passing
disabledto bothCombobox.RootandCombobox.Trigger - Removing the custom
renderprop - Rendering the native Base UI trigger directly
- Removing all items, values, controlled state, and API-query logic
The same mismatch still occurs with the minimal Combobox.
The Base UI state attribute data-disabled="" is present in both cases. Only the native disabled attribute differs.
Could this be an SSR issue in Combobox.Trigger or Base UI's internal native-button handling?
Source: mui/base-ui