# Docs and help centers

> Records and settings for documentation and help centers: one record per section, so a search lands on the heading that answers it.

Readers search docs for a task or a term, and want the part of the page that covers it. Give each section its own record, and a search lands on the right heading with the matching words highlighted. The search on these docs works this way.

## Records

One record per section, for each `##` and `###` heading, plus one for each page's introduction:

```json
{
  "objectID": "settings#synonyms",
  "page": "Search settings",
  "section": "Synonyms",
  "group": "Guides",
  "url": "/docs/settings#synonyms",
  "text": "synonyms are groups of words or phrases that match each other: searching for any of them finds the others…",
  "code": "",
  "summary": "synonyms are groups of words or phrases that match each other: searching for any of them finds the others, ranked slightly below the word itself.",
  "level": 3,
  "order": 29
}
```

- **Sections, not pages.** A whole page matches nearly any search about its topic, and opens at its top. A section matches what it covers, opens at its heading, and fits in the 16 KB a searchable field holds.
- **`url` ends with the heading's anchor,** so a result opens at the section.
- **`text` is plain text,** without Markdown or HTML, so highlights and excerpts read well. Code goes in its own field, searched with less weight.
- **`summary`** is the section's first sentence, to show when the match was in the heading.
- **`level` and `order`** put a page's introduction and main sections ahead of its subsections when results tie, in reading order.

Build the records from your Markdown or HTML when the site builds, and upload them with [`replaceAll`](/docs/records.md#replace-the-whole-catalog) on each deploy, so renamed and removed sections leave search.

## Settings

```ts
{
  searchableAttributes: [
    { field: "section", weight: 8 },
    { field: "page", weight: 4 },
    { field: "text", weight: 2 },
    { field: "code", weight: 1 },
  ],
  facetFields: [],
  filterFields: ["group"],
  customRanking: [
    { field: "level", direction: "asc" },
    { field: "order", direction: "asc" },
  ],
  synonyms: [["delete", "remove"], ["api key", "secret key"], ["autocomplete", "search as you type"]],
  didYouMean: true,
  languages: ["en"],
}
```

- **Headings first.** They're short and say what a section is about, and the first two searchable fields hold 1 KB each, which suits them.
- **Synonyms** for your product's terms and the words readers use instead, such as "remove" for "delete".
- **`group`** as a filter lets a search box offer choices like "Guides only".

## Search box

`SearchDialog` is the pattern docs sites use: a button that opens a search dialog, which ⌘K (Ctrl+K elsewhere) and `/` open too.

```tsx
import { SearchDialog } from "@findlane/browser/react"

export function DocsSearch() {
  return (
    <SearchDialog
      publicId="pub_your_public_id"
      placeholder="Search the docs"
      fields={["page", "section", "url", "summary"]}
      hrefTemplate="{url}"
    />
  )
}
```

Show each result as "page › section", with an excerpt from `Snippet` around the matched words (see [Highlights](/docs/react.md#highlights)).

## Questions and keywords

Every word in a search must match. [`languages`](/docs/settings.md#languages) leaves out common words such as "the" and "a", but not question words, so "how do I delete a record" only finds sections that also contain "how" and "do". Keywords such as "delete record" work best, and a placeholder can suggest them.

## Private docs

Everything browser search can read is public. Docs for signed-in customers belong in their own index, searched from your server with a `search` key after you check who's asking.
