Live Documentation Search

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.
The live search modal with a filter chip active and ranked results

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.

ModeTriggered byMatches onCost
KeywordTyping, from three characters, debounced so a burst of keystrokes makes one requestThe words in your pagesCheap — a full-text query
HybridPressing Enter, onceWords and meaning, with the two rankings mergedSpends 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

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 happenedWhat the reader seesRecovers on its own?What you should do
The query matched nothingNo results found for “…” and Try different keywords or check your spellingNot applicableTreat it as a content signal, not a bug — the query was answered
Too many searches from one address in a short windowSearch is temporarily unavailableYes, within a minute or soNothing
Too many meaning-based searches for the siteResults still appear, with a note above them: Semantic search is briefly unavailable; results are full-text only.YesNothing — 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 setSearch goes quiet: the box falls back to recent searches and stops queryingNoBind a search index to the page type
The search service itself failedSearch is temporarily unavailable / Please try again in a moment.YesNothing, unless it persists
Your plan no longer includes live search, while a live-search build is still deployedSearch is temporarily unavailable, on every queryNo — only a rebuild fixes itPublish, 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.

The search modal showing results with the downgraded-search note

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.

ESC