## How Search Works

zudo-doc's built-in search widget uses a client-side word-match scorer for full-text site search. A search index is generated from your content files (title, description, and body text) and served as a single JSON file. The browser loads this index and performs all searching client-side — no server or external service required.

Each page's body is indexed up to the [`searchMaxBodyLength`](https://zudo-doc.takazudomodular.com/docs/guides/configuration#search-searchmaxbodylength) setting — 3,000 characters by default — so a query can match text deep into a long page, not only its opening lines. This setting controls indexing depth only, not what a result shows: a match always renders as a compact snippet of about 200 characters centered on the match, and the page description is shown instead of the body whenever one is set. Raising the cap grows `search-index.json` accordingly, since the whole indexed excerpt of every page ships to the browser — raising it from the old 300-character default to 3,000 grew this showcase's index about 3.4× (roughly 410 KB to 1.4 MB).

[Dynamic content unavailable in text export]

The optional [Search Worker](https://zudo-doc.takazudomodular.com/docs/guides/search#server-side-search-search-worker) indexes the same `searchMaxBodyLength`-capped body text, so changing the setting affects both the built-in widget and the worker together.



## Agent retrieval is separate

The optional [agent-readable export](https://zudo-doc.takazudomodular.com/docs/guides/agent-export) builds a separate full-text corpus, including material beyond `searchMaxBodyLength`. Its [MCP server](https://zudo-doc.takazudomodular.com/docs/guides/mcp-server) offers read-only `search` and `fetch` tools for documentation clients. Enabling either feature does not change the browser widget or this Search Worker's ranking and index contract.

## Using Search

Open the search dialog with:

- **Keyboard shortcut**: `Ctrl+K` (Windows/Linux) or `Cmd+K` (macOS)
- **Search button**: Click the search icon in the header

Type your query and results appear instantly. Click a result to navigate to that page.

## Works Everywhere

Search works in all environments:

- **Dev mode** (`pnpm dev`): The search index is generated on-the-fly via zfb's devMiddleware
- **Production build** (`pnpm build`): The index is written to `search-index.json` alongside the static site
- **Tauri** (offline reader): Loads the same index file from the bundled `dist/` — no special handling needed

[Dynamic content unavailable in text export]

No need to build before testing search. It works immediately with `pnpm dev`.



## Excluding Pages from Search

Pages with `search_exclude: true`, `draft: true`, or `unlisted: true` in their frontmatter are automatically excluded from the search index.

To explicitly exclude a page, add `search_exclude: true` to its frontmatter:

```mdx
---
title: My Internal Page
search_exclude: true
---
```

[Dynamic content unavailable in text export]

This is useful for pages like changelogs, imported content (e.g., CLAUDE.md), or internal-only pages that would clutter search results.



## Replacing the Search Widget

Use the `SearchWidget` slot in [Host Chrome Bindings](https://zudo-doc.takazudomodular.com/docs/reference/host-chrome-bindings) to replace the header search widget. The chrome passes exactly these seven locale-aware props:

```ts
SearchWidget: (props: {
  placeholderText: string;
  shortcutHint: string;
  resultCountTemplate: string;
  searchLabel: string;
  searchUnavailableText: string;
  loadingIndexText: string;
  noResultsText: string;
}) => unknown;
```

The chrome binds the site `base` path internally. A host widget never receives `base`, so do not require it in the replacement component.

## Search Features

The built-in widget provides:

- **Word matching**: Matches query terms in titles, descriptions, and body text
- **Field scoring**: Title matches add 3 points, descriptions add 2, and body text adds 1
- **Multiple terms**: Scores accumulate across matching terms and fields
- **Instant results**: The full index is loaded once and queried in-memory

## Server-Side Search (Search Worker)

For large documentation bases or programmatic API access, zudo-doc provides an optional **Search Worker** -- a Cloudflare Worker that runs MiniSearch server-side.

### When to Use the Search Worker

The built-in client-side search works well for small-to-medium documentation sites. The Search Worker becomes useful when:

- **Large index size** -- the full `search-index.json` is too large for comfortable browser download
- **API consumers** -- bots, CLI tools, or integrations need search access without a browser
- **Server-side processing** -- you want to keep the search index off the client

### How It Works

The Search Worker fetches the same `search-index.json` from your deployed site and caches it with a 5-minute TTL. It uses MiniSearch with prefix, fuzzy, and field-boost settings; its matching behavior is independent from the built-in widget's word-match scorer.

### Comparison

| Feature                    | Client-Side Search (built-in) | Search Worker              |
| -------------------------- | ----------------------------- | -------------------------- |
| Runtime                    | Browser (in-memory)           | Cloudflare Workers         |
| Setup required             | None (enabled by default)     | Cloudflare account + KV    |
| Index download             | Full index sent to browser    | Index stays server-side    |
| Best for                   | Small-to-medium doc bases     | Large doc bases, API consumers |
| Latency                    | Instant (local)               | Network round-trip         |

For setup instructions, API documentation, and deployment details, see the [Search Worker API reference](https://zudo-doc.takazudomodular.com/docs/reference/search-worker).