Live documentation search replaces the index your reader downloads with an endpoint on your own site. Typing searches as they type; pressing Enter runs a stronger search that also matches on meaning. There is nothing extra to configure — the search index you already bound to the set is what it reads.
What changes for a reader
The search box looks the same. What happens behind it does not.
- Results arrive as they type, from the third character onwards. Below three characters the modal shows their recent searches instead of querying.
- Pressing Enter runs a stronger search that matches on meaning as well as on words, so a reader who searches “stop a page going live” can find a page titled Unpublishing and Archiving.
- Filter chips above the results narrow to one page type of the index — useful the moment a single index covers both guides and an API reference.
- Each hit says how it matched — Keyword, Semantic, or Keyword + semantic — alongside a breadcrumb built from the set name and the page’s folders, and a snippet with the query terms highlighted. A meaning-only hit carries no snippet, because the snippet comes from the keyword index; its summary block is omitted rather than rendered empty.
- Recent searches are kept in their own browser, in local storage, and are offered again the next time they open the box. Nothing about that list leaves their machine.
What changes for you
Nothing, beyond having a search index bound to the set. There is no live-search switch, no per-set toggle and no second index to maintain.
The decision is made once per build. The build resolves your plan, then ships exactly one of the two search clients — the other file is not copied into your site at all, and on the live path the prebuilt index is not built and its library is not loaded. The choice fails closed: if the plan cannot be established, the build ships prebuilt search rather than shipping a client with nothing behind it.
The two search modes
The expensive path is spent only on a deliberate action, which is why typing stays cheap and Enter is worth pressing.
| Mode | Triggered by | Matches on | Cost |
|---|---|---|---|
| Keyword | Typing, from three characters, debounced so a burst of keystrokes makes one request | The words in your pages | Cheap — a full-text query |
| Hybrid | Pressing Enter, once | Words and meaning, with the two rankings merged | Spends one semantic embedding; subject to a per-site allowance |
An in-flight request is canceled when the next keystroke supersedes it, so a fast typist never sees results from a query they have already replaced.
sequenceDiagram
autonumber
actor Reader
participant Modal as Search modal
participant API as Search endpoint
Reader->>Modal: Types (3+ characters)
Modal->>API: Keyword search (debounced)
API-->>Modal: Ranked results
Reader->>Modal: Presses Enter
Modal->>API: Hybrid search (keyword + meaning)
alt Allowance available
API-->>Modal: Keyword + semantic results
else Semantic allowance spent
API-->>Modal: Keyword results + downgrade note
Modal-->>Reader: Results, with the note above them
else Refused or unavailable
API-->>Modal: Error
Modal-->>Reader: Search is temporarily unavailable
end
What a reader can and cannot search
The searchable universe is resolved on the server from the page the reader is standing on: their page type, the search index bound to it, and that index’s page types. The browser never names an index.
That has two consequences worth designing around. A reader cannot broaden their search by editing a request — the index is a real boundary, not a default. And a filter chip naming a page type outside the resolved universe is rejected rather than quietly ignored, which happens when an index was narrowed after the page was published: the client drops the stale chip, retries once, and the retry’s authoritative chip list replaces it. The reader sees a filter row that corrects itself, not an error.
Every failure state, and what the reader sees
This is the part worth reading before you ship. Every state below is deliberate, and none of them shows a reader a blank box.
| What happened | What the reader sees | Recovers on its own? | What you should do |
|---|---|---|---|
| The query matched nothing | No results found for “…” and Try different keywords or check your spelling | Not applicable | Treat it as a content signal, not a bug — the query was answered |
| Too many searches from one address in a short window | Search is temporarily unavailable | Yes, within a minute or so | Nothing |
| Too many meaning-based searches for the site | Results still appear, with a note above them: Semantic search is briefly unavailable; results are full-text only. | Yes | Nothing — the search still ran, it just ran weaker |
| The set has no index bound, or the page is not part of a documentation or API set | Search goes quiet: the box falls back to recent searches and stops querying | No | Bind a search index to the page type |
| The search service itself failed | Search is temporarily unavailable / Please try again in a moment. | Yes | Nothing, unless it persists |
| Your plan no longer includes live search, while a live-search build is still deployed | Search is temporarily unavailable, on every query | No — only a rebuild fixes it | Publish, so the build ships the prebuilt client again |
Two of these deserve their own paragraph.
A downgraded search still says so. When the meaning-based half is unavailable, the search is answered with keyword matching and the note is rendered above the results — including when the downgraded query found nothing, because an empty result set with no explanation reads as a statement about your documentation rather than about the weaker query the reader actually got.
An unconfigured set goes quiet rather than claiming to be broken. A page type with no index can never be searched, however many times you ask, so the client stops asking after the first refusal instead of putting temporarily unavailable on the screen once per keystroke — that sentence would not be true.
Privacy, and what gets recorded
The search endpoint runs outside your site’s session and cookie handling. It mints no session and sets no cookie of its own, so a debounced keystroke never creates a tracking row for a reader who has not otherwise been identified. It does read the identity your site’s analytics tracker has already established, so a search by a known visitor is attributed to them — and a reader with tracking blocked still gets search, it is simply logged without the attribution.
Every query is recorded as one request event, including queries that found nothing. Zero-result searches are the point: they are the record of what readers expected your documentation to contain. Failed searches are marked as failures so they cannot be mistaken for genuine misses.
Nothing to publish beyond the index
There is no live-search artifact to publish. The index that defines the searchable universe is created and bound at Search for Your Documentation, and everything else follows from your plan at build time.
The modal itself — the Ctrl + K shortcut, the ESC hint, the result list — is identical on both implementations and is described from the reader’s side at Site Search for Readers.