Fix template theme hydration - #876
Draft
zahlekhan wants to merge 2 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
useSyncExternalStorewith a deterministic server snapshot in the OpenUI Cloud template and exampleAgentInterfaceopenui-chatexample with the template behaviorRoot cause
The theme hook used a lazy
useStateinitializer that returnedlightduring server rendering but readprefers-color-schemeduring the browser's first render. For users in dark mode, React hydrated light server markup with dark client properties, including a different logo URL, and reported an unrecoverable attribute mismatch.useSyncExternalStorenow supplieslightas React's server and hydration snapshot, then switches to the live media-query snapshot after hydration and continues subscribing to system-theme changes.Impact
Cloud and self-hosted apps generated by the CLI now hydrate deterministically while retaining responsive system light/dark mode behavior. The checked-in Cloud and OSS examples use the same implementation.
Validation
npm test(3 passed)npm run typechecknpm run lint(passes with one pre-existingno-img-elementwarning)npm run buildnpm run lintnpx tsc --noEmitOPENAI_API_KEY=build-validation-placeholder npm run build