Most "global search" is per-module search
A search box in the header that only queries whatever module you're currently viewing isn't global search — it's a filter with a bigger ambition in its label. Real global search means one query, one keystroke to open it from anywhere, and results spanning every entity type a user might be looking for: clients, projects, documents, tasks, invoices.
That's a harder problem than it looks, because each of those entity types usually lives behind a different API, a different permission model, and a different "open this result" navigation path.
What separates good search from a box that queries an API
One global keyboard shortcut
Cmd/Ctrl+K opens search from anywhere in the app, focus already in the input. If a user has to reach for the mouse to start searching, the feature will be underused.
Group results by entity type
A flat list mixing clients, invoices and documents forces users to read every row. Grouped, labeled sections let them jump straight to the type they're after.
Debounce, don't throttle the first keystroke
Debounce requests as the user types, but never delay the very first character's request — that first response is what convinces someone the feature is fast.
Preview before navigating
A hover or arrow-key preview of a task or document saves a full page navigation for the common case of "just checking," and keeps the search panel open for the next query.
Respect permissions in the index, not the UI
Filtering results a user can't access after they've already appeared on screen is both a security bug and a confusing flash of content. Filter server-side, before the response is built.
Design the zero-results state
A blank panel after a query reads as broken. Suggest a spelling correction, a broader term, or a fallback action — "create a new client named…" — instead of silence.
The navigation problem nobody plans for
Every entity type search returns needs its own "go here" route, and those routes rarely line up with a single, predictable URL pattern once permissions, tabs and nested detail views are involved. Build a small routing resolver per entity type early — a lookup table from result type to a route-building function — rather than hardcoding navigation logic inside the search component itself.
That separation is what lets a new entity type get search support in an afternoon instead of a sprint: register its resolver, index it server-side, and the search UI needs no changes at all.
The takeaway
Global search earns its name through keyboard access from anywhere, grouped and previewable results, permission filtering at the source, and a navigation layer decoupled from the search component itself. Get those right and it stops feeling like a filter with a bigger label — it becomes the fastest way through the product.
Let's talk about your frontendRelated reading
Architecture
The Case for a Thin Wrapper Layer Around Every UI Library
UX · Reading Behavior
Designing for the Second Glance: What Users Actually Scan vs. Read
Angular · Theming
PrimeUIX Theming in Practice: Customizing a Design System Without Forking It
See this global search applied in production on the Compito case study.