Docula ships with a fast, fully client-side search built into the modern
template — no third-party service, API key, or external dependency required.
At build time Docula generates a search-index.json file from your
documentation and changelog, and the template renders a keyboard-driven search
modal that queries it in the browser.
Table of Contents
How it works
- During the build, every documentation page and changelog entry is split into
sections — one record per heading — and written to
search-index.jsonin the output root. - Each record keeps the page title, the heading breadcrumb, the section text,
and a deep-link URL (including the
#anchor) so results jump straight to the matching heading. - The modern template renders a search button in the header and a modal that loads the index on first open and ranks matches as you type.
Using search
- Click the Search button in the header, press ⌘ K / Ctrl K, or press / to open the modal.
- Type to filter — results are ranked by where the match occurs (titles rank above body text) and matched terms are highlighted.
- Use ↑ / ↓ to move between results, ↵ to open the highlighted result, and esc to close.
Configuration
Search is enabled by default. Set enableSearch to false to skip generating
the index and hide the search UI:
import type { DoculaOptions } from 'docula';
export const options: Partial<DoculaOptions> = {
enableSearch: false,
};
When enableSearch is false, no search-index.json is written and the search
button and modal are omitted from the rendered pages.
What gets indexed
| Content | Indexed |
|---|---|
Documentation pages (docs/) |
Yes — one record per heading, plus a page-level record |
| Changelog entries | Yes — published entries (drafts are skipped) |
| API reference | No — the API page has its own built-in endpoint filter |
The injected "Table of Contents" section is automatically excluded from the index so it never shows up as a result.