01 — Foundation

Search should feel predictable

Users expect to type, submit, see results, and recover when nothing matches.

Search is one of the fastest ways to lose trust. Slow feedback, mystery placeholders, results that jump, and errors buried in toasts make people repeat queries or leave. This pattern covers practical search UI — not enterprise search architecture.

02 — Input

The search field itself

Start with a real labelled input before adding instant suggestions.

  • visible label or accessible name — placeholder is not a label
  • use type="search" where appropriate; keep submit explicit when results are server-driven
  • show what scope is searched — “Search products”, not generic “Search”
  • clear button when the field often holds long queries
<form role="search" action="/search/" method="get">
    <label for="site-search">Search products</label>
    <input id="site-search" name="q" type="search" autocomplete="off" />
    <button type="submit">Search</button>
</form>

03 — Results

Results, loading, and no matches

Every state should answer: did it work, and what can I do next?

  • show that a search ran — query echoed, result count, or “Showing results for…”
  • loading feedback proportional to wait time; avoid flashing empty lists
  • empty results with guidance — spelling, filters, broader terms
  • errors inline with retry — not only a toast users might miss

04 — Enhancement

Live search and suggestions

Instant results are optional polish — the baseline should work without them.

  • debounce requests; cancel in-flight fetches when the query changes
  • combobox patterns for suggestions — keyboard, focus, and aria-expanded
  • do not trap users in client-only search with no shareable URL when lists matter
  • respect reduced motion; avoid animating every keystroke

05 — Review

Before you approve

A short checklist for search UI in code review.

  • labelled input, clear submit path, and understandable scope
  • loading, empty, and error states are specific and recoverable
  • enhancements degrade gracefully without JavaScript