Skip to content

Keep search text typed before the page finishes loading - #64

Merged
lexler merged 2 commits into
mainfrom
fix/search-input-before-hydration
Oct 30, 2026
Merged

lexler merged 2 commits into
mainfrom
fix/search-input-before-hydration

Conversation

@lexler

@lexler lexler commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Text typed into the search bar before hydration was erased: the server-rendered input accepted keystrokes, then React hydrated it back to its empty initial state. On slow loads (and reliably on WebKit) the search looked broken.

Fix

SearchBar leaves the input uncontrolled until hydrated (value={isHydrated ? searchQuery : undefined}). The mount effect copies whatever the reader already typed (inputRef.current.value) into searchQuery, then sets isHydrated. Early keystrokes are kept and searched instead of blocked.

An earlier revision made the input readOnly until mount. That silently dropped early keystrokes, and the test hid it because fill() waits for an editable input.

Known side effect: switching from uncontrolled to controlled makes React log a dev-only "changing an uncontrolled input to be controlled" warning (it shows up in Jest output). Production builds don't log it, and no test fails on it.

Tests

  • New Playwright test text typed while the page is still loading is kept: delays /_next/static/chunks/** by 2s, focuses the input and types with page.keyboard.type during the delayed load, then expects results plus the typed value. It failed on desktop-chrome and iphone against both main and the readOnly revision, and passes now.
  • iPhone search tests with --repeat-each=2: on main 11 of 20 failed in the dev orb; now 22 of 22 pass.
  • ./test.sh: 370 passed. npm run lint: clean. ./e2e.sh: 93 passed, 0 failed (9 skipped are pre-existing).

CI

.github/workflows/deploy.yml now installs chromium webkit and runs --project=desktop-chrome --project=iphone.

Before hydration the search input accepted typing, then React reset it to
its empty initial state. The input is now read-only until a mount effect
marks it ready. CI also runs the iPhone (WebKit) project, which reproduces
the bug reliably.

Amp-Thread-ID: https://ampcode.com/threads/T-01a18b16-89b6-7301-9d0c-e6ff7f681d32
Co-authored-by: Lada Kesseler <archie.kesseler@gmail.com>
The input stays uncontrolled until hydrated, then the mount effect copies
what the reader already typed into state. The early-typing test now types
with the keyboard during the delayed load, since fill() waits for an
editable input and hid the dropped keystrokes under the readOnly approach.

Amp-Thread-ID: https://ampcode.com/threads/T-01a18b16-89b6-7301-9d0c-e6ff7f681d32
Co-authored-by: Lada Kesseler <archie.kesseler@gmail.com>
@lexler
lexler merged commit f72c252 into main Oct 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants