API
SearchOverlay component
SearchOverlay.astro renders the ⌘K command palette. Add it once in a
global layout. It’s a <dialog> that opens over the page; it doesn’t affect
layout until opened.
---
import SearchOverlay from "@hev/ask/components/SearchOverlay.astro";
---
<SearchOverlay />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
endpoint | string | '/api/ask' | Endpoint the overlay posts queries to. Must match the integration’s endpoint option. |
placeholder | string | 'Search the docs…' | Placeholder text for the input. |
debounce | number | 500 | Milliseconds after typing stops before a keyword query is sent. |
<SearchOverlay
endpoint="/api/ask"
placeholder="Search hev ask…"
debounce={400}
/>
Opening the overlay
Two ways, both built in:
⌘K/Ctrl-Kis bound automatically once the component is on the page.- Any element with
data-hev-ask-openopens it on click — wire up as many triggers as you like (header button, sidebar, inline links).
<button type="button" data-hev-ask-open>
Search <kbd>⌘K</kbd>
</button>
<a href="#" data-hev-ask-open>Search the docs</a>
Keyboard model
The overlay is ask-first: the number of words you’ve typed decides the path.
- Open (with AI on) → a few suggested questions appear. Click one — or
press
Tabto drop the first into the input — to ask it. - Type one word → debounced keyword search runs; the first result is auto-active. This is the instant, keyless lookup path.
- Type a space (a second word) → keyword type-ahead stops and the overlay switches to ask mode: the results area shows an Ask AI affordance and Enter sends the question to the agentic loop.
- Enter → in ask mode, runs the agentic loop. In keyword mode, opens the
active result. (If you moved the selection with
↑/↓on a single-word query, Enter opens that result instead of asking.) ↑/↓→ move the active keyword result. Esc → close.
So type a question → Enter asks AI, and type one word → Enter (or ↓↓ → Enter) opens a keyword hit. The footer hint reflects the current mode.
Suggested questions
When AI is on, the overlay fetches a short list of suggested questions from the
endpoint (GET /api/ask) the first time it opens and shows them in the empty
state. They come from the knowledge graph’s suggestions, baked in at build
time, so there’s no model call to render them — and if the graph has none,
the overlay simply shows nothing extra. Clicking a suggestion fills the input and
asks it immediately.
The mode toggle
The overlay persists an “AI on Enter” preference in localStorage under the key
hev-ask:mode (agentic or keyword). Readers who flip it to keyword-only
never trigger a model call: a space just searches for a phrase, and no suggested
questions are shown. The choice survives reloads.
Keyword results and deep links
Each keyword result row renders the document title, an optional heading
breadcrumb (Concepts › The agentic loop), and a one-line snippet. The row’s
link is the chunk’s url, which already carries the #anchor — so clicking a
result lands on the exact heading.
The streamed answer
Pressing Enter (with a key configured) replaces the keyword rows with an
answer panel. The sub-queries the model runs appear live as a faint
searched: … line, then the grounded answer streams in token-by-token with
a blinking caret until it completes. Inline deep links in the prose are
styled in the accent color and point at the exact /docs/page#anchor; hovering
shows the section breadcrumb. A Sources chip row beneath the answer lists
every section it drew from.
Links are validated against the source set the endpoint streamed: any link the model emits to a URL outside that set is rendered as plain text, so a hallucinated anchor can never become a clickable dead link.
Theming
The overlay’s markup uses the as- class prefix and reads your page’s CSS
custom properties. Define these on :root (this site’s values shown) and the
overlay inherits your palette:
:root {
--paper: #111111; /* overlay background */
--ink: #fafaf5; /* primary text */
--muted: #6b6b66; /* secondary text */
--signal: #e25822; /* accent / active state */
}
Because the component ships scoped styles keyed to these variables, matching your site’s look is usually just defining the tokens — no overlay CSS to override.