#5726·base-ui

[combobox] Disabled Trigger omits native disabled during SSR and causes a hydration mismatch

Author: LeonHellqvistCreated Sep 15, 2026Updated Sep 15, 2026
Labelsstatus: waiting for maintainercomponent: combobox

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:

xml
<button type="button" data-disabled="">Open</button>

while the first client render expects:

xml
<button type="button" data-disabled="" disabled>Open</button>

React reports:

diff
<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:

typescript
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.25

I confirmed that the logical state is the same during SSR and the first client render:

SSR:
disabled = true

First client render:
disabled = true

I also tested the following:

  • Passing disabled directly to Combobox.Root
  • Passing disabled to both Combobox.Root and Combobox.Trigger
  • Removing the custom render prop
  • 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?