Preparing your docs site

What the bot needs from your ctrl alt doc site, and how to write docs that search well.

The bot doesn't store a copy of your documentation. It asks your docs site's integration API each time, so the answers it gives depend on the site.

Version #

Run ctrl alt doc 1.0.7 or later for the full experience:

Site versionWhat the bot can do
1.0.8 or laterEverything below, plus each result's section and breadcrumb
1.0.7Question-style search, typo tolerance, answers that link to the matching heading, and section text with its original formatting
EarlierExact-phrase search only, and section text with simpler formatting

Older sites still work. The bot uses whatever each site provides.

API routes #

Sites expose the API from four route files. From 1.0.7 each one re-exports a handler from the package, so updating ctrl-alt-doc updates the API:

ts
// src/routes/api/search/+server.ts
import { searchEndpoint } from 'ctrl-alt-doc/api';

import { getSiteConfig } from '$lib/server/site';

export const GET = searchEndpoint(getSiteConfig);
Route fileHandler
src/routes/api/search/+server.tssearchEndpoint
src/routes/api/suggest/+server.tssuggestEndpoint
src/routes/api/page/+server.tspageEndpoint
src/routes/api/list/+server.tslistEndpoint

Sites created before 1.0.7 have their own copies of these routes. Updating the package doesn't change them, so replace each file with its one-line re-export once. After that, updates arrive with the package.

Hosting on Cloudflare #

If your docs site and the bot are Workers in the same Cloudflare account, Cloudflare blocks requests between them unless the bot has the global_fetch_strictly_public compatibility flag. The bot's template includes it. Bots set up before version 1.1.1 need it added by hand. See Troubleshooting .

Writing docs that search well #

The bot finds pages the same way your site's search box does:

  • Titles and headings count most. Name pages and sections after what people ask about, such as "Hide a page from the sidebar" rather than "Visibility".

  • Descriptions count next. A clear description helps the right page win.

  • Add keywords for words your text doesn't use. Synonyms, old names, and common misspellings all help:

    yaml
    ---
    title: Details
    keywords: [collapsible, accordion, spoiler, toggle]
    ---
  • Use headings for distinct topics. The bot can answer with a single section, so a question about one topic gets that section rather than the whole page.

API reference #

The bot uses three endpoints:

text
GET /api/search?q=<query>
GET /api/suggest?q=<text>&kind=page
GET /api/page?slug=<slug>

A search result looks like this. heading appears when a heading matches better than the page title:

json
{
	"title": "Cooking eggs",
	"description": "Boil, fry, and scramble.",
	"slug": "cooking/eggs",
	"excerpt": "…",
	"section": "Cooking",
	"breadcrumb": ["Cooking"],
	"heading": { "id": "boiling-an-egg", "title": "Boiling an egg" }
}

A page looks like this. content is the rendered HTML, and markdown is the source the bot uses for section text:

json
{
	"title": "Cooking eggs",
	"description": "Boil, fry, and scramble.",
	"excerpt": "",
	"slug": "cooking/eggs",
	"section": "Cooking",
	"breadcrumb": ["Cooking"],
	"toc": [{ "id": "boiling-an-egg", "title": "Boiling an egg", "level": 2 }],
	"content": "<h2 id=\"boiling-an-egg\">…",
	"markdown": "## Boiling an egg\n\n…"
}

A page that doesn't exist returns HTTP 404.