From 596397c359968841aeaa8a91e399d07c7bb234f6 Mon Sep 17 00:00:00 2001 From: Paul Jankowski <8bittitan@gmail.com> Date: Thu, 30 Jul 2026 09:47:28 -0400 Subject: [PATCH] feat(docs): Document v5 beta (#2935) * chore(docs): v5 documentation * Writing style clean up * fix: website after conflicts --- AGENTS.md | 4 + bun.lock | 22 +- packages/website/WRITING_GUIDE.md | 91 ++ .../docs/agent-studio/dynamic-indices.mdx | 162 +++ .../website/docs/agent-studio/feedback.mdx | 82 ++ .../docs/agent-studio/getting-started.mdx | 158 +++ packages/website/docs/agent-studio/memory.mdx | 68 ++ .../docs/agent-studio/prompt-suggestions.mdx | 69 ++ packages/website/docs/agent-studio/tools.mdx | 106 ++ packages/website/docs/api.mdx | 886 +------------- packages/website/docs/composable-api.mdx | 529 ++++---- .../docs/crawler-configuration-visual.mdx | 21 +- packages/website/docs/crawler.mdx | 98 +- packages/website/docs/create-crawler.mdx | 28 +- packages/website/docs/docsearch-program.md | 87 +- packages/website/docs/docsearch.mdx | 405 +------ packages/website/docs/docusaurus-adapter.mdx | 120 +- packages/website/docs/examples.mdx | 362 +----- packages/website/docs/how-does-it-work.mdx | 30 +- packages/website/docs/hybrid-mode.mdx | 441 +++++++ packages/website/docs/integrations.md | 15 +- packages/website/docs/manage-your-crawls.mdx | 10 +- packages/website/docs/mcp/installation.mdx | 256 +++- packages/website/docs/mcp/overview.mdx | 51 +- packages/website/docs/mcp/usage.mdx | 146 ++- .../website/docs/migrating-from-legacy.mdx | 22 +- packages/website/docs/migrating-from-v4.mdx | 293 +++++ packages/website/docs/packages/core/api.mdx | 284 +++++ .../website/docs/packages/core/overview.mdx | 124 ++ .../docs/packages/css/bundle-exports.mdx | 101 ++ .../website/docs/packages/css/styling.mdx | 131 ++ .../configuration-reference.mdx | 618 ++++++++++ .../docusaurus-adapter/getting-started.mdx | 142 +++ .../docusaurus-adapter/migrating-from-v4.mdx | 388 ++++++ .../docs/packages/js/api-reference.mdx | 487 ++++++++ .../docs/packages/js/getting-started.mdx | 168 +++ packages/website/docs/packages/modal/api.mdx | 343 ++++++ .../website/docs/packages/modal/overview.mdx | 139 +++ packages/website/docs/packages/overview.mdx | 84 ++ .../docs/packages/react/api-reference.mdx | 418 +++++++ .../website/docs/packages/react/examples.mdx | 271 +++++ .../docs/packages/react/getting-started.mdx | 140 +++ .../docs/packages/sidepanel-js/api.mdx | 230 ++++ .../packages/sidepanel-js/getting-started.mdx | 120 ++ .../packages/sidepanel/advanced-use-cases.mdx | 162 +++ .../website/docs/packages/sidepanel/api.mdx | 229 ++++ .../packages/sidepanel/getting-started.mdx | 101 ++ packages/website/docs/record-extractor.md | 39 +- .../website/docs/required-configuration.mdx | 67 +- .../docs/sidepanel/advanced-use-cases.mdx | 144 +-- .../website/docs/sidepanel/api-reference.mdx | 149 +-- .../docs/sidepanel/getting-started.mdx | 137 +-- packages/website/docs/sidepanel/hybrid.mdx | 165 +-- packages/website/docs/styling.md | 47 +- packages/website/docs/templates.mdx | 94 +- packages/website/docs/tips.md | 53 +- packages/website/docs/v5-breaking-changes.mdx | 236 ++++ packages/website/docs/what-is-docsearch.md | 18 +- packages/website/docs/who-can-apply.md | 18 +- packages/website/docusaurus.config.mjs | 17 +- packages/website/sidebars.js | 112 +- packages/website/src/components/Home.js | 6 +- .../website/versioned_docs/version-v4/api.mdx | 935 ++++++++++++++ .../version-v4/composable-api.mdx | 315 +++++ .../crawler-configuration-visual.mdx | 96 ++ .../versioned_docs/version-v4/crawler.mdx | 120 ++ .../version-v4/create-crawler.mdx | 78 ++ .../version-v4/docsearch-program.md | 131 ++ .../versioned_docs/version-v4/docsearch.mdx | 418 +++++++ .../version-v4/docusaurus-adapter.mdx | 61 + .../versioned_docs/version-v4/examples.mdx | 428 +++++++ .../version-v4/how-does-it-work.mdx | 51 + .../versioned_docs/version-v4/integrations.md | 45 + .../version-v4/manage-your-crawls.mdx | 67 ++ .../version-v4/mcp/installation.mdx | 32 + .../version-v4/mcp/overview.mdx | 49 + .../versioned_docs/version-v4/mcp/usage.mdx | 113 ++ .../version-v4/migrating-from-legacy.mdx | 87 ++ .../version-v4}/migrating-from-v3.md | 0 .../version-v4/record-extractor.md | 345 ++++++ .../version-v4/required-configuration.mdx | 189 +++ .../sidepanel/advanced-use-cases.mdx | 144 +++ .../version-v4/sidepanel/api-reference.mdx | 186 +++ .../version-v4/sidepanel/getting-started.mdx | 136 +++ .../version-v4/sidepanel/hybrid.mdx | 100 ++ .../versioned_docs/version-v4/styling.md | 48 + .../versioned_docs/version-v4/templates.mdx | 1069 +++++++++++++++++ .../website/versioned_docs/version-v4/tips.md | 71 ++ .../version-v4}/v4/askai-api.mdx | 2 +- .../version-v4}/v4/askai-errors.mdx | 2 +- .../v4/askai-markdown-indexing.mdx | 10 +- .../version-v4}/v4/askai-models.mdx | 2 +- .../version-v4}/v4/askai-prompts.mdx | 0 .../v4/askai-whitelisted-domains.mdx | 0 .../version-v4}/v4/askai.mdx | 4 +- .../version-v4/what-is-docsearch.md | 32 + .../version-v4/who-can-apply.md | 30 + .../version-v4-sidebars.json | 81 ++ packages/website/versions.json | 2 +- 99 files changed, 13053 insertions(+), 2970 deletions(-) create mode 100644 packages/website/WRITING_GUIDE.md create mode 100644 packages/website/docs/agent-studio/dynamic-indices.mdx create mode 100644 packages/website/docs/agent-studio/feedback.mdx create mode 100644 packages/website/docs/agent-studio/getting-started.mdx create mode 100644 packages/website/docs/agent-studio/memory.mdx create mode 100644 packages/website/docs/agent-studio/prompt-suggestions.mdx create mode 100644 packages/website/docs/agent-studio/tools.mdx create mode 100644 packages/website/docs/hybrid-mode.mdx create mode 100644 packages/website/docs/migrating-from-v4.mdx create mode 100644 packages/website/docs/packages/core/api.mdx create mode 100644 packages/website/docs/packages/core/overview.mdx create mode 100644 packages/website/docs/packages/css/bundle-exports.mdx create mode 100644 packages/website/docs/packages/css/styling.mdx create mode 100644 packages/website/docs/packages/docusaurus-adapter/configuration-reference.mdx create mode 100644 packages/website/docs/packages/docusaurus-adapter/getting-started.mdx create mode 100644 packages/website/docs/packages/docusaurus-adapter/migrating-from-v4.mdx create mode 100644 packages/website/docs/packages/js/api-reference.mdx create mode 100644 packages/website/docs/packages/js/getting-started.mdx create mode 100644 packages/website/docs/packages/modal/api.mdx create mode 100644 packages/website/docs/packages/modal/overview.mdx create mode 100644 packages/website/docs/packages/overview.mdx create mode 100644 packages/website/docs/packages/react/api-reference.mdx create mode 100644 packages/website/docs/packages/react/examples.mdx create mode 100644 packages/website/docs/packages/react/getting-started.mdx create mode 100644 packages/website/docs/packages/sidepanel-js/api.mdx create mode 100644 packages/website/docs/packages/sidepanel-js/getting-started.mdx create mode 100644 packages/website/docs/packages/sidepanel/advanced-use-cases.mdx create mode 100644 packages/website/docs/packages/sidepanel/api.mdx create mode 100644 packages/website/docs/packages/sidepanel/getting-started.mdx create mode 100644 packages/website/docs/v5-breaking-changes.mdx create mode 100644 packages/website/versioned_docs/version-v4/api.mdx create mode 100644 packages/website/versioned_docs/version-v4/composable-api.mdx create mode 100644 packages/website/versioned_docs/version-v4/crawler-configuration-visual.mdx create mode 100644 packages/website/versioned_docs/version-v4/crawler.mdx create mode 100644 packages/website/versioned_docs/version-v4/create-crawler.mdx create mode 100644 packages/website/versioned_docs/version-v4/docsearch-program.md create mode 100644 packages/website/versioned_docs/version-v4/docsearch.mdx create mode 100644 packages/website/versioned_docs/version-v4/docusaurus-adapter.mdx create mode 100644 packages/website/versioned_docs/version-v4/examples.mdx create mode 100644 packages/website/versioned_docs/version-v4/how-does-it-work.mdx create mode 100644 packages/website/versioned_docs/version-v4/integrations.md create mode 100644 packages/website/versioned_docs/version-v4/manage-your-crawls.mdx create mode 100644 packages/website/versioned_docs/version-v4/mcp/installation.mdx create mode 100644 packages/website/versioned_docs/version-v4/mcp/overview.mdx create mode 100644 packages/website/versioned_docs/version-v4/mcp/usage.mdx create mode 100644 packages/website/versioned_docs/version-v4/migrating-from-legacy.mdx rename packages/website/{docs => versioned_docs/version-v4}/migrating-from-v3.md (100%) create mode 100644 packages/website/versioned_docs/version-v4/record-extractor.md create mode 100644 packages/website/versioned_docs/version-v4/required-configuration.mdx create mode 100644 packages/website/versioned_docs/version-v4/sidepanel/advanced-use-cases.mdx create mode 100644 packages/website/versioned_docs/version-v4/sidepanel/api-reference.mdx create mode 100644 packages/website/versioned_docs/version-v4/sidepanel/getting-started.mdx create mode 100644 packages/website/versioned_docs/version-v4/sidepanel/hybrid.mdx create mode 100644 packages/website/versioned_docs/version-v4/styling.md create mode 100644 packages/website/versioned_docs/version-v4/templates.mdx create mode 100644 packages/website/versioned_docs/version-v4/tips.md rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-api.mdx (97%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-errors.mdx (99%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-markdown-indexing.mdx (99%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-models.mdx (71%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-prompts.mdx (100%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai-whitelisted-domains.mdx (100%) rename packages/website/{docs => versioned_docs/version-v4}/v4/askai.mdx (98%) create mode 100644 packages/website/versioned_docs/version-v4/what-is-docsearch.md create mode 100644 packages/website/versioned_docs/version-v4/who-can-apply.md create mode 100644 packages/website/versioned_sidebars/version-v4-sidebars.json diff --git a/AGENTS.md b/AGENTS.md index eb934717..4e7c544f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -259,3 +259,7 @@ Non-obvious caveats: - **To run/demo the widget, use the React playground:** `bun run playground:start` serves at `http://localhost:5173` (Vite). `bun run playground-js:start` serves the vanilla-JS demo. These connect to Algolia's hosted index using public credentials baked into the demo, so **outbound internet is required** for live search results. - Run unit tests non-interactively with `bun run test --run` (plain `bun run test` starts Vitest watch mode). - `bun run lint:css` reports many pre-existing CSS lint violations in the repo; these are not environment problems. + +## Documentation + +- When writing or working on the documentation website (`packages/website`), MUST adhere to the writing guidelines in @packages/website/WRITING_GUIDE.md diff --git a/bun.lock b/bun.lock index 63b80ac4..e986d9fc 100644 --- a/bun.lock +++ b/bun.lock @@ -31,7 +31,7 @@ }, "adapters/docusaurus-theme-search-algolia": { "name": "@docsearch/docusaurus-adapter", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@algolia/autocomplete-core": "1.19.2", "@docsearch/core": "workspace:*", @@ -115,7 +115,7 @@ }, "packages/docsearch-core": { "name": "@docsearch/core", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "devDependencies": { "@testing-library/jest-dom": "6.6.3", "@testing-library/react": "16.2.0", @@ -137,7 +137,7 @@ }, "packages/docsearch-css": { "name": "@docsearch/css", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "devDependencies": { "browserslist": "4.28.2", "lightningcss": "1.32.0", @@ -146,7 +146,7 @@ }, "packages/docsearch-js": { "name": "@docsearch/js", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@docsearch/core": "4.6.0", "@docsearch/react": "4.6.0", @@ -160,7 +160,7 @@ }, "packages/docsearch-modal": { "name": "@docsearch/modal", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@docsearch/core": "4.6.0", "@docsearch/react": "4.6.0", @@ -185,13 +185,13 @@ }, "packages/docsearch-react": { "name": "@docsearch/react", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@ai-sdk/react": "^2.0.30", "@algolia/autocomplete-core": "1.19.2", "@base-ui/react": "^1.5.0", - "@docsearch/core": "5.0.0-beta.0", - "@docsearch/css": "5.0.0-beta.0", + "@docsearch/core": "5.0.0-beta.1", + "@docsearch/css": "5.0.0-beta.1", "ai": "^5.0.30", "algoliasearch": "^5.28.0", "marked": "^16.3.0", @@ -199,7 +199,7 @@ }, "devDependencies": { "@algolia/autocomplete-core": "1.19.2", - "@docsearch/core": "5.0.0-beta.0", + "@docsearch/core": "5.0.0-beta.1", "@testing-library/jest-dom": "6.6.3", "@testing-library/react": "16.2.0", "preact": "11.0.0-beta.0", @@ -222,7 +222,7 @@ }, "packages/docsearch-sidepanel": { "name": "@docsearch/sidepanel", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@docsearch/core": "4.6.0", "@docsearch/css": "4.6.0", @@ -248,7 +248,7 @@ }, "packages/docsearch-sidepanel-js": { "name": "@docsearch/sidepanel-js", - "version": "5.0.0-beta.0", + "version": "5.0.0-beta.1", "dependencies": { "@docsearch/core": "4.6.0", "@docsearch/react": "4.6.0", diff --git a/packages/website/WRITING_GUIDE.md b/packages/website/WRITING_GUIDE.md new file mode 100644 index 00000000..ae2aff81 --- /dev/null +++ b/packages/website/WRITING_GUIDE.md @@ -0,0 +1,91 @@ +# Style guide + +## Core principles + +- Help users succeed with Algolia. +- Docs must stay correct, clear, complete, current. +- Missing rule: use [Google developer docs style guide](https://developers.google.com/style). API refs: use [API docs style guide](https://api-clients-automation.netlify.app/docs/add-a-new-api/api-documentation-guidelines). +- Write simple, consistent, concise. Explain what users need. No extra. +- ALWAYS lean on using standardized markdown templating. + +## Voice and tone + +- Write like teaching new teammate. Then cut fluff. +- Use contractions, short sentences, short paragraphs, imperative mood, active voice. +- Focus user goals, not feature internals. +- Give guidance + best practices. Samples should feel production-ready. +- No sarcasm, humor, emojis, double negatives, idioms, `easy`, `simply`, `quick`. +- Write accessible, global, inclusive docs. + +## Version references + +- When referencing installing a `v5` package, MUST use the caret (`^`) based versioning: `@^5.0.0-beta` +- When displaying install commands, ONLY include `@docsearch/*` packages, there's no need to include any other packages unless specified + +## Pages + +- Every page MUST have a title +- Every page MUST have a concise description describing at a high level the information that is on the page +- If you are about to explain a concept or property that is better explained on a different page, prefer to link to that current section on the other page instead + +## Tabs + +- Use Docusaurus theme `` and `` components when writing the following: + - Code snippets: One tab for React/TSX based snippet, one tab for vanilla JS snippet + - vanilla js -> label: 'JavaScript', value: 'js' + - react -> label: 'React', value: 'react' + - Install commands (npm/yarn/pnpm/bun) with each package manager being it's own tab +- Always give each tab a title +- "React" tab MUST always be the first one listed + +**EXAMPLE**: + +```tsx + + + + +``` + +## Links + +- Prefer to use shared links on pages + +**EXAMPLE**: + +```mdx +This is a test [Website][1] + +[1]: https://example.com +``` + +## API References + +- API reference pages should focus on detailing out the specification for the related package/domain +- If explaining exports/imports of a package, those definitions MUST appear at the bottom of the page + - exports/imports here are the rare occassion where tables ARE THE PREFERRED DISPLAY TYPE +- Property definition as defined below is preferred over tables + + +## `PROPERTY_NAME` + +> `type: TYPE_PRIMITIVE|ROUGH_TYPE_DEFINITION_FROM_SOURCE` | **required** | **optional** | **experimental** + +CONCISE DESCRIPTION OF THE PROPERTY + + +"type" in the property definition is a static string that should always be included, it tells the reader that the following information is a type definition. +The different tags (required/optional/experimental) are optional on their own, but MUST be used correctly + +## Tables + +- AVOID tables as much as possible +- IF a table is required, or absolutely the best option for display, it MUST be contained to a MAX of 3 columns + +## Package names + +- When referencing @docsearch/sidepanel package, the component MUST be named `Sidepanel` (capital 'S') + +## Code blocks + +- A Codeblock should prefer to have a title to it, ideally a realtively similar filename (app.tsx, Search.tsx, load-docsearch.js) diff --git a/packages/website/docs/agent-studio/dynamic-indices.mdx b/packages/website/docs/agent-studio/dynamic-indices.mdx new file mode 100644 index 00000000..7ee8c07d --- /dev/null +++ b/packages/website/docs/agent-studio/dynamic-indices.mdx @@ -0,0 +1,162 @@ +--- +title: Configure dynamic indices +description: Select Agent Studio search indices dynamically at runtime. +--- + +Pass `askAi.indices` when the Agent Studio search tool needs index definitions at request time. This lets your application choose indices, descriptions, fixed search parameters, and model-controlled parameters for each DocSearch instance. + +This property isn't the same as the top-level `indices` property: + +- Top-level `indices` configures DocSearch keyword search. Entries are index names or objects with a `name` property. +- `askAi.indices` configures Agent Studio search. Entries use an `index` property and require a `description`. + +## Define an index + +```tsx title="Search.tsx" + +``` + +Each index accepts these properties: + +### `index` + +> `type: string` | **required** + +Names the Algolia index. + +### `description` + +> `type: string` | **required** + +Tells the agent what the index contains. + +### `enhancedDescription` + +> `type: string` | **optional** + +Gives the agent more guidance about when and how to use the index. + +### `searchParameters` + +> `type: SearchParamsObject` | **optional** + +Sets defaults for the internal, non-MCP search path. It accepts Algolia search parameters. + +### `searchControls` + +> `type: AgentStudioSearchControls` | **optional** + +Configures parameters for the MCP-based search path. + +Write specific descriptions. Agent Studio uses them to select an index and plan a search. See [Algolia Search tool configuration](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/algolia-search) for guidance. + +## Configure search controls + +A search control describes whether the model can provide a value and which default or constraints apply. + +### `query` + +> `type: { exposed, default? }` | **optional** + +Sets the search query control. It has no DocSearch default when omitted. + +### `hits_per_page` + +> `type: { exposed, default?, constraint?: { min?, max? } }` | **optional** + +Sets the number of results per page. When omitted, DocSearch uses `{ exposed: false, default: 7 }`. + +### `page` + +> `type: { exposed, default?, constraint?: { min?, max? } }` | **optional** + +Sets the requested page. When omitted, DocSearch uses `{ exposed: false, default: 0 }`. + +### `attributesToRetrieve` + +> `type: { exposed, default?, constraint?: { values? }, merge? }` | **optional** + +Sets the attributes returned for each hit. When omitted, DocSearch uses `{ exposed: false, default: ['*'] }`. + +### `responseFields` + +> `type: { exposed, default?, constraint?: { values? }, merge? }` | **optional** + +Sets the fields returned in the search response. When omitted, DocSearch uses `{ exposed: false, default: ['hits', 'nbHits', 'page', 'nbPages', 'hitsPerPage', 'facets'] }`. + +### `facets` + +> `type: { exposed: false, default? }` | **optional** + +Sets the facets requested with the search. It has no DocSearch default when omitted. + +### `custom` + +> `type: Record` | **optional** + +Sets extra tool parameters. It has no DocSearch default when omitted. + +Use `exposed: true` only for values the model should choose from conversation context. Use fixed defaults for business rules and response limits. For the distinction between runtime and predefined parameters, see [Agent Studio tools](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/overview#configure-runtime-parameters-for-dynamic-tool-execution). + +## Set request-wide search parameters + +`askAi.searchParameters` is keyed by index name: + +```js title="docsearch.js" +askAi: { + assistantId: 'YOUR_AGENT_ID', + searchParameters: { + docs_markdown: { + filters: 'visibility:public', + attributesToRetrieve: ['title', 'content', 'url'], + distinct: false, + }, + }, +} +``` + +Don't use the flat search-parameter shape from earlier DocSearch AI integrations. + +## Docusaurus validation + +The v5 Docusaurus adapter requires at least one entry when you set `askAi.indices`. Every entry must include `index` and `description`. It rejects unknown `searchControls` properties, except values nested under `custom`. + +See the [React package reference](/docs/packages/react/api-reference) and [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started) for the complete types. diff --git a/packages/website/docs/agent-studio/feedback.mdx b/packages/website/docs/agent-studio/feedback.mdx new file mode 100644 index 00000000..0797a9fc --- /dev/null +++ b/packages/website/docs/agent-studio/feedback.mdx @@ -0,0 +1,82 @@ +--- +title: Collect response feedback +description: Collect user feedback on Agent Studio responses. +--- + +DocSearch v5 includes feedback controls for completed Agent Studio answers. You don't need to add an `askAi` option to enable them. + +Use an API key with the `search` ACL. Agent Studio accepts one vote per message. See [Agent Studio feedback](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/feedback) for service requirements and reporting details. + +## Understand the ratings + +Thumbs up submits positive feedback immediately: + +```ts +{ + thumbs: 1; +} +``` + +Thumbs down opens a form before submission. A user can select zero or more reason tags and add an optional note: + +```ts +{ + thumbs: 0; + tags?: AskAiFeedbackReason[]; + notes?: string; +} +``` + +Closing or canceling the form doesn't submit feedback. Submitting without a reason or note is valid. DocSearch trims notes, omits an empty note, and limits notes to 1,000 characters. + +DocSearch supports these reason values: + +| Value | Default label | +| ------------------ | ----------------------- | +| `incorrect` | Incorrect or incomplete | +| `not_what_i_asked` | Not what I asked for | +| `slow_or_buggy` | Slow or buggy | +| `style_or_tone` | Style or tone | +| `safety_or_legal` | Safety or legal concern | +| `other` | Other | + +Reason tags and notes are collected only for negative feedback. + +## Understand submission behavior + +DocSearch sends the Agent Studio agent ID, message ID, vote, and optional negative-feedback details to Agent Studio. After a successful request, it shows a thank-you state and records the rating with the locally stored conversation. + +If submission fails, DocSearch keeps the negative-feedback form open and displays the error so the user can retry. + +## Change feedback labels + +Override feedback text through `translations.modal.askAiScreen`: + +```tsx title="Search.tsx" + +``` + +See the [React package reference](/docs/packages/react/api-reference) for all feedback translation keys and the exported feedback types. diff --git a/packages/website/docs/agent-studio/getting-started.mdx b/packages/website/docs/agent-studio/getting-started.mdx new file mode 100644 index 00000000..11cd6e97 --- /dev/null +++ b/packages/website/docs/agent-studio/getting-started.mdx @@ -0,0 +1,158 @@ +--- +title: Get started with Agent Studio +description: Configure Agent Studio to answer questions from your documentation. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +DocSearch v5 uses [Agent Studio](https://www.algolia.com/doc/guides/algolia-ai/agent-studio) as its only AI backend. The public option is still named `askAi`, so you can add AI without learning a second DocSearch configuration shape. + +Don't add an `agentStudio` flag. There's no AI backend selector in v5. + +## Before you begin + +1. [Create and publish an Agent Studio agent](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/quickstart). +2. Copy its agent ID. DocSearch calls this value `assistantId` in its public API. +3. Create a Search API key that can search the indices used by DocSearch and Agent Studio. Don't expose an Admin API key. +4. Note your Algolia application ID and DocSearch index name. + +## Add DocSearch + + + + +Install the React package and styles: + + + + +```bash +npm install @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Render `DocSearchAI`, not the search-only `DocSearch` component: + +```tsx title="Search.tsx" +import { DocSearchAI } from '@docsearch/react'; +import '@docsearch/css'; + +export function Search() { + return ( + + ); +} +``` + +See the [React package reference](/docs/packages/react/api-reference) for all `DocSearchAI` props and exported types. + + + + +Install the JavaScript package and styles: + + + + +```bash +npm install @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Add a container to your page: + +```html title="index.html" +
+``` + +Initialize DocSearch with your Agent Studio agent: + +```js title="load-docsearch.js" +import docsearch from '@docsearch/js'; +import '@docsearch/css'; + +docsearch({ + container: '#docsearch', + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_DOCSEARCH_INDEX'], + askAi: { + assistantId: 'YOUR_AGENT_ID', + }, +}); +``` + +See the [JavaScript package reference](/docs/packages/js/api-reference) for the complete API. + +
+
+ +## Configure more Agent Studio features + +Use the `askAi` object to add: + +- [Dynamic indices and search controls](/docs/agent-studio/dynamic-indices) +- [Client-side and MCP tools](/docs/agent-studio/tools) +- [User-scoped memory](/docs/agent-studio/memory) +- [Suggested prompts and follow-ups](/docs/agent-studio/prompt-suggestions) +- [Response feedback](/docs/agent-studio/feedback) + +## Use the Docusaurus adapter + +The v5 Docusaurus adapter requires `themeConfig.docsearch.askAi` to be an object with `assistantId`. It rejects the string shorthand and the removed `agentStudio` property. Keep `appId`, `apiKey`, and keyword-search `indices` at the top level. + +See the [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started) for its full configuration and validation rules. diff --git a/packages/website/docs/agent-studio/memory.mdx b/packages/website/docs/agent-studio/memory.mdx new file mode 100644 index 00000000..a88c8802 --- /dev/null +++ b/packages/website/docs/agent-studio/memory.mdx @@ -0,0 +1,68 @@ +--- +title: Add user-scoped memory +description: Store and retrieve user-scoped memory in Agent Studio conversations. +--- + +Agent Studio memory lets an agent retain useful context for a user across conversations. Configure memory in Agent Studio first, then give DocSearch a secure user token so Agent Studio can isolate each user's data. + +Read the [Agent Studio memory overview](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/memory/overview) before enabling memory in production. + +## Generate a secure user token + +Generate the JWT on your backend after authenticating the user. Follow the [Agent Studio user authentication guide](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/user-authentication) for the required claims, signing algorithm, and key ID. + +Protect the token flow: + +- Never generate the token in browser code. +- Never expose the Algolia secret key used to sign it. +- Use a stable, non-sensitive user identifier in the JWT `sub` claim. +- Set an expiration and refresh expired tokens. +- Serve the token only over HTTPS. +- Don't put sensitive user data in JWT claims. JWT payloads aren't encrypted. + +## Pass the token to DocSearch + +Fetch a token from your backend and pass it as `memory.userToken`: + +```js title="load-docsearch.js" +const response = await fetch('/api/agent-studio-token', { + credentials: 'include', +}); +const { userToken } = await response.json(); + +docsearch({ + container: '#docsearch', + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['docs'], + askAi: { + assistantId: 'YOUR_AGENT_ID', + memory: { + enabled: true, + userToken, + }, + }, +}); +``` + +Use the same `askAi.memory` object with React's `DocSearchAI`. + +When `userToken` is present, DocSearch sends it in the `X-Algolia-Secure-User-Token` request header. When it's absent, DocSearch omits the header. Don't use unscoped memory for a multi-user application. + +## `memory.enabled` + +> `type: boolean` | **optional** + +Controls whether DocSearch displays Agent Studio's built-in memory tool activity: + +- `algolia_memorize` displays that information was saved. +- `algolia_ponder` and `algolia_memory_search` display that memory was used. +- Memory tool errors aren't displayed. + +The default is `false`. + +This option doesn't enable memory in Agent Studio and doesn't create a user identity. Configure the feature on the agent and pass `userToken` for user isolation. DocSearch sends `userToken` when provided even if `enabled` is `false`. + +A custom entry in `askAi.tools` with the same memory tool name replaces the built-in memory rendering. + +See the [JavaScript package reference](/docs/packages/js/api-reference) or [React package reference](/docs/packages/react/api-reference) for the `Memory` configuration type. diff --git a/packages/website/docs/agent-studio/prompt-suggestions.mdx b/packages/website/docs/agent-studio/prompt-suggestions.mdx new file mode 100644 index 00000000..dc6ebb7e --- /dev/null +++ b/packages/website/docs/agent-studio/prompt-suggestions.mdx @@ -0,0 +1,69 @@ +--- +title: Configure prompt suggestions +description: Display suggested prompts for Agent Studio conversations. +--- + +DocSearch v5 can show questions in three places. Each source has a different purpose and configuration. + +- **Suggested questions** appear on the new-conversation screen. They come from published records for the agent in the fixed suggested-questions index. Configure them with `suggestedQuestions: true`. +- **Keyword prompt suggestions** appear while the user types in keyword search. They come from your Algolia prompt-suggestions index. Configure them with `promptSuggestions`. +- **Streamed follow-ups** appear below the latest completed answer. They come from `data-suggestions` streamed by Agent Studio. Configure suggestions on the agent. + +## Show suggested questions + +Enable curated starting questions with `suggestedQuestions`: + +```js title="docsearch.js" +askAi: { + assistantId: 'YOUR_AGENT_ID', + suggestedQuestions: true, +} +``` + +DocSearch queries the `algolia_ask_ai_suggested_questions` index for records where `state` is `published` and `assistantId` matches the configured agent. It requests up to three records. + +A suggested-question record has this shape, plus its Algolia `objectID`: + +```ts +{ + appId: string; + assistantId: string; + question: string; + locale?: string; + state: 'published'; + source: string; + order: number; +} +``` + +When a user selects one, DocSearch sends its `objectID` as `suggestedQuestionId` with the question. + +## Show prompt suggestions during keyword search + +Create an Algolia index whose records contain a `prompt` string, then configure its name: + +```js title="docsearch.js" +askAi: { + assistantId: 'YOUR_AGENT_ID', + promptSuggestions: { + indexName: 'docs_prompt_suggestions', + hitsPerPage: 3, + }, +} +``` + +As the user types, DocSearch searches this index with the entered query and retrieves only the `prompt` attribute. It places matching prompts after the action that asks the entered text directly. + +`hitsPerPage` defaults to `3`. The Docusaurus adapter requires a positive value. If this search fails, DocSearch keeps the direct Ask AI action and omits the suggestions. + +Selecting a prompt starts Agent Studio with that prompt. It doesn't send a `suggestedQuestionId`. + +## Show streamed follow-ups + +Configure contextual suggestions in the Agent Studio agent editor. See [write and configure agent prompts](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/dashboard#write-and-configure-agent-prompts). + +Agent Studio streams these follow-ups in a `data-suggestions` part. DocSearch renders its `suggestions` array below the latest answer only. Selecting one sends it as the next user message in the same conversation. + +There's no DocSearch `askAi` option for streamed follow-ups. If Agent Studio doesn't stream `data-suggestions`, DocSearch doesn't show them. + +See the [JavaScript package reference](/docs/packages/js/api-reference) and [React package reference](/docs/packages/react/api-reference) for the suggestion options and translation keys. diff --git a/packages/website/docs/agent-studio/tools.mdx b/packages/website/docs/agent-studio/tools.mdx new file mode 100644 index 00000000..0a88f7c1 --- /dev/null +++ b/packages/website/docs/agent-studio/tools.mdx @@ -0,0 +1,106 @@ +--- +title: Add tools +description: Extend Agent Studio with tools for custom actions and data. +--- + +Use tools to let your agent read live data or perform actions. Configure the tool and its input schema in Agent Studio, then add a matching entry to `askAi.tools` when DocSearch needs to run or render it. + +See [Agent Studio tools](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/overview) before exposing a tool to users. + +## Add a client-side tool + +The key in `tools` must match the tool name configured in Agent Studio. + +```tsx title="Search.tsx" +import { DocSearchAI, type ToolCalls } from '@docsearch/react'; + +const tools: ToolCalls = { + getAccountPlan: { + translations: { + callingToolText: 'Checking your account', + }, + render({ message: { input, output } }) { + const result = output as { plan?: string } | undefined; + return result?.plan ? `Account plan: ${result.plan}` : ''; + }, + async onToolCall({ input, addToolOutput }) { + const response = await fetch('/api/account-plan', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(input), + }); + + const output = await response.json(); + await addToolOutput({ output }); + }, + }, +}; + +export function Search() { + return ( + + ); +} +``` + +The JavaScript package accepts the same `askAi.tools` object. + +Every tool definition requires `render`. DocSearch calls it after output is available and passes both `input` and `output`. Return a string to show a result, or an empty string to show nothing. + +Add `onToolCall` for a tool that runs in the browser. It receives: + +- `input`: the arguments selected by the agent. Treat this value as untrusted and validate it. +- `toolCallId`: the current call ID. +- `toolName`: the configured tool name. +- `dynamic`: whether the streamed call was marked as dynamic, when provided. +- `addToolOutput`: the function that returns the result to the conversation. + +Call `addToolOutput({ output })` after your work finishes. DocSearch invokes `onToolCall` without waiting for its returned promise, so handle failures inside the callback. + +Keep browser tools within the signed-in user's permissions. Don't place service credentials in the tool definition. Call your backend for privileged work. See [client-side tool security](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/security). + +For React, define `tools` outside the component or memoize it. Recreating the object doesn't change behavior, but a stable object avoids rebuilding dependent configuration. + +## Render server-side or MCP tools + +If Agent Studio executes a tool, omit `onToolCall` and provide `render` under the streamed tool name. DocSearch uses the output returned by Agent Studio. + +```js title="tools.js" +const tools = { + get_release_status: { + render({ message: { output } }) { + const status = output?.status; + return status ? `Release status: ${status}` : ''; + }, + }, +}; +``` + +## Understand Algolia MCP search tools + +DocSearch recognizes these Agent Studio search tool names without a `tools` entry: + +- `algolia_search_index` +- Any name beginning with `algolia_search_index_` + +The recognized input includes `query`, `index`, optional `number_of_results`, and optional `facet_filters`. The output can include `hits`, `nbHits`, and `queryId`. + +DocSearch shows search progress and the query used by the tool. It combines consecutive completed search calls into one search summary when more than one call has a nonempty query. A non-search message part ends the group. + +You can add a matching `tools` entry to replace the built-in rendering for a search or memory tool. Your custom renderer takes precedence. + +To connect other MCP servers to an agent, see [MCP tools in Agent Studio](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/mcp-tools). See the [React package reference](/docs/packages/react/api-reference) for `ToolCalls` and `ToolDefinition`. + +## Use tools with Docusaurus + +Docusaurus removes functions while serializing theme configuration. The v5 adapter rejects `askAi.tools` and `sidePanel.tools` in `docusaurus.config`. Swizzle `@theme/SearchBar` and pass tools to the modal or Sidepanel from React instead. + +See the [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started) for the supported configuration. diff --git a/packages/website/docs/api.mdx b/packages/website/docs/api.mdx index 4693f750..ab339e00 100644 --- a/packages/website/docs/api.mdx +++ b/packages/website/docs/api.mdx @@ -1,882 +1,28 @@ --- -title: API Reference +title: API references +description: Browse API references for DocSearch packages and integrations. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import useBaseUrl from '@docusaurus/useBaseUrl'; +Choose the reference for the package in your application: - - +- [`@docsearch/js` API](/docs/packages/js/api-reference) +- [`@docsearch/react` API](/docs/packages/react/api-reference) +- [`@docsearch/modal` API](/docs/packages/modal/api) +- [`@docsearch/sidepanel` API](/docs/packages/sidepanel/api) +- [`@docsearch/sidepanel-js` API](/docs/packages/sidepanel-js/api) +- [`@docsearch/core` API](/docs/packages/core/api) +- [Docusaurus adapter configuration](/docs/packages/docusaurus-adapter/configuration-reference) + +For an end-to-end example, start with the [package overview](/docs/packages/overview). ## `container` -> `type: string | HTMLElement` | **required** +See the [`@docsearch/js` API](/docs/packages/js/api-reference#container) for the JavaScript container option. -The container for the DocSearch search box. You can either pass a [CSS selector][5] or an [Element][6]. If there are several containers matching the selector, DocSearch picks up the first one. +## Translations -## `environment` - -> `type: typeof window` | `default: window` | **optional** - -The environment in which your application is running. - -This is useful if you’re using DocSearch in a different context than window. - - - - -## `appId` - -> `type: string` | **required** - -Your Algolia application ID. - -## `apiKey` - -> `type: string` | **required** - -Your Algolia Search API key. - -## `indices` - -> `type: Array` | **required** - -The list of indices and their _optional_ `searchParameters` to be used for keyword search. - -[Algolia Search Parameters][7] - -:::tip - -The ordering matters in the list, as results are ordered based on `indices` order. - -::: - - - - -```js -docsearch({ - // ... - indices: ['YOUR_ALGOLIA_INDEX'], - // ... -}); -``` - -in case you want to use custom `searchParameters` for the index - -```js -docsearch({ - // ... - indices: [ - { - name: 'YOUR_ALGOLIA_INDEX', - searchParameters: { - facetFilters: ['language:en'], - // ... - }, - }, - ], - // ... -}); -``` - - - - - -```jsx - -``` - -in case you want to use custom `searchParameters` for the index - -```jsx - -``` - - - - -## `placeholder` - -> `type: string` | `default: "Search docs"` | **optional** - -The placeholder of the input of the DocSearch pop-up modal. Note: If you add a placeholder it will replace the dynamic placeholder based on askAi, It would be better to edit [translations](#translations) +See the [React API](/docs/packages/react/api-reference#translations) for the shared translation structure. ## `askAi` -> `type: AskAiObject` | `string` | **optional** - -Your Algolia Assistant ID. - - - - -```js -docsearch({ - // ... - askAi: 'YOUR_ALGOLIA_ASSISTANT_ID', - // ... -}); -``` - -or if you want to use different credentials for askAi and add search parameters - -```js -docsearch({ - // ... - askAi: { - indexName: 'ANOTHER_INDEX_NAME', - apiKey: 'ANOTHER_SEARCH_API_KEY', - appId: 'ANOTHER_APP_ID', - assistantId: 'YOUR_ALGOLIA_ASSISTANT_ID', - searchParameters: { - // Filtering parameters - facetFilters: ['language:en', 'version:latest'], - filters: 'type:content AND language:en', - - // Content control parameters - attributesToRetrieve: ['title', 'content', 'url'], - restrictSearchableAttributes: ['title', 'content'], - - // Deduplication - distinct: true, - }, - - // Enables/disables showing suggested questions on Ask AI's new conversation screen - // NOTE: Only available with version >= 4.3 - suggestedQuestions: true, - }, - // ... -}); -``` - - - - - -```jsx - -``` - -in case you want to use different credentials for askAi - -```jsx -= 4.3 - suggestedQuestions: true, - }} -/> -``` - - - - -:::tip[Ask AI supports these essential search parameters for optimal performance:] - -- **Filtering**: `facetFilters: ['type:content']` - Filter by language, version, or content type -- **Complex filtering**: `filters: 'type:content AND language:en'` - Apply complex filtering rules -- **Content control**: `attributesToRetrieve: ['title', 'content', 'url']` - Control which attributes are retrieved -- **Search scope**: `restrictSearchableAttributes: ['title', 'content']` - Limit search to specific fields -- **Deduplication**: `distinct: true` - Remove duplicate results - -These parameters provide the essential functionality for Ask AI while keeping the API simple and focused. - -::: - -## `agentStudio` - -> `type: boolean` | **optional** | **experimental** - -:::warning[Experimental] - -`agentStudio` is currently an experimental property. It is targeted to be stable in release `5.0.0`. - -::: - -If `agentStudio` is true, the Ask AI chat will use Algolia's [Agent Studio][12] as the chat backend instead of the Ask AI backend. Learn more on [Algolia Agent Studio Docs][13]. - -## `transformItems` - -> `type: function` | `default: items => items` | **optional** - -Receives the items from the search response, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them. - - - - -```js -docsearch({ - // ... - transformItems(items) { - return items.map((item) => ({ - ...item, - content: item.content.toUpperCase(), - })); - }, -}); -``` - - - - - -```jsx - { - return items.map((item) => ({ - ...item, - content: item.content.toUpperCase(), - })); - }} -/> -``` - - - - -## `hitComponent` - -> `type: ({ hit, children }, { html }) => JSX.Element | string | Function` | `default: Hit` | **optional** - -The component to display each item. Supports template patterns: - -- **HTML strings with html helper** (recommended for JS CDN): `({ hit, children }, { html }) => html...` -- **JSX templates** (for React/Preact): `({ hit, children }) =>
...
` -- **Function-based templates**: `(props) => string | JSX.Element | Function` - -You get access to the `hit` object which contains all the data for the search result, and `children` which is the default rendered content. - -See the [default implementation][8]. - - - - -```js -docsearch({ - // ... - hitComponent({ hit, children }, { html }) { - // Using HTML strings with html helper - return html` - -
πŸ”
-
${children}
-
- `; - }, -}); -``` - -
- - - -```jsx - { - // Using JSX templates - return ( - -
πŸ”
-
{children}
-
- ); - }} -/> -``` - -
-
- -## `transformSearchClient` - -> `type: function` | `default: DocSearchTransformClient => DocSearchTransformClient` | **optional** - -Useful for transforming the [Algolia Search Client][10], for example to [debounce search queries][9] - -## `disableUserPersonalization` - -> `type: boolean` | `default: false` | **optional** - -Disable saving recent searches and favorites to the local storage. - -## `initialQuery` - -> `type: string` | **optional** - -The search input initial query. - -## `navigator` - -> `type: Navigator` | **optional** - -An implementation of [Algolia Autocomplete][1]’s Navigator API to redirect the user when opening a link. - -Learn more on the [Navigator API][11] documentation. - -## `translations` - -> `type: Partial` | `default: docSearchTranslations` | **optional** - -Allow translations of any raw text and aria-labels present in the DocSearch button or modal components. - -
-docSearchTranslations -
- -```ts -const translations: DocSearchTranslations = { - button: { - buttonText: 'Search', - buttonAriaLabel: 'Search', - }, - modal: { - searchBox: { - clearButtonTitle: 'Clear', - clearButtonAriaLabel: 'Clear the query', - closeButtonText: 'Close', - closeButtonAriaLabel: 'Close', - placeholderText: undefined, // fallback: 'Search docs' or 'Search docs or ask AI a question' - placeholderTextAskAi: undefined, // fallback: 'Ask another question...' - placeholderTextAskAiStreaming: 'Answering...', - // can only be one of the following - // https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/enterkeyhint#value - enterKeyHint: 'search', - enterKeyHintAskAi: 'enter', - searchInputLabel: 'Search', - backToKeywordSearchButtonText: 'Back to keyword search', - backToKeywordSearchButtonAriaLabel: 'Back to keyword search', - newConversationPlaceholder: 'Ask a question', - conversationHistoryTitle: 'My conversation history', - startNewConversationText: 'Start a new conversation', - viewConversationHistoryText: 'Conversation history' - }, - startScreen: { - recentSearchesTitle: 'Recent', - noRecentSearchesText: 'No recent searches', - saveRecentSearchButtonTitle: 'Save this search', - removeRecentSearchButtonTitle: 'Remove this search from history', - favoriteSearchesTitle: 'Favorite', - removeFavoriteSearchButtonTitle: 'Remove this search from favorites', - recentConversationsTitle: 'Recent conversations', - removeRecentConversationButtonTitle: - 'Remove this conversation from history', - }, - errorScreen: { - titleText: 'Unable to fetch results', - helpText: 'You might want to check your network connection.', - }, - noResultsScreen: { - noResultsText: 'No results found for', - suggestedQueryText: 'Try searching for', - reportMissingResultsText: 'Believe this query should return results?', - reportMissingResultsLinkText: 'Let us know.', - }, - resultsScreen: { - askAiPlaceholder: 'Ask AI: ', - noResultsAskAiPlaceholder: 'Didn't find it in the docs? Ask AI to help: ', - }, - askAiScreen: { - disclaimerText: - 'Answers are generated with AI which can make mistakes. Verify responses.', - relatedSourcesText: 'Related sources', - thinkingText: 'Thinking...', - copyButtonText: 'Copy', - copyButtonCopiedText: 'Copied!', - copyButtonTitle: 'Copy', - likeButtonTitle: 'Like', - dislikeButtonTitle: 'Dislike', - thanksForFeedbackText: 'Thanks for your feedback!', - preToolCallText: 'Searching...', - duringToolCallText: 'Searching for ', - afterToolCallText: 'Searched for', - // If provided, these override the default rendering of aggregated tool calls: - aggregatedToolCallNode: undefined, // (queries: string[], onSearchQueryClick: (query: string) => void) => React.ReactNode - aggregatedToolCallText: undefined, // (queries: string[]) => { before?: string; separator?: string; lastSeparator?: string; after?: string } - // Text to show when user has stopped streaming a message - stoppedStreamingText: 'You stopped this response', - }, - footer: { - selectText: 'Select', - submitQuestionText: 'Submit question', - selectKeyAriaLabel: 'Enter key', - navigateText: 'Navigate', - navigateUpKeyAriaLabel: 'Arrow up', - navigateDownKeyAriaLabel: 'Arrow down', - closeText: 'Close', - backToSearchText: 'Back to search', - closeKeyAriaLabel: 'Escape key', - poweredByText: 'Powered by', - }, - newConversation: { - newConversationTitle: 'How can I help you today?', - newConversationDescription: 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.' - } - }, -}; -``` - -
-
- -## `getMissingResultsUrl` - -> `type: ({ query: string }) => string` | **optional** - -Function to return the URL of your documentation repository. - - - - -```js -docsearch({ - // ... - getMissingResultsUrl({ query }) { - return `https://github.com/algolia/docsearch/issues/new?title=${query}`; - }, -}); -``` - - - - - -```jsx - { - return `https://github.com/algolia/docsearch/issues/new?title=${query}`; - }} -/> -``` - - - - -When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property. - -
- No results screen with informative message -
- -## `keyboardShortcuts` - -> `type: KeyboardShortcuts` | **optional** - -Configuration for keyboard shortcuts that trigger the search modal. - -### Default behavior: - -- `Ctrl/Cmd+K` - Opens and closes the search modal -- `/` - Opens the search modal (doesn't close) - -### Interface: - -```typescript -interface KeyboardShortcuts { - 'Ctrl/Cmd+K'?: boolean; // default: true - '/'?: boolean; // default: true -} -``` - - - - -```js -// Default - all shortcuts enabled -docsearch({ - // ... -}); - -// Disable slash shortcut -docsearch({ - // ... - keyboardShortcuts: { '/': false }, -}); - -// Disable Ctrl/Cmd+K shortcut (also hides button hint) -docsearch({ - // ... - keyboardShortcuts: { 'Ctrl/Cmd+K': false }, -}); - -// Disable all keyboard shortcuts -docsearch({ - // ... - keyboardShortcuts: { 'Ctrl/Cmd+K': false, '/': false }, -}); -``` - - - - - -```jsx -{ - /* Default - all shortcuts enabled */ -} -; - -{ - /* Disable slash shortcut */ -} -; - -{ - /* Disable Ctrl/Cmd+K shortcut (also hides button hint) */ -} -; - -{ - /* Disable all keyboard shortcuts */ -} -; -``` - - - - -:::info[Keyboard Shortcut Behavior] - -- **Ctrl/Cmd+K**: Toggle shortcut that both opens and closes the modal -- **/**: Character shortcut that only opens the modal (prevents interference with search typing) -- **Escape**: Always works to close the modal regardless of Configuration - -::: - -## `resultsFooterComponent` - -> `type: ({ state }, { html }) => JSX.Element | string | Function` | **optional** - -The component to display below the search results. Supports template patterns: - -- **HTML strings with html helper** (recommended for JS CDN): `({ state }, { html }) => html...` -- **JSX templates** (for React/Preact): `({ state }) =>
...
` -- **Function-based templates**: `(props) => string | JSX.Element | Function` - -You get access to the [current state](https://github.com/algolia/autocomplete/blob/next/packages/autocomplete-core/src/types/AutocompleteState.ts) which allows you to retrieve the number of hits returned, the query etc. - - - - -```js -docsearch({ - // ... - resultsFooterComponent({ state }, { html }) { - // Using HTML strings with html helper - return html` - - `; - }, -}); -``` - - - - - -```jsx - { - // Using JSX templates - return ( - - ); - }} -/> -``` - - - - -## `maxResultsPerGroup` - -> `type: number` | **optional** - -The maximum number of results to display per search group. Default is 5. - -[You can find a working example without JSX in this sandbox](https://codesandbox.io/s/docsearch-v3-maxresultspergroup-without-jsx-ct9m22?file=/src/index.js) - - - - -```js -docsearch({ - // ... - maxResultsPerGroup: 7, -}); -``` - - - - - -## `recentSearchesLimit` - -> `type: number` | `default: 7` | **optional** - -The maximum number of recent searches that are stored for the user. Default is 7. - - - - -```js -docsearch({ - // ... - recentSearchesLimit: 12, - // ... -}); -``` - - - - - -```jsx - -``` - - - - -## `recentSearchesWithFavoritesLimit` - -> `type: number` | `default: 4` | **optional** - -The maximum number of recent searches that are stored when the user has favorited searches. Default is 4. - - - - -```js -docsearch({ - // ... - recentSearchesWithFavoritesLimit: 5, - // ... -}); -``` - - - - - -```jsx - -``` - - - - -## `portalContainer` (React-only) - -> `type: Element | DocumentFragment` | `default: document.body` | **optional** - -The element where the DocSearch modal will be portaled. Use this when you need the overlay to render in a custom DOM nodeβ€”for example when working inside a shadow root, a specific layout container, or a modal manager. When omitted, the modal portals to `document.body`. - -:::warning - -This prop only exists in `@docsearch/react`. If you are using **`@docsearch/js`**, use the [`container`](#container) option insteadβ€”the value you pass there is both the **mount point** of the search button _and_ the portal target for the modal. - -::: - - - - -```jsx -// assume you have a dedicated modal root in your html - diff --git a/packages/website/docs/crawler.mdx b/packages/website/docs/crawler.mdx index 6b5b28cf..d5c7907b 100644 --- a/packages/website/docs/crawler.mdx +++ b/packages/website/docs/crawler.mdx @@ -1,16 +1,17 @@ --- title: DocSearch x Algolia Crawler +description: Resolve common DocSearch crawler questions and migration tasks. --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -If you're not finding the answer to your question on this website, this page will help you. If you're still unsure, don't hesitate to connect with us on [Discord][1] or let our [support][3] team know. +Use this page to resolve common crawler questions. If you need more help, contact us on [Discord][1] or through [Algolia support][3]. -You can also read our [Crawler FAQ](https://www.algolia.com/doc/tools/crawler/troubleshooting/crawl-status/), to understand how it behaves: +For more troubleshooting guidance, read the [Crawler FAQ][4]: -- [One of my pages wasn't crawled](https://www.algolia.com/doc/tools/crawler/troubleshooting/extraction-issues/#a-page-wasnt-crawled) -- [Why are my pages skipped?](https://www.algolia.com/doc/tools/crawler/troubleshooting/fetching-issues/) +- [One of my pages wasn't crawled][5] +- [Why are my pages skipped?][6] For questions related to the DocSearch program, please see our [DocSearch program FAQ](/docs/docsearch-program). @@ -22,61 +23,61 @@ Crawls are scheduled at a random time once a week. You can [configure this sched This can happen when you have more than one URL pointing to the same content, for example with `./docs`, `./docs/` and `./docs/index.html`. -We recommend configuring canonical URLs on your website, you can read more on the ["Consolidate duplicate URLs" guide by Google](https://developers.google.com/search/docs/advanced/crawling/consolidate-duplicate-urls). +Configure canonical URLs on your website. For more information, read Google's [Consolidate duplicate URLs][7] guide. -Ultimately, it is possible to set set the [`exclusionPatterns`](https://www.algolia.com/doc/tools/crawler/apis/configuration/exclusion-patterns/) to all the patterns you want to exclude. +Use [`exclusionPatterns`][8] to exclude duplicate URL patterns. -## Are the [`docsearch-scraper`](https://github.com/algolia/docsearch-scraper) and [`docsearch-configs`](https://github.com/algolia/docsearch-configs) repository still maintained? +## Are the [`docsearch-scraper`][9] and [`docsearch-configs`][10] repositories still maintained? -We've deprecated our legacy infrastructure, but you can still use it to [run your own instance](/docs/legacy/run-your-own) and plug it to [DocSearch v3](/docs/v3/docsearch)! +The legacy scraper infrastructure is deprecated. You can still [run a legacy scraper instance][12] and use its index with the historical [DocSearch v3 UI][13]. For current frontend integrations, choose a [DocSearch v5 package][14]. The scraper or crawler version doesn't determine the frontend package version. -## How to migrate +## How do I migrate? -> Every owners should have received a migration email from Algolia with the details. If you were not part of the previous `index` owners, or the maintainer has changed, you can request access via [our support page](https://www.algolia.com/support/). +> Every owner should have received a migration email from Algolia with the details. If you were not part of the previous `index` owners, or the maintainer has changed, you can request access via [our support page](https://www.algolia.com/support/). -All the steps are detailed in the email you've received, but in order to use the new infrastructure you need to: +Use the migration email to complete these steps: - Join the Algolia application with the invite included in the email -- Update your frontend integration with the credentials received in the email. +- Update your frontend integration with the credentials received in the email. For v5, follow the [JavaScript][15] or [React][16] guide. - - -```js app.js -docsearch({ - container: '#docsearch', - appId: 'YOUR_NEW_ALGOLIA_APP_ID', - apiKey: 'YOUR_NEW_ALGOLIA_SEARCH_API_KEY', - indices: ['YOUR_INDEX_NAME'], // it does not change -}); -``` - - - -```jsx App.js +```jsx title="Search.tsx" ``` + + +```js title="search.js" +docsearch({ + container: '#docsearch', + appId: 'YOUR_NEW_ALGOLIA_APP_ID', + apiKey: 'YOUR_NEW_ALGOLIA_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], // The index name doesn't change. +}); +``` + + ## What should I do with my legacy config and credentials? -You can forget about them, we will do the cleaning once all of our users have migrated to the new infrastructure! +Use the credentials for your current Algolia application. Don't use legacy credentials for new frontend integrations. You should use [the dedicated web interface][2] to make any changes to your index. @@ -84,31 +85,31 @@ You should use [the dedicated web interface][2] to make any changes to your inde We did not remove access to the legacy DocSearch application (`BH4D9OD16A`) to give you the time to get familiar with our new infrastructure. `BH4D9OD16A` will remain available until the migration has been completed for all the DocSearch users. -## Search yield no results +## Search yields no results If your search does not yield any results, but there is no error in [your browser developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools), there might be an issue with your index. -Make sure that: +Check the following settings: -1. [Your Crawler config](/docs/record-extractor) matches your website structure +1. Confirm that [your crawler configuration][17] matches your website structure. -We provide [config templates](/docs/templates) for many website generators, but you can also use them as a base. To debug your selectors, we recommend using [the URL tester](/docs/manage-your-crawls/#url-tester). + Use a [configuration template][18] for your website generator as a starting point. Test your selectors with [the URL tester][19]. -2. Your index settings are up to date (you'll see a banner in [the search preview](/docs/manage-your-crawls/#search-preview) if not) +2. Confirm that your index settings are current. If they aren't, [the search preview][20] displays a banner. -The Crawler only applies `index settings` at index creation index, to keep the Algolia dashboard as the source of truth. If you have drastically changed your config, or moved to a website generator, we recommend you to delete your index from the Algolia dashboard before starting a new crawl. + The crawler applies `index settings` only when it creates an index, which keeps the Algolia dashboard as the source of truth. If you changed your configuration significantly or moved to a different website generator, delete the index from the Algolia dashboard before starting a new crawl. ## Can I delete my crawler? -No. Well, you can but once you do things will not work correctly. We automatically create a default crawler that is associated with your DocSearch application and deleting it with the intention of creating a new one will not work as expected. +Don't delete the default crawler associated with your DocSearch application. Creating a replacement might not preserve the program configuration. ## What if I delete my DocSearch Crawler? -The fastest way will be to connect with us on our [Discord](https://alg.li/discord). Alternatively, email us at the address below and we will get to it as soon as we can. +Contact us on [Discord][1] or email us at the address below. -## Can I use the Crawler on password protected sites? +## Can I use the crawler on password-protected sites? -The Crawler as used with DocSearch applications cannot be used for password protected sites that require a login. If you need this functionality, you need to utilize a regular Algolia plan https://www.algolia.com/pricing and add a crawler to it. Note that while it is free to add a pay-as-you-go crawler, the free tier does have limitations. +The crawler included with DocSearch applications can't access password-protected sites that require a login. To crawl these sites, choose an [Algolia plan][11] and add a crawler. Pay-as-you-go plans include a crawler, but the free tier has usage limits. ## Links related to the migration @@ -118,3 +119,20 @@ The Crawler as used with DocSearch applications cannot be used for password prot [1]: https://alg.li/discord [2]: https://dashboard.algolia.com/crawler [3]: https://support.algolia.com/ +[4]: https://www.algolia.com/doc/tools/crawler/troubleshooting/crawl-status/ +[5]: https://www.algolia.com/doc/tools/crawler/troubleshooting/extraction-issues/#a-page-wasnt-crawled +[6]: https://www.algolia.com/doc/tools/crawler/troubleshooting/fetching-issues/ +[7]: https://developers.google.com/search/docs/advanced/crawling/consolidate-duplicate-urls +[8]: https://www.algolia.com/doc/tools/crawler/apis/configuration/exclusion-patterns/ +[9]: https://github.com/algolia/docsearch-scraper +[10]: https://github.com/algolia/docsearch-configs +[11]: https://www.algolia.com/pricing +[12]: /docs/legacy/run-your-own +[13]: /docs/v3/docsearch +[14]: /docs/packages/overview +[15]: /docs/packages/js/getting-started +[16]: /docs/packages/react/getting-started +[17]: /docs/record-extractor +[18]: /docs/templates +[19]: /docs/manage-your-crawls/#url-tester +[20]: /docs/manage-your-crawls/#search-preview diff --git a/packages/website/docs/create-crawler.mdx b/packages/website/docs/create-crawler.mdx index 5e7c5124..f41544ae 100644 --- a/packages/website/docs/create-crawler.mdx +++ b/packages/website/docs/create-crawler.mdx @@ -1,17 +1,20 @@ --- -title: Create a New Crawler +title: Create a new crawler +description: Add, verify, and crawl a domain with the Algolia Crawler. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -# Create a New Crawler +# Create a new crawler :::info -New DocSearch apps created after **July 2nd, 2024** can now use the Algolia Crawler UI to set up and manage their crawls. This guide walks you through the process of adding your domain, verifying ownership, creating a crawler, and running your first test crawl. You can find the new Crawler UI at [dashboard.algolia.com/crawler](https://dashboard.algolia.com/crawler). -If you signed up before July 2nd, 2024, you can still use the Crawler UI, but creating and managing a Crawler is more streamlined for users who joined after that date. +DocSearch apps created after **July 2, 2024** can use the Algolia Crawler UI to set up and manage crawls. This guide covers adding your domain, verifying ownership, creating a crawler, and running your first test crawl. Open the Crawler UI at [dashboard.algolia.com/crawler](https://dashboard.algolia.com/crawler). + +If you signed up before July 2, 2024, you can still use the Crawler UI, but creating and managing a crawler is more streamlined for users who joined after that date. + +Learn more about the [Crawler interface](./crawler-configuration-visual). -Learn more about the [New Crawler UI/UX features](./crawler-configuration-visual). ::: ## Add domains @@ -30,35 +33,40 @@ Learn more about the [New Crawler UI/UX features](./crawler-configuration-visual /> -> **Note:** You must verify your domain within a 7-day grace period after adding it. Additionally, your domain must be approved for use by the DocSearch team before you can proceed with crawling. +> **Note:** Verify your domain within 7 days of adding it. The DocSearch team must also approve the domain before you can crawl it. ## Verify your domain You must verify ownership of each domain you want to crawl. The default method is email verification, but you can also use a meta tag, HTML file, robots.txt, or DNS record. ### Meta tag + 1. In the **Meta tag** tab, click **Copy** to copy the verification tag. 2. Add the tag to your site's `` section. 3. Publish your site and click **Verify now** in the Crawler dashboard. ### HTML file + 1. In the **HTML file** tab, click **Copy** to copy the verification file content. 2. Save it as a new HTML file and upload it to your web server. 3. Add the file’s URL in the dashboard and click **Verify now**. ### robots.txt + 1. In the **Robots.txt** tab, click **Copy** to copy the verification code. 2. Paste it into your site's `robots.txt` file. 3. Publish and click **Verify now**. ### DNS + 1. In the **DNS** tab, copy the provided DNS TXT record. 2. Add it to your DNS provider’s settings. 3. Click **Verify now** after the record propagates (may take up to 72 hours). ## Create a new crawler -Once your domain is verified and approved by our DocSearch team: +After you verify your domain and the DocSearch team approves it: + 1. Go to the **Crawler** page in the dashboard. 2. Click **New Crawler** and fill in: - **Crawler name** (descriptive) @@ -69,10 +77,12 @@ Once your domain is verified and approved by our DocSearch team: ## Run the test crawl -The initial crawl will visit up to 100 URLs to test access and extraction. You can monitor progress in the **Overview** page. After completion, review the extracted records in the Algolia dashboard. +The initial crawl visits up to 100 URLs to test access and extraction. Monitor its progress on the **Overview** page. After it finishes, review the extracted records in the Algolia dashboard. + +Creating a crawler doesn't install or select a DocSearch frontend version. After indexing, choose a [DocSearch v5 package](/docs/packages/overview) or [framework integration](/docs/integrations). ## Next steps - Edit your crawler configuration for scheduled crawls, inclusion/exclusion rules, and extraction settings. - Use the Crawler’s suggestions for further optimization. -- For more details, see the [official Algolia documentation](https://www.algolia.com/doc/tools/crawler/getting-started/create-crawler/). \ No newline at end of file +- For more details, see the [Algolia Crawler documentation](https://www.algolia.com/doc/tools/crawler/getting-started/create-crawler/). diff --git a/packages/website/docs/docsearch-program.md b/packages/website/docs/docsearch-program.md index 9fe83877..53ff077e 100644 --- a/packages/website/docs/docsearch-program.md +++ b/packages/website/docs/docsearch-program.md @@ -1,96 +1,90 @@ --- title: DocSearch program +description: Learn about DocSearch program eligibility, costs, data, and support. --- -If you're not finding the answer to your question on this website, this page will help you. If you're still unsure, don't hesitate to connect with us on [Discord][1] or let our [support][4] team know. +Use this page to learn about the DocSearch program. If you need more help, contact us on [Discord][1] or through [Algolia support][4]. -For questions related to the DocSearch x Algolia Crawler, please see our [Crawler FAQ](/docs/crawler). +For questions about the DocSearch crawler, see the [Crawler FAQ][5]. ## What do I need to install on my side? -You just need to [implement DocSearch in your frontend](/docs/docsearch) with the credentials received by email when your application has been deployed. +After your content is indexed, add a [DocSearch v5 frontend package][19] with the application ID, Search API key, and index name from your Algolia application. -DocSearch leverages the [Algolia Crawler](https://www.algolia.com/products/search-and-discovery/crawler/), which offers a web [interface](https://dashboard.algolia.com/crawler) to create, monitor, edit, start your Crawlers. If you have any questions regarding it, please see our [Crawler FAQ](/docs/crawler). +DocSearch uses the [Algolia Crawler][6] to index your content. Use the [Crawler interface][7] to create, monitor, edit, and start crawlers. For crawler questions, see the [Crawler FAQ][5]. Crawler configuration and frontend package versions are independent. ## How much does it cost? -It's free! +The DocSearch program is free. -We know that paying for search infrastructure is a cost not all open source projects can afford. That's why we decided to keep DocSearch free for everyone. All we ask in exchange is that you keep the "Search by [Algolia][2]" logo displayed next to the search results. +Search infrastructure can be costly for open source projects, so the DocSearch program is free. In exchange, keep the "Search by [Algolia][2]" logo next to the search results. -If this is not possible for you, you're free to [open your own Algolia account](https://www.algolia.com/pricing) and run [DocSearch on your own][3] without this limitation. In that case, though, depending on the size of your documentation, you might need a paid account (free accounts can hold as much as 10k records). +If you can't display the logo, [create an Algolia account][8] and run [DocSearch on your own][3]. Depending on the size of your documentation, you might need a paid plan. Free plans can hold up to 10,000 records. ## What data are you collecting? -We save the data we extract from your website markup, which we put in a custom JSON format instead of HTML. This is the data we put in the Algolia DocSearch index. The selectors in your config define what data to scrape. +We extract data from your website markup and store it in a custom JSON format in your Algolia DocSearch index. The selectors in your crawler configuration determine what data to extract. -As the website owner, we also give you access to your own Algolia application. This will let you see how your website is indexed in Algolia, detailed analytics about the anonymized searches in your website, team managements, and more! +As the website owner, you can access your Algolia application to review indexed data, analyze anonymized searches, and manage your team. ## Where is my data hosted? -We host the DocSearch data on Algolia's servers, with replications around the globe. You can find more details about the actual [server specs here](https://www.algolia.com/doc/guides/infrastructure/servers/), and more complete information in our [privacy policy](https://www.algolia.com/policies/privacy). +We host DocSearch data on Algolia servers with replicas around the world. For more information, see the [Algolia infrastructure documentation][9] and [privacy policy][10]. ## How do I upgrade my DocSearch app? -Depending on what you are looking for you have a few options! +Choose an option based on your goal. ### Upgrade #1: I want a specific feature, like Rules, added to my existing DocSearch application -[Reach out to us](https://algolia.com/support) and we may be able to help! +[Contact Algolia support][4] to discuss your requirements. ### Upgrade #2: I want to remove the Algolia logo -This would disqualify you from the free DocSearch program. We do offer an open-source -[legacy version](https://docsearch.algolia.com/docs/legacy/run-your-own) of the DocSearch Crawler that you can use and -host yourself or you can use our [API clients](https://www.algolia.com/doc/api-client/getting-started/install/javascript/?client=javascript) but you will need to use a new Algolia application and pay for its usage. +Removing the logo makes the project ineligible for the free DocSearch program. Instead, host the open source [legacy DocSearch crawler][3] or use an [Algolia API client][11]. Both options require a new Algolia application, and usage charges may apply. ### Upgrade #3: Algolia is awesome, I want to use it for my whole site -That's awesome! Please reach out to our [sales team](https://www.algolia.com/contactus/) -who can help you figure out the right plan for you. Once you have your new application -created you can simply copy and paste [your Crawler config](https://docsearch.algolia.com/docs/templates) into your new application's -Crawler. +Contact the [Algolia sales team][12] to choose a plan. After creating your application, adapt a [crawler configuration template][20] for the new crawler. ## Can I use DocSearch on non-doc pages? -The free DocSearch we provide will **only** crawl open-source projects documentation pages or technical blogs. To use it on other parts of your website, you'll need to create your own Algolia account and either: +The free DocSearch program crawls only documentation pages for open source projects and technical blogs. To index other parts of your website, create an Algolia account and choose one of these options: - Run the [DocSearch crawler][3] on your own -- Use one of our other [framework integrations or API clients](https://www.algolia.com/doc/api-client/getting-started/install/javascript/?client=javascript) +- Use a [DocSearch frontend package][19], a supported [framework integration][21], or an [Algolia API client][11] ## Can you index code samples? Yes, but we do not recommend it. -Code samples are a great way for humans to understand how people use a specific method. It often requires boilerplate code though, repeated across examples, which adds noise to the results. +Code samples can help users understand a method, but repeated boilerplate adds noise to search results. ## A documentation website I like does not use DocSearch. What can I do? -We'd love to help! - -If one of your favorite tool documentation websites is missing DocSearch, we encourage you to file an issue in their repository explaining how DocSearch could help. Feel free to [let us know on Discord][1] as well and we'll provide all the help we can. +If a documentation website does not use DocSearch, file an issue in its repository that explains how DocSearch could help. You can also [contact us on Discord][1]. ## How did we build this website? -We build this website with [Docusaurus v2](https://docusaurus.io/). We were helped by a great man who inspired us a lot, Endi. We want [to pay a tribute to this exceptional human being that will be always part of the DocSearch project](https://docusaurus.io/blog/2020/01/07/tribute-to-endi). Rest in peace mate! +We built this website with [Docusaurus][13]. Endi helped inspire the project. Read our [tribute to Endi][14]. ## Can I share the `apiKey` in my repo? -The `apiKey` the DocSearch team provides is [a search-only key](https://www.algolia.com/doc/guides/security/api-keys/#search-only-api-key) and can be safely shared publicly. You can track it in your version control system (e.g. git). If you are running the scraper on your own, please make sure to create a search-only key and [do not share your Admin key](https://www.algolia.com/doc/guides/security/api-keys/#admin-api-key). +The `apiKey` from the DocSearch team is a [search-only API key][15], so you can share it publicly and track it in version control. If you run the scraper yourself, create a search-only key and [don't share your Admin API key][16]. ## Why is the email API key different in the dashboard? -Every Algolia app comes with a default "Search API Key" which can be seen in the dashboard. That key allow you to list indices, settings, and search on **every** index owned by your application. In the case of a DocSearch application, in your acceptance email we provide a search **ONLY** API key scoped to only your DocSearch index. If for any reason you need to recover the API key sent in the email, just connect with our [support](https://algolia.com/support) team. +Every Algolia application has a default "Search API Key" in the dashboard. That key lets you list indices, retrieve settings, and search every index in your application. For DocSearch applications, the acceptance email includes a search-only API key scoped to your DocSearch index. To recover this key, contact [Algolia support][4]. ## How do I rotate my API keys? -Please reach out to our [support](https://algolia.com/support) team. +Contact [Algolia support][4]. ## Can I have multiple projects under the same Algolia application? -We recommend having a single Algolia application per project. Please [apply](https://dashboard.algolia.com/users/sign_up?selected_plan=docsearch&utm_source=docsearch.algolia.com&utm_medium=referral&utm_campaign=docsearch&utm_content=apply) if you'd like to use DocSearch in an other project of yours. +Use one Algolia application per project. [Apply to the DocSearch program][17] for each additional project. -### Why ? +### Why? The information of the initially applied project is used everywhere when we deploy your app: @@ -99,13 +93,13 @@ The information of the initially applied project is used everywhere when we depl - The indices we generate - The allowed domains of your Crawler -This allow us to easily scope issues when reaching out for support. +This information helps us scope support requests to the correct project. ## Support :::caution -Please make sure to **first read the documentation before reaching out**. +Before contacting support, read the relevant documentation. Here are some links to help you: @@ -114,18 +108,35 @@ Here are some links to help you: - [The DocSearch FAQ](/docs/docsearch-program) - [The Algolia documentation](https://www.algolia.com/doc/) -You can also take a look at [the Algolia academy](https://academy.algolia.com/trainings) to understand more about Algolia. +Visit [Algolia Academy][18] to learn more about Algolia. ::: -Please be informed that while Algolia does not provide support for DocSearch itself, we can support requests for the following products: +Algolia doesn't provide support for the DocSearch UI library, but support is available for these products: -- The Algolia Crawler, reach out [via the support page](https://algolia.com/support). -- The Algolia Dashboard, reach out [via the support page](https://algolia.com/support). +- Contact [Algolia support][4] for the Algolia Crawler. +- Contact [Algolia support][4] for the Algolia dashboard. -For any issue related to [the DocSearch UI library](https://github.com/algolia/docsearch), please open a [GitHub issues](https://github.com/algolia/docsearch/issues). +For any issue related to [the DocSearch UI library](https://github.com/algolia/docsearch), please open a [GitHub issue](https://github.com/algolia/docsearch/issues). [1]: https://alg.li/discord [2]: https://www.algolia.com/ [3]: /docs/legacy/run-your-own [4]: https://support.algolia.com/ +[5]: /docs/crawler +[6]: https://www.algolia.com/products/search-and-discovery/crawler/ +[7]: https://dashboard.algolia.com/crawler +[8]: https://www.algolia.com/pricing +[9]: https://www.algolia.com/doc/guides/infrastructure/servers/ +[10]: https://www.algolia.com/policies/privacy +[11]: https://www.algolia.com/doc/api-client/getting-started/install/javascript/?client=javascript +[12]: https://www.algolia.com/contactus/ +[13]: https://docusaurus.io/ +[14]: https://docusaurus.io/blog/2020/01/07/tribute-to-endi +[15]: https://www.algolia.com/doc/guides/security/api-keys/#search-only-api-key +[16]: https://www.algolia.com/doc/guides/security/api-keys/#admin-api-key +[17]: https://dashboard.algolia.com/users/sign_up?selected_plan=docsearch&utm_source=docsearch.algolia.com&utm_medium=referral&utm_campaign=docsearch&utm_content=apply +[18]: https://academy.algolia.com/trainings +[19]: /docs/packages/overview +[20]: /docs/templates +[21]: /docs/integrations diff --git a/packages/website/docs/docsearch.mdx b/packages/website/docs/docsearch.mdx index e64f2d2d..9d3487f5 100644 --- a/packages/website/docs/docsearch.mdx +++ b/packages/website/docs/docsearch.mdx @@ -1,402 +1,19 @@ --- -title: Getting Started with v5 +title: Get started with DocSearch +description: Set up DocSearch keyword search or Agent Studio answers. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +DocSearch v5 provides separate packages for JavaScript, React, composable interfaces, and framework integrations. -## Introduction +Start with the [package overview](/docs/packages/overview) to choose an integration: -DocSearch v5 provides a significant upgrade over previous versions, offering enhanced accessibility, responsiveness, and an improved search experience for your documentation. Built on [Algolia Autocomplete][1], DocSearch v5 ensures a seamless integration trusted by leading documentation sites worldwide. +- Use [`@docsearch/js`](/docs/packages/js/getting-started) for a JavaScript application. +- Use [`@docsearch/react`](/docs/packages/react/getting-started) for a React application. +- Use the [Docusaurus adapter](/docs/packages/docusaurus-adapter/getting-started) for a Docusaurus site. +- Use the [Composable API](/docs/composable-api) to control the React interface. + +To upgrade an existing integration, follow [Migrating from v4](/docs/migrating-from-v4). ## Installation -> Looking for the Composable API documentation? You can find it [here][17]. - -DocSearch packages are available on the [npm registry][10]. - -### Docusaurus users - -If your docs site is powered by Docusaurus, use [`@docsearch/docusaurus-adapter`](/docs/docusaurus-adapter) for the latest DocSearch features (including new Ask AI capabilities such as sidepanel support), while keeping `@docusaurus/preset-classic`. - - - - -```bash -npm install @docsearch/js@5 -``` - -### Without package manager - -Include CSS in your website's `` - -```html - -``` - -And the JavaScript at the end of your ``: - -```html - -``` - - - - -```bash -bun add @docsearch/react@5 -# or -npm install @docsearch/react@5 -``` - -### Without package manager - -Include CSS in your website's ``: - -```html - -``` - -And the JavaScript at the end of your ``: - -```html - -``` - - - - - -### Optimize first query performance - -Enhance your users' first search experience by using `preconnect`, see [Performance optimization](#preconnect) below - -## Implementation - - - - -DocSearch requires a dedicated container in your HTML - -```html -
-``` - -Initialize DocSearch by passing your container: - -```js app.js -import docsearch from '@docsearch/js'; - -import '@docsearch/css'; - -docsearch({ - container: '#docsearch', - appId: 'YOUR_APP_ID', - indices: [{ name: 'YOUR_INDEX_NAME' }], - apiKey: 'YOUR_SEARCH_API_KEY', -}); -``` - -DocSearch generates an accessible, fully-functional search input for you automatically. - -
- - - -Integrating DocSearch into your React app is straightforward: - -```jsx App.js -import { DocSearch } from '@docsearch/react'; - -import '@docsearch/css'; - -function App() { - return ( - - ); -} - -export default App; -``` - -DocSearch generates a fully accessible search input out-of-the-box. - - - -
- -### Quick Testing (without credentials) - -If you'd like to test DocSearch immediately without your own credentials, use our demo configuration: - - - - -```js -docsearch({ - appId: 'PMZUYBQDAK', - apiKey: '24b09689d5b4223813d9b8e48563c8f6', - indices: [{ name: 'docsearch' }], - askAi: { - assistantId: 'askAIDemo', - }, -}); -``` - - - - - -```jsx - -``` - - - - - -Or use our new dedicated [DocSearch Playground](https://community.algolia.com/docsearch-playground/) - -### Using DocSearch with Ask AI - -DocSearch v5 supports Ask AI through Algolia Agent Studio. Ask AI enhances the user experience by providing contextually relevant and intelligent responses directly from your documentation. - -To enable Ask AI, add your Agent Studio assistant ID: - - - - -```js -docsearch({ - appId: 'YOUR_APP_ID', - indices: [{ name: 'YOUR_INDEX_NAME' }], - apiKey: 'YOUR_SEARCH_API_KEY', - askAi: { - assistantId: 'YOUR_AGENT_STUDIO_ASSISTANT_ID', - suggestedQuestions: true, - }, -}); -``` - - - - -```jsx - -``` - - - - -- Configure the content indices the assistant can search in Agent Studio. -- The suggested questions feature is controlled on the [Dashboard](https://dashboard.algolia.com) in the Ask AI section. - -### Filtering search results - -#### Keyword search - -If your website uses [DocSearch meta tags][13] or if you've added [custom variables to your config][14], you'll be able to use the [`facetFilters`][16] option to scope your search results to a [`facet`][15] - -This is useful to limit the scope of the search to one language or one version. - - - - -```js -docsearch({ - indices: [ - { - name: 'YOUR_INDEX_NAME', - searchParameters: { - facetFilters: ['language:en', 'version:1.0.0'], - }, - }, - ], -}); -``` - - - - - -```jsx - -``` - - - - - -#### Ask AI - -Filtering also applies when using Ask AI. This is useful to limit the scope of the LLM's search to only relevant results. - -:::info -We recommend using the `facetFilters` option when using Ask AI with multiple languages or any multi-faceted index. -::: - - - -```js -docsearch({ - askAi: { - assistantId: 'YOUR_AGENT_STUDIO_ASSISTANT_ID', - searchParameters: { - 'YOUR_MARKDOWN_INDEX': { - facetFilters: ['language:en', 'version:1.0.0'], - }, - }, - }, -}); -``` - - - -```jsx - -``` - - - - -:::tip -You can use `facetFilters: ['type:content']` to ensure Ask AI only uses records where the `type` attribute is `content` (i.e., only records that actually have content). This is useful if your index contains records for navigation, metadata, or other non-content types. -::: - -### Sending events - -You can send search events to your DocSearch index by passing in the `insights` parameter when creating your DocSearch instance. - - - - -```diff -docsearch({ - // other options -+ insights: true, -}); -``` - - - - - -```diff - -``` - - - - - -## Performance optimization - -### Preconnect - -Improve the loading speed of your initial search request by adding this snippet into your website's `` section: - -```html - -``` - -This helps the browser establish a quick connection with Algolia, enhancing user experience, especially on mobile devices. - -[1]: https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/ -[2]: https://github.com/algolia/docsearch/ -[3]: https://github.com/algolia/docsearch/tree/master -[4]: /docs/legacy/dropdown -[5]: /docs/integrations -[6]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors -[7]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement -[8]: https://codesandbox.io/s/docsearch-js-v3-playground-z9oxj -[9]: https://codesandbox.io/s/docsearch-react-v3-playground-619yg -[10]: https://www.npmjs.com/ -[11]: /docs/api#container -[12]: /docs/api -[13]: /docs/required-configuration#introduce-global-information-as-meta-tags -[14]: /docs/record-extractor#indexing-content-for-faceting -[15]: https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/ -[16]: https://www.algolia.com/doc/guides/managing-results/refine-results/filtering/#facetfilters -[17]: /docs/composable-api +Install instructions depend on your package. Open the package guide above for commands and required styles. diff --git a/packages/website/docs/docusaurus-adapter.mdx b/packages/website/docs/docusaurus-adapter.mdx index c9e76644..fe07c9d4 100644 --- a/packages/website/docs/docusaurus-adapter.mdx +++ b/packages/website/docs/docusaurus-adapter.mdx @@ -1,118 +1,10 @@ --- -title: Docusaurus Adapter (Recommended) +title: Docusaurus adapter +description: Configure DocSearch for a Docusaurus documentation site. --- -If you use Docusaurus, install and configure `@docsearch/docusaurus-adapter` to get the latest DocSearch features on your current Docusaurus version. +Use `@docsearch/docusaurus-adapter` to add DocSearch v5 to a Docusaurus site. -## Why this adapter exists - -Docusaurus ships an excellent built-in Algolia integration (`@docusaurus/theme-search-algolia`), but Docusaurus (Meta-maintained) and DocSearch don't always release on the same cadence. - -The DocSearch adapter lets us ship new DocSearch features (including Ask AI sidepanel support) without forcing users to wait for a Docusaurus integration update. - -In practice, this means: - -- Faster access to new DocSearch capabilities. -- Better compatibility for Ask AI + sidepanel features. -- A dedicated search integration path maintained in the DocSearch project. - -## Install - -```bash -yarn add @docsearch/docusaurus-adapter -# or -npm install @docsearch/docusaurus-adapter -``` - -## Configuration - -Keep `@docusaurus/preset-classic`, add the adapter plugin, and configure search under `themeConfig.docsearch`: - -```js title="docusaurus.config.mjs" -export default { - plugins: ['@docsearch/docusaurus-adapter'], - themeConfig: { - docsearch: { - appId: 'YOUR_APP_ID', - apiKey: 'YOUR_SEARCH_API_KEY', - indices: [{ name: 'YOUR_INDEX_NAME' }], - askAi: { - assistantId: 'YOUR_ASSISTANT_ID', - }, - sidePanel: true, - contextualSearch: true, - searchPage: { path: 'search' }, - }, - }, -}; -``` - -## Configuration Key - -Use `themeConfig.docsearch` as the only adapter configuration key. - -The adapter doesn't read `themeConfig.algolia`, which avoids built-in Docusaurus search-theme validation conflicts when you want newer DocSearch options like Agent Studio and the sidepanel. - -### Client Side Tools - -Docusaurus serializes `themeConfig` for the browser and removes function values. Configure `askAi.tools` and `sidePanel.tools` in a swizzled `@theme/SearchBar` component instead of `themeConfig.docsearch`: - -```tsx title="src/theme/SearchBar/index.tsx" -import type { ToolCalls } from '@docsearch/react'; -import SearchBar from '@theme-original/SearchBar'; -import type { ReactNode } from 'react'; - -const tools: ToolCalls = { - logMessage: { - render: () => 'Tool completed.', - }, -}; - -export default function SearchBarWithTools(): ReactNode { - return ( - - ); -} -``` - -Pass `tools` through `askAi` to enable them in the modal, `sidePanel` to enable them in the side panel, or both for both interfaces. Include any other Ask AI or side-panel options when overriding the corresponding object. - -## Search Page - -The adapter ships a full search page (enabled by default at `/search`) with faceted filtering, an accessible "Load more" pagination, recent searches, and "Browse by section" shortcuts. Disable it with `searchPage: false`, or change its path with `searchPage: { path: 'search' }`. - -### Facets - -By default the sidebar exposes a single "Section" facet built from the `hierarchy.lvl0` attribute. Configure your own refinement lists with `searchPage.facets`: - -```js title="docusaurus.config.mjs" -export default { - themeConfig: { - docsearch: { - // ... - searchPage: { - path: 'search', - facets: [ - { attribute: 'hierarchy.lvl0', label: 'Section' }, - { attribute: 'type', label: 'Type' }, - ], - }, - }, - }, -}; -``` - -Each facet is a disjunctive (OR) refinement list. Active refinements are reflected in the URL so filtered searches are shareable. - -### Analytics - -When `insights: true` is set (the same flag used by the modal), the search page enables Algolia click analytics and sends `clickedObjectIDsAfterSearch` events when a result is opened, so full-page searches feed relevance tuning just like the modal. - -## Customizing Search UI (SearchBar/SearchPage) - -If you want to customize search behavior or UI, customize the adapter theme components (`@theme/SearchBar` and `@theme/SearchPage`) from the adapter integration path. - -This keeps your customization aligned with DocSearch feature updates and avoids coupling to the built-in Docusaurus Algolia theme implementation. +- [Install the adapter](/docs/packages/docusaurus-adapter/getting-started). +- [Configure the adapter](/docs/packages/docusaurus-adapter/configuration-reference). +- [Migrate a v4 configuration](/docs/packages/docusaurus-adapter/migrating-from-v4). diff --git a/packages/website/docs/examples.mdx b/packages/website/docs/examples.mdx index 256d29e2..c8d90727 100644 --- a/packages/website/docs/examples.mdx +++ b/packages/website/docs/examples.mdx @@ -1,358 +1,14 @@ --- -id: examples -title: Examples and extensions -description: live demos showing how to use and extend docsearch beyond documentation-only use cases. +title: Examples +description: Explore DocSearch implementation examples and common configurations. --- -import { DocSearch } from '@docsearch/react'; -import '@docsearch/css/dist/style.css'; +Use these guides for production-ready examples: -> These examples are interactive. click a button to open the modal and try a query. +- [React examples](/docs/packages/react/examples) +- [Composable API](/docs/composable-api) +- [Hybrid Mode](/docs/hybrid-mode) +- [Agent Studio tools](/docs/agent-studio/tools) +- [Docusaurus adapter](/docs/packages/docusaurus-adapter/getting-started) -## Basic keyword search - -Use the default experience with your index credentials. this works great for typical docs, blogs, and any site with a docsearch-compliant index. - -```jsx - -``` - - - ---- - -## Ask AI: ai-assisted answers - -Add algolia askai to get synthesized answers grounded in your indexed content. you can scope the llm context using `searchParameters` like `facetFilters`, `filters`, `attributesToRetrieve`,`restrictSearchableAttributes`, and `distinct`. - -```jsx - -``` - - - ---- - -## Custom hit rendering (`hitComponent`) - -Replace the default hit markup to match your brand and layout. below is a minimal example of a custom component. - -```jsx -function CustomHit({ hit }) { - // render a compact, branded hit card - return ( - -
-
- {hit.type?.toUpperCase?.() || 'DOC'} -
-
-
- {hit.hierarchy?.lvl1 || 'untitled'} -
- {hit.hierarchy?.lvl2 && ( -
- {hit.hierarchy.lvl2} -
- )} - {hit.content && ( -
{hit.content}
- )} -
-
-
- ); -} - -; -``` - - { - // render a compact, branded hit card - return ( - -
-
- {hit.type?.toUpperCase?.() || 'DOC'} -
-
-
- {hit.hierarchy?.lvl1 || 'untitled'} -
- {hit.hierarchy?.lvl2 && ( -
- {hit.hierarchy.lvl2} -
- )} - {hit.content && ( -
{hit.content}
- )} -
-
-
- ); - }} - insights={true} - translations={{ button: { buttonText: 'custom hits (demo)' } }} -/> - ---- - -## Opening links in new tabs - -By default, DocSearch opens search result links in the current window. If you want results to open in new tabs, you need to use both a custom `hitComponent` and the `navigator` prop to handle both click and keyboard navigation consistently. - -```jsx -// Custom hit component with target="_blank" -function HitWithNewTab({ hit, children }) { - return ( - - {children} - - ); -} - -// Navigator configuration to handle keyboard navigation -const newTabNavigator = { - navigate: ({ itemUrl }) => window.open(itemUrl, '_blank'), - navigateNewTab: ({ itemUrl }) => window.open(itemUrl, '_blank'), - navigateNewWindow: ({ itemUrl }) => window.open(itemUrl, '_blank'), -}; - -; -``` - - ( - - {children} - - )} - navigator={{ - navigate: ({ itemUrl }) => window.open(itemUrl, '_blank'), - navigateNewTab: ({ itemUrl }) => window.open(itemUrl, '_blank'), - navigateNewWindow: ({ itemUrl }) => window.open(itemUrl, '_blank'), - }} - insights={true} - translations={{ button: { buttonText: 'open in new tabs (demo)' } }} -/> - -

- -:::warning -**Note**: Using only `hitComponent` with `target="_blank"` will work for mouse clicks, but keyboard navigation (arrows + Enter) requires the `navigator` prop to consistently open links in new tabs. -::: - ---- - -## Bring-your-own-data shape with `transformItems` - -Docsearch is not limited to docsearch-like records. use `transformItems` to adapt any record shape into the internal structure docsearch expects. this lets you build search for apps, help centers, changelogs, or any custom content. - -the snippet below maps a non-standard record to the internal format. try it live: - -```jsx - - items.map((item) => ({ - objectID: item.objectID, - content: item.content ?? '', - url: item.domain + item.path, - hierarchy: { - lvl0: (item.breadcrumb || []).join(' > ') ?? '', - lvl1: item.h1 ?? '', - lvl2: item.h2 ?? '', - lvl3: null, - lvl4: null, - lvl5: null, - lvl6: null, - }, - url_without_anchor: item.domain + item.path, - type: 'content', - anchor: null, - _highlightResult: item._highlightResult, - _snippetResult: item._snippetResult, - })) - } - insights={true} - translations={{ button: { buttonText: 'transform items (demo)' } }} -/> -``` - - - items.map((item) => ({ - objectID: item.objectID, - content: item.content ?? '', - url: item.domain + item.path, - hierarchy: { - lvl0: (item.breadcrumb || []).join(' > ') ?? '', - lvl1: item.h1 ?? '', - lvl2: item.h2 ?? '', - lvl3: null, - lvl4: null, - lvl5: null, - lvl6: null, - }, - url_without_anchor: item.domain + item.path, - type: 'content', - anchor: null, - _highlightResult: item._highlightResult, - _snippetResult: item._snippetResult, - })) - } - insights={true} - translations={{ button: { buttonText: 'transform items (demo)' } }} -/> - ---- - -## Tips - -- **Instrumentation**: enable `insights` to send usage analytics and iterate on relevance. -- **Ask AI scoping**: use `facetFilters`, `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct` to control ai context and improve answer quality. -- **Customization**: use `hitComponent`, `transformItems`, and `translations` to make docsearch feel native to any product surface. +For JavaScript setup examples, see [Get started with `@docsearch/js`](/docs/packages/js/getting-started). diff --git a/packages/website/docs/how-does-it-work.mdx b/packages/website/docs/how-does-it-work.mdx index 3cc42427..5424321e 100644 --- a/packages/website/docs/how-does-it-work.mdx +++ b/packages/website/docs/how-does-it-work.mdx @@ -1,10 +1,11 @@ --- title: How does it work? +description: Learn how DocSearch crawls, indexes, and serves documentation content. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -Getting up and ready with DocSearch is a straightforward process that requires three steps: you apply, we configure the crawler and the Algolia app for you, and you integrate our UI in your frontend. You only need to copy and paste a JavaScript snippet. +DocSearch setup has three parts: join the DocSearch program, index your content, and add a frontend package or framework integration. + + +### React + +Install the connected React packages and CSS: + + + + +```bash +npm install @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Render `DocSearchAskAiModal` and `Sidepanel` under the same `DocSearch` provider. The Sidepanel registers itself with the provider after mount. From then on, desktop Ask AI actions move to the Sidepanel automatically. + +```tsx title="HybridSearch.tsx" +import { DocSearch } from '@docsearch/core'; +import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal'; +import { Sidepanel, SidepanelButton } from '@docsearch/sidepanel'; +import type { JSX } from 'react'; + +import '@docsearch/css/dist/style.css'; +import '@docsearch/css/dist/sidepanel.css'; + +interface HybridSearchProps { + appId: string; + apiKey: string; + keywordIndexName: string; + askAiIndexName: string; + assistantId: string; + onReady?: () => void; + onOpen?: () => void; + onClose?: () => void; + onSidepanelOpen?: () => void; + onSidepanelClose?: () => void; +} + +export function HybridSearch({ + appId, + apiKey, + keywordIndexName, + askAiIndexName, + assistantId, + onReady, + onOpen, + onClose, + onSidepanelOpen, + onSidepanelClose, +}: HybridSearchProps): JSX.Element { + return ( + + + + + + + + ); +} +``` + +`SidepanelButton` gives users a direct Ask AI entry point. You can omit it without disabling hybrid handoff. Keep `Sidepanel` mounted so it can register before a user submits an Ask AI request. + +Use the same index name for `keywordIndexName` and `askAiIndexName` when one index serves both experiences. Pass different names when your Agent Studio setup uses a dedicated content index. + +#### React lifecycle callbacks + +Put lifecycle callbacks on `DocSearch` so they observe the shared state. + +During the automatic React handoff, the state changes directly from `modal-askai` to `sidepanel`. That transition calls `onSidepanelOpen`; it doesn't call `onClose`. + +##### `onReady` + +> `type: () => void` | **optional** + +Runs when the provider mounts. + +##### `onOpen` + +> `type: () => void` | **optional** + +Runs when a modal opens from `ready` or `sidepanel`. + +##### `onClose` + +> `type: () => void` | **optional** + +Runs when a modal changes directly to `ready`. + +##### `onSidepanelOpen` + +> `type: () => void` | **optional** + +Runs when the state changes to `sidepanel`. + +##### `onSidepanelClose` + +> `type: () => void` | **optional** + +Runs when the state leaves `sidepanel`. + + + + +### JavaScript + +The JavaScript packages create independent DocSearch and Sidepanel instances. Connect them with `interceptAskAiEvent`. + + + + +```bash +npm install @docsearch/js@^5.0.0-beta @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/js@^5.0.0-beta @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/js@^5.0.0-beta @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/js@^5.0.0-beta @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Add one mount element for each instance: + +```html title="index.html" +
+
+``` + +Create the Sidepanel first so the interceptor always has a target. The mobile check in this example matches the React integration: mobile users stay in the Ask AI modal, while desktop users move to the Sidepanel. + +```ts title="search.ts" +import docsearch, { type DocSearchInstance } from '@docsearch/js'; +import sidepanel, { type SidepanelInstance } from '@docsearch/sidepanel-js'; + +import '@docsearch/css/dist/style.css'; +import '@docsearch/css/dist/sidepanel.css'; + +const appId = 'YOUR_APP_ID'; +const apiKey = 'YOUR_SEARCH_API_KEY'; +const keywordIndexName = 'YOUR_KEYWORD_INDEX_NAME'; +const askAiIndexName = 'YOUR_ASK_AI_INDEX_NAME'; +const assistantId = 'YOUR_ASSISTANT_ID'; +const mobileQuery = window.matchMedia('(max-width: 768px)'); + +let search: DocSearchInstance | undefined; +let panel: SidepanelInstance | undefined; + +panel = sidepanel({ + container: '#docsearch-sidepanel', + appId, + apiKey, + indexName: askAiIndexName, + assistantId, + onReady: () => { + document.body.setAttribute('data-sidepanel-ready', ''); + }, + onOpen: () => { + search?.close(); + document.body.setAttribute('data-sidepanel-open', ''); + }, + onClose: () => { + document.body.removeAttribute('data-sidepanel-open'); + }, +}); + +search = docsearch({ + container: '#docsearch', + appId, + apiKey, + indices: [keywordIndexName], + askAi: { assistantId }, + interceptAskAiEvent: (initialMessage) => { + if (mobileQuery.matches) { + return false; + } + + search?.close(); + panel?.open(initialMessage); + return true; + }, + onReady: () => { + document.body.setAttribute('data-docsearch-ready', ''); + }, + onOpen: () => { + panel?.close(); + document.body.setAttribute('data-search-open', ''); + }, + onClose: () => { + document.body.removeAttribute('data-search-open'); + }, +}); +``` + +The root `@docsearch/js` export includes Ask AI. The keyword-only JavaScript entry point is `@docsearch/js/docsearch`; don't use that entry point for hybrid mode because it has no Ask AI action to intercept. + +#### How `interceptAskAiEvent` works + +`interceptAskAiEvent` runs before the modal changes to Ask AI or sends a message. + +- Return `true` after another interface accepts the request. DocSearch clears the keyword query and skips all default Ask AI behavior. +- Return `false` or `undefined` to keep the default Ask AI modal flow. +- Pass `initialMessage` unchanged to `sidepanelInstance.open(initialMessage)` so conversation and suggestion IDs survive. + +Keep the `onOpen` callbacks that close the other instance. They prevent two interfaces from staying open when application code calls `search.open()`, `search.openAskAi()`, or `panel.open()` directly. + +The JavaScript instances expose these lifecycle callbacks and controls: + +- The DocSearch instance accepts the `onReady`, `onOpen`, and `onClose` callbacks, and exposes `open()`, `close()`, `openAskAi()`, `destroy()`, `isReady`, and `isOpen`. +- The Sidepanel instance accepts the `onReady`, `onOpen`, and `onClose` callbacks, and exposes `open()`, `close()`, `destroy()`, `isReady`, and `isOpen`. + +Call both `destroy()` methods if your application removes the mount elements or tears down the page without a full navigation. + +
+
+ +## Add hybrid mode to Docusaurus + +Hybrid mode is supported through `@docsearch/docusaurus-adapter`. The adapter loads the v5 modal and Sidepanel, connects their state, and applies the mobile behavior described in this guide. + +Install the adapter and keep `@docusaurus/preset-classic`: + + + + +```bash +npm install @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +Configure DocSearch under `themeConfig.docsearch`. Set top-level `sidePanel` to `true` or to a Sidepanel options object. + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + docsearch: { + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [{ name: 'YOUR_INDEX_NAME' }], + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + }, + sidePanel: true, + contextualSearch: true, + searchPage: { path: 'search' }, + }, + }, +}; +``` + +The adapter requires `askAi` to be an object with `assistantId`; it doesn't accept the string shorthand in Docusaurus configuration. It also requires `askAi` whenever `sidePanel` is set. + +Don't put `sidePanel` inside `askAi`. Don't configure this adapter under `themeConfig.algolia`. If you need function-valued custom tools, pass them through a swizzled `@theme/SearchBar` component because Docusaurus removes functions while serializing theme configuration. + +The built-in `@docusaurus/theme-search-algolia` integration doesn't provide this v5 Sidepanel configuration. Use the DocSearch adapter for this workflow. + +## Mobile behavior + +The React provider treats viewports that match `(max-width: 768px)` as mobile. On those viewports, an Ask AI action stays in the modal even when a Sidepanel is registered. This avoids moving the conversation into the desktop Sidepanel layout. + +The provider updates this decision on window resize. The Sidepanel also avoids focusing its prompt automatically on mobile because opening the virtual keyboard can disrupt the layout. + +The JavaScript packages don't share a provider, so they don't apply the hybrid mobile decision to your interceptor. Add the `matchMedia` branch shown in the JavaScript example when you want the same behavior. + +## Load the styles + +Hybrid mode needs both style bundles: + +```ts title="search.ts" +import '@docsearch/css/dist/style.css'; +import '@docsearch/css/dist/sidepanel.css'; +``` + +`style.css` includes shared variables, the button, keyword modal, and Ask AI modal. `sidepanel.css` adds the Sidepanel layout and imports the shared variables it needs. + +If your bundler resolves the React style entry points, `@docsearch/react/style` and `@docsearch/react/style/sidepanel` load the same bundles. Import each bundle once. + +## Troubleshoot hybrid mode + +### Ask AI stays in the modal on desktop + +Confirm that `Sidepanel` is mounted under the same `DocSearch` provider before the Ask AI action. The provider enables automatic handoff only after the Sidepanel registers. Also confirm that the viewport is wider than 768 pixels. + +### Both the modal and Sidepanel submit the prompt + +Return `true` from `interceptAskAiEvent` after calling `panel.open(initialMessage)`. Returning `false` or no value tells the modal to continue its default flow. + +### Mobile users open the Sidepanel + +In JavaScript integrations, check `(max-width: 768px)` in the interceptor and return `false` on a match. React and the Docusaurus adapter already make this decision. + +### The Sidepanel loses a suggestion or saved conversation + +Pass the complete `initialMessage` object to `open()`. Rebuilding it with only `query` discards `suggestedQuestionId` and `messageId`. + +### A callback doesn't run during React handoff + +Expect `onSidepanelOpen`, not `onClose`, when React changes directly from the modal to the Sidepanel. Use the shared provider callbacks rather than treating modal close as the handoff signal. + +### Two JavaScript interfaces remain open + +Close the search instance in the Sidepanel's `onOpen`, and close the Sidepanel in the search instance's `onOpen`. This also covers programmatic calls that bypass the interceptor. + +### The interface is unstyled + +Import both `style.css` and `sidepanel.css`. Check that your bundler includes CSS imports from dependencies. + +### Docusaurus rejects the configuration + +Use `themeConfig.docsearch`, pass `askAi` as an object, and put `sidePanel` beside `askAi`. Install `@docsearch/docusaurus-adapter@^5.0.0-beta` instead of configuring hybrid mode through the built-in Algolia theme. + +### Server rendering fails with `window` or `document` errors + +Mount the composable React components only in the browser. The Docusaurus adapter handles this boundary and lazy-loads the modal and Sidepanel client-side. diff --git a/packages/website/docs/integrations.md b/packages/website/docs/integrations.md index 4770be2f..ec8a2eec 100644 --- a/packages/website/docs/integrations.md +++ b/packages/website/docs/integrations.md @@ -1,15 +1,16 @@ --- -title: Supported Integrations +title: Supported integrations +description: Find supported framework integrations for DocSearch. --- -We worked with **documentation website generators** to have DocSearch directly embedded as a first class citizen in the websites they produce. +Documentation frameworks can embed DocSearch in the websites they generate. A framework integration configures the frontend; your Algolia Crawler and index remain separate. -## Our great integrations +## Framework integrations -So, if you're using one of the following tools, checkout their documentation to see how to enable DocSearch on your website: +If you use one of the following tools, follow its documentation to enable DocSearch. Framework documentation can target a different DocSearch frontend release, so check its package compatibility before adopting v5. - [Docusaurus v1][1] - [How to enable search][2] -- [Docusaurus v2 & v3][3] - [DocSearch adapter (recommended)][23] / [Using Algolia DocSearch][4] +- [Docusaurus v2 and v3][3] - [DocSearch v5 adapter][23] / [Using Algolia DocSearch][4] - [VuePress][5] - [Algolia Search][6] - [VitePress][21] - [Search][22] - [Starlight][7] - [Algolia Search][8] @@ -20,7 +21,7 @@ So, if you're using one of the following tools, checkout their documentation to - [Lotus Docs][19] - [Enabling the DocSearch Plugin][20] - [Sphinx](https://www.sphinx-doc.org/en/master/) - [Algolia DocSearch for Sphinx](https://sphinx-docsearch.readthedocs.io/) -If you're maintaining a similar tool and want us to add you to the list, [feel free to make a pull request](https://github.com/algolia/docsearch/edit/main/packages/website/docs/integrations.md) and [contribute to Code Exchange](https://www.algolia.com/developers/code-exchange/contribute/). We're happy to help. +If you maintain a similar tool and want us to add it to the list, [open a pull request](https://github.com/algolia/docsearch/edit/main/packages/website/docs/integrations.md) and [contribute to Code Exchange](https://www.algolia.com/developers/code-exchange/contribute/). [1]: https://v1.docusaurus.io/ [2]: https://v1.docusaurus.io/docs/en/search @@ -42,4 +43,4 @@ If you're maintaining a similar tool and want us to add you to the list, [feel f [20]: https://lotusdocs.dev/docs/guides/features/docsearch/#enabling-the-docsearch-plugin [21]: https://vitepress.dev/ [22]: https://vitepress.dev/reference/default-theme-search#algolia-search -[23]: /docs/docusaurus-adapter +[23]: /docs/packages/docusaurus-adapter/getting-started diff --git a/packages/website/docs/manage-your-crawls.mdx b/packages/website/docs/manage-your-crawls.mdx index 7e752830..aa3351f8 100644 --- a/packages/website/docs/manage-your-crawls.mdx +++ b/packages/website/docs/manage-your-crawls.mdx @@ -1,11 +1,13 @@ --- -title: "[Pre-v4] Manage your crawls" +title: Legacy crawler interface +description: Manage legacy DocSearch crawler configurations in the Algolia dashboard. --- :::caution -This UI is deprecated and no longer maintained. For the latest instructions, please use the new documentation: [Crawler Configuration Visual UI](./crawler-configuration-visual). You can find the new Crawler UI at [dashboard.algolia.com/crawler](https://dashboard.algolia.com/crawler). -::: +This crawler interface is deprecated and no longer maintained. It isn't a DocSearch frontend version. For current instructions, use the [Crawler interface guide](./crawler-configuration-visual). Open the current interface at [dashboard.algolia.com/crawler](https://dashboard.algolia.com/crawler). + +::: import useBaseUrl from '@docusaurus/useBaseUrl'; @@ -46,7 +48,7 @@ The live editor allows you to update your config file and test your URLs (`URL t ## Search preview -From the [`editor`](#update-your-config), you have access to a `Search preview` tab to browse search results with [`DocSearch v3`](/docs/v3/docsearch). +The legacy editor's `Search preview` tab renders results with the historical [`DocSearch v3` frontend](/docs/v3/docsearch). This preview doesn't require your website to use that frontend version. For current integrations, see the [v5 package guides](/docs/packages/overview).
+## Install with `@docsearch/cli` -## Verify the install +The DocSearch CLI requires Node.js 20 or later. Run the interactive installer without installing the package globally: -Ask your MCP client a public documentation question, for example: + + -```text -Use DocSearch MCP to find the current Next.js middleware matcher docs. +```sh +npx @docsearch/cli@^0.0.2 setup ``` -The client should call the DocSearch tools and answer with content from the matching documentation, ideally with source links. + + -:::note +```sh +yarn dlx @docsearch/cli@^0.0.2 setup +``` -Algolia DocSearch MCP is a free service and is provided by Algolia "AS IS" and "AS AVAILABLE" without warranty of any kind, and may be suspended, modified, or discontinued by Algolia at any time in its sole discretion. Algolia disclaims all obligation and liability arising out of or in connection with Your use of DocSearch MCP. You shall comply with all laws and governmental regulations in Your use of the DocSearch MCP. + + -::: +```sh +pnpm dlx @docsearch/cli@^0.0.2 setup +``` + + + + +```sh +bunx @docsearch/cli@^0.0.2 setup +``` + + + + +The installer asks whether to update the current project or your user-level settings. It detects and configures these clients: + +- Cursor +- Claude Code +- Codex +- OpenCode +- Gemini CLI + +For each selected client, the installer adds the `algolia-docsearch` server, a rule that describes when to search documentation, and a skill that describes the tool workflow. Project setup finds the repository root before writing files. You can run setup again without removing unrelated configuration. + +Pass a scope and client flags to skip the prompts: + + + + +```sh +npx @docsearch/cli@^0.0.2 setup --project --cursor --claude --yes +npx @docsearch/cli@^0.0.2 setup --global --all --yes +``` + + + + +```sh +yarn dlx @docsearch/cli@^0.0.2 setup --project --cursor --claude --yes +yarn dlx @docsearch/cli@^0.0.2 setup --global --all --yes +``` + + + + +```sh +pnpm dlx @docsearch/cli@^0.0.2 setup --project --cursor --claude --yes +pnpm dlx @docsearch/cli@^0.0.2 setup --global --all --yes +``` + + + + +```sh +bunx @docsearch/cli@^0.0.2 setup --project --cursor --claude --yes +bunx @docsearch/cli@^0.0.2 setup --global --all --yes +``` + + + + +Use `--cursor`, `--claude`, `--codex`, `--opencode`, or `--gemini` to select clients. Use either `--project` or `--global`, not both. + +To install the `docsearch` command globally, run: + + + + +```sh +npm install --global @docsearch/cli@^0.0.2 +docsearch setup +``` + + + + +```sh +yarn global add @docsearch/cli@^0.0.2 +docsearch setup +``` + + + + +```sh +pnpm add --global @docsearch/cli@^0.0.2 +docsearch setup +``` + + + + +```sh +bun add --global @docsearch/cli@^0.0.2 +docsearch setup +``` + + + + +## Install a client plugin + +Plugins include the MCP connection and instructions that teach the client when and how to use DocSearch. + +### Claude Code + +Run these commands inside Claude Code: + +```text +/plugin marketplace add algolia/docsearch +/plugin install algolia-docsearch@algolia-docsearch-marketplace +``` + +The plugin adds the MCP server, a skill, and the `/algolia-docsearch:docs` command. + +### Cursor + +The Cursor plugin package is in the DocSearch repository at: + +```text +mcp/plugins/docsearch/cursor/algolia-docsearch +``` + +It includes the MCP server configuration, a rule, and a skill. + +## Configure a supported agent manually + +Manual configuration adds the server but doesn't install the rules and skills supplied by the CLI or plugins. + + + + +Add this entry to `~/.cursor/mcp.json` for user-level configuration or `.cursor/mcp.json` for project configuration: + +```json title=".cursor/mcp.json" +{ + "mcpServers": { + "algolia-docsearch": { + "url": "https://mcp.algolia.com/1/docsearch/mcp" + } + } +} +``` + + + + +Add the user-level remote server with the Claude Code CLI: + +```sh +claude mcp add --scope user --transport http algolia-docsearch https://mcp.algolia.com/1/docsearch/mcp +``` + + + + +Add the remote server with the Codex CLI: + +```sh +codex mcp add algolia-docsearch --url https://mcp.algolia.com/1/docsearch/mcp +``` + +You can also add the URL under `[mcp_servers.algolia-docsearch]` in `~/.codex/config.toml`. + + + + +Add this entry to `opencode.json` or `opencode.jsonc`: + +```json title="opencode.json" +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "algolia-docsearch": { + "type": "remote", + "url": "https://mcp.algolia.com/1/docsearch/mcp", + "enabled": true + } + } +} +``` + + + + +Add this entry to `.gemini/settings.json` for project configuration or `~/.gemini/settings.json` for user-level configuration: + +```json title=".gemini/settings.json" +{ + "mcpServers": { + "algolia-docsearch": { + "httpUrl": "https://mcp.algolia.com/1/docsearch/mcp" + } + } +} +``` + + + + +## Connect another MCP client + +You can also connect clients that support remote HTTP MCP servers. Use these connection methods: + +- **Claude Desktop**: Add a custom connector named `Algolia DocSearch` with the endpoint URL. +- **ChatGPT**: Add a no-auth custom connector. Availability depends on the plan and workspace settings. +- **Pi**: Install an MCP extension or adapter before adding the server. +- **VS Code**: Add a remote server to the workspace or user MCP configuration. The tools are available in Copilot Chat agent mode. +- **Windsurf**: Add the endpoint to the Cascade MCP configuration, then restart Windsurf. +- **Zed**: Add the endpoint as a context server. +- **Conductor**: Configure the server in the selected Claude Code, Codex, or Cursor host. Conductor doesn't use a separate MCP configuration for those sessions. +- **Antigravity**: Add the endpoint through **Manage MCP Servers > View raw config**, then refresh the installed servers. + +Configuration keys differ by client. Follow the client's MCP documentation and keep the server name `algolia-docsearch` and the endpoint URL unchanged. + +## Verify the installation + +Ask your client to search public documentation: + +```text +Use DocSearch MCP to find the Next.js middleware matcher documentation. +``` + +Confirm that the client calls a tool whose name starts with `algolia_docsearch_` and returns source links from the selected documentation. + +If verification fails, see [Troubleshooting](/docs/mcp/usage#troubleshooting). diff --git a/packages/website/docs/mcp/overview.mdx b/packages/website/docs/mcp/overview.mdx index 1d3aeae5..8c211136 100644 --- a/packages/website/docs/mcp/overview.mdx +++ b/packages/website/docs/mcp/overview.mdx @@ -1,49 +1,66 @@ --- title: DocSearch MCP +description: Understand the DocSearch Model Context Protocol server. sidebar_label: Overview --- -DocSearch MCP lets AI clients search current public developer documentation from the DocSearch corpus. +DocSearch MCP lets AI clients search public developer documentation in the DocSearch corpus. -Use it when you want an assistant to answer questions from public docs instead of relying only on model training data. The public endpoint does not require authentication: +Use it when an assistant needs information from published documentation instead of relying only on its training data. Connect an MCP-compatible client to this endpoint: ```text https://mcp.algolia.com/1/docsearch/mcp ``` -## What it does +The endpoint doesn't require authentication. You don't need an Algolia application ID, search API key, or DocSearch application. -DocSearch MCP exposes documentation search through the [Model Context Protocol](https://modelcontextprotocol.io/). MCP-compatible clients connect to the endpoint and call DocSearch tools while answering your questions. +## What DocSearch MCP provides -The endpoint is focused on public developer documentation. You do not need an Algolia application ID, search API key, or DocSearch application to use it. +DocSearch MCP exposes documentation search through the [Model Context Protocol](https://modelcontextprotocol.io/). Your client calls its tools, receives ranked documentation excerpts and source URLs, and uses those results to answer your question. -## How it works +Use DocSearch MCP for public documentation about libraries, frameworks, SDKs, APIs, CLI tools, and cloud services. It doesn't provide access to: -Most lookups are a single call: name the product and ask your question, and DocSearch finds the right documentation set and returns the matching content together. +- Private or unpublished documentation +- Internal repositories +- DocSearch crawler or administration operations +- Algolia indices or credentials +- General programming advice outside the indexed documentation -When a question spans several products, or you want to inspect and hand-pick documentation sets first, there is a two-step flow: resolve the documentation sets, then query the ones you choose. +## How searches work + +For most searches, provide a product name and a focused question. DocSearch resolves the matching documentation set and searches it in one call. + +Use the two-step workflow when a question covers several products or when you need to select the documentation set yourself. First resolve candidate sets, then query the selected set IDs. ## Available tools ### `algolia_docsearch_search_docs` -The one-shot tool, and the right default for most lookups. Give it a `library` (the product, SDK, or platform) and a `query` (your question); it resolves the best matching documentation set and returns ranked content in a single call. If the library is ambiguous, it returns candidate documentation sets to choose from instead. +Use this one-shot tool for most searches. Set `library` to the official product, SDK, or platform name. Set `query` to the documentation question. + +The tool resolves the best matching documentation set and returns ranked content. If the product name is ambiguous, it returns candidate documentation sets instead. ### `algolia_docsearch_resolve_docset` -Step 1 of the manual flow. Finds the documentation sets that best match a product, library, or platform and returns candidates β€” each with a `docset_id`, title, description, and ranking signals to help pick the best match. +Use this tool first in the manual workflow. It returns candidate documentation sets with a `docset_id`, title, description, and ranking signals. ### `algolia_docsearch_query_docs` -Step 2 of the manual flow. Retrieves documentation content for one or more `docset_id`s returned by `algolia_docsearch_resolve_docset`. Pass several at once when a question spans multiple products. +Use this tool with one or more `docset_id` values returned by `algolia_docsearch_resolve_docset`. Pass several IDs when the question covers more than one product. + +## Security and service limits + +Connect only to the HTTPS endpoint shown on this page. Don't add Algolia credentials to the MCP configuration. Send documentation questions, not secrets or confidential data, to the hosted service. + +DocSearch MCP searches public content and returns external documentation to your client. Review generated answers and commands before you use them. + +:::note[Service terms] + +Algolia DocSearch MCP is a free service and is provided by Algolia "AS IS" and "AS AVAILABLE" without warranty of any kind. Algolia may suspend, modify, or discontinue the service at any time at its sole discretion. Algolia disclaims all obligation and liability arising from or related to your use of DocSearch MCP. You must comply with all applicable laws and government regulations when you use the service. + +::: ## Next steps - [Install DocSearch MCP](/docs/mcp/installation) - [Use DocSearch MCP](/docs/mcp/usage) - -:::note - -Algolia DocSearch MCP is a free service and is provided by Algolia "AS IS" and "AS AVAILABLE" without warranty of any kind, and may be suspended, modified, or discontinued by Algolia at any time in its sole discretion. Algolia disclaims all obligation and liability arising out of or in connection with Your use of DocSearch MCP. You shall comply with all laws and governmental regulations in Your use of the DocSearch MCP. - -::: diff --git a/packages/website/docs/mcp/usage.mdx b/packages/website/docs/mcp/usage.mdx index fb7b8a9b..85e76537 100644 --- a/packages/website/docs/mcp/usage.mdx +++ b/packages/website/docs/mcp/usage.mdx @@ -1,41 +1,40 @@ --- title: Use DocSearch MCP +description: Query documentation with the DocSearch MCP server. sidebar_label: Usage --- -DocSearch MCP works best when your client knows to search public documentation before answering library, framework, API, or SDK questions. - -## Ask documentation questions - -After installation, ask your client about public developer docs in natural language: +Ask focused questions about public documentation. Include the official product name, topic, and version when the version affects the answer. ```text How do I configure middleware matchers in Next.js? ``` ```text -Show me the current Stripe webhook signature verification docs. +Show me the Stripe webhook signature verification documentation. ``` ```text -What is the current setup for Algolia InstantSearch React? +What is the setup for Algolia InstantSearch React? ``` -If your client does not automatically use MCP tools, mention DocSearch MCP explicitly: +If your client doesn't select MCP tools on its own, name the server in your request: ```text Use DocSearch MCP to look up React Server Components data fetching. ``` +Ask the client to include source URLs when you need to inspect the supporting documentation. + ## Use the Claude Code command -The Claude Code plugin includes a manual command: +The Claude Code plugin provides this command: ```text /algolia-docsearch:docs [topic] ``` -Examples: +For example: ```text /algolia-docsearch:docs Next.js middleware matcher @@ -43,15 +42,48 @@ Examples: /algolia-docsearch:docs Algolia InstantSearch React configure search client ``` -## Tool flow +## Search from the terminal -DocSearch MCP exposes three tools. Most of the time the client only needs the one-shot tool; the two-step flow is for multi-product questions or when you want to hand-pick documentation sets. +`@docsearch/cli` can call the hosted MCP tools without a separate MCP client. Use `docs` for most questions: -You can ask in natural language β€” full sentences and questions work well. For the one-shot tool, keep `library` to the product name and put the actual question in `query`. +```sh +docsearch docs Next.js "how do middleware matchers work" +``` -### One-shot: `algolia_docsearch_search_docs` +Limit the number of results or documentation sets when needed: -The client names the product and asks the question in a single call: +```sh +docsearch docs Next.js "cache revalidation" --max-results 3 --max-docsets 2 +``` + +For explicit documentation-set selection, resolve a product and then query its returned ID: + +```sh +docsearch resolve "Algolia InstantSearch React" +docsearch query repo/algolia/instantsearch "configure the React search client" +``` + +Limit resolver candidates with `--top-n`: + +```sh +docsearch resolve Next.js --top-n 3 +``` + +Add `--json` to print the raw MCP result as JSON: + +```sh +docsearch docs Next.js "cache revalidation" --json +``` + +Machine-readable results go to standard output. Progress and errors go to standard error. + +## Choose a tool workflow + +DocSearch MCP provides a one-shot search and a two-step search. Use natural-language questions rather than lists of keywords. + +### Search in one call + +Use `algolia_docsearch_search_docs` for most questions. Keep the product name in `library` and the question in `query`: ```json { @@ -60,54 +92,72 @@ The client names the product and asks the question in a single call: } ``` -It returns ranked documentation content for the best matching set. If the library is ambiguous, it returns candidate documentation sets instead so the client can pick one and fall back to `algolia_docsearch_query_docs`. +The tool resolves the best documentation set and returns ranked content. If `library` doesn't identify a clear match, it returns candidate sets instead of searching the wrong one. -### Two-step: resolve, then query +### Resolve and query documentation sets -For questions that span several products, or when the client wants to choose documentation sets explicitly: +Use the two-step workflow when the product is ambiguous, you want to inspect the candidates, or the question covers multiple products. -1. `algolia_docsearch_resolve_docset` finds documentation sets: +1. Call `algolia_docsearch_resolve_docset` with the product or platform name: -```json -{ - "query": "Next.js app router" -} -``` + ```json + { + "query": "Next.js app router" + } + ``` -It returns candidates, each with a `docset_id`. +2. Select the best `docset_id` from the response. -2. `algolia_docsearch_query_docs` retrieves content for the chosen `docset_id`(s): +3. Call `algolia_docsearch_query_docs` with the selected ID and a focused question: -```json -{ - "query": "middleware matcher config", - "docsetIds": ["nextjs"] -} -``` + ```json + { + "query": "middleware matcher configuration", + "docsetIds": ["nextjs"] + } + ``` -Pass multiple `docsetIds` when a question spans more than one product. - -## Tips - -- Be specific about the product and topic you want. -- Include a version when it matters. -- Ask for source URLs if you want the client to show where the answer came from. -- If the first result is too broad, ask for a narrower topic. +Pass more than one `docsetIds` value when the question covers multiple products. Don't guess IDs. Use only IDs returned by `algolia_docsearch_resolve_docset` or `algolia_docsearch_search_docs`. ## Troubleshooting -### The client does not call DocSearch MCP +### The client doesn't call DocSearch MCP -Make sure the MCP server is enabled in your client and named `algolia-docsearch`. If you installed the plugin, check that the plugin is enabled too. +Confirm that the server is enabled and named `algolia-docsearch`. If you installed a plugin, confirm that the plugin is enabled. Then ask the client to use DocSearch MCP explicitly. -### The result is about the wrong product +### The client can't connect -Ask again with the official product name. For the one-shot tool, set `library` to the vendor's product name (for example, `Algolia InstantSearch` rather than `search`). - -### The client cannot connect - -Confirm that your client supports remote HTTP MCP servers and that the configured URL is: +Confirm that the client supports remote HTTP MCP servers and uses this exact HTTPS URL: ```text https://mcp.algolia.com/1/docsearch/mcp ``` + +The public endpoint doesn't require authentication. Remove application IDs, API keys, headers, or authentication settings that the client doesn't require. + +### CLI setup doesn't detect an agent + +Pass the agent flag directly, or use `--all` with the setup command from the [installation guide](/docs/mcp/installation). + +```sh +docsearch setup --project --cursor --yes +docsearch setup --global --all --yes +``` + +Supported flags are `--cursor`, `--claude`, `--codex`, `--opencode`, and `--gemini`. + +### CLI setup reports an invalid configuration + +Fix the reported JSON, JSONC, or TOML error before running setup again. The CLI stops instead of replacing an invalid configuration. It also rejects duplicate `[mcp_servers.algolia-docsearch]` sections in Codex configuration. + +### The result covers the wrong product + +Use the official product or vendor name. For example, use `Algolia InstantSearch` instead of `search`. If the name remains ambiguous, resolve the documentation set first and query the selected ID. + +### The result is too broad or empty + +Add the product version and narrow the question to one task. Run separate searches for unrelated topics. If a narrower search still returns no useful content, the requested documentation might not be in the public DocSearch corpus. + +### Private documentation isn't returned + +DocSearch MCP searches public developer documentation only. It doesn't search private company docs, internal repositories, or unpublished APIs. diff --git a/packages/website/docs/migrating-from-legacy.mdx b/packages/website/docs/migrating-from-legacy.mdx index b438951e..01b7d94d 100644 --- a/packages/website/docs/migrating-from-legacy.mdx +++ b/packages/website/docs/migrating-from-legacy.mdx @@ -1,5 +1,6 @@ --- title: Migrating from the legacy scraper +description: Move a legacy DocSearch scraper configuration to the Algolia Crawler. --- import Tabs from '@theme/Tabs'; @@ -7,21 +8,23 @@ import TabItem from '@theme/TabItem'; ## Introduction -With the new version of the [DocSearch UI][1], we wanted to go further and provide better tooling for you to create and maintain your config file, and some extra Algolia features that you all have been requesting for a long time! +This guide covers the historical migration from the self-hosted DocSearch scraper to the Algolia Crawler. It is separate from upgrading the frontend UI. For the current frontend, choose a [DocSearch v5 package][33]. ## What's new? -### Scraper +### Indexing infrastructure -The DocSearch infrastructure now leverages the [Algolia Crawler][2]. We've teamed up with our friends and created a new [DocSearch helper][4], that extracts records as we were previously doing with our beloved [DocSearch scraper][3]! +DocSearch indexing now uses the [Algolia Crawler][2]. The [DocSearch helper][4] extracts records in place of the legacy [DocSearch scraper][3]. -The best part, is that you no longer need to install any tooling on your side if you want to maintain or update your index! +You don't need to install local scraper tooling to maintain or update your index. -We now provide a web interface **[legacy][7]** or **[new](https://dashboard.algolia.com/crawler)** that will allow you to: +Use the **[legacy interface][7]** or the **[current Crawler interface](https://dashboard.algolia.com/crawler)** to: - Start, schedule and monitor your crawls - Edit your config file from our live editor -- Test your results directly with [DocSearch v3][1] or [DocSearch v4][32] +- Test results with the historical [DocSearch v3][1] or [DocSearch v4][32] previews + +These preview versions don't set the crawler record schema or the frontend package installed on your website. Likewise, crawler `recordVersion: 'v3'` names a record schema, not DocSearch UI v3. ### Algolia application and credentials @@ -31,7 +34,7 @@ We've received a lot of requests asking for: - Browse and see how Algolia records are indexed - See and subscribe to other Algolia features -They are now all available, in **your own Algolia application**, for free :D +These features are available in your Algolia application. ## FAQ @@ -44,7 +47,7 @@ You can find answers related to the DocSearch migration in our [Crawler FAQ page ## Config file key mapping -Below are the keys that can be found in the [`legacy` DocSearch configs][14] and their translation to an [Algolia Crawler config][16]. More detailed documentation of the Algolia Crawler can be found on the [the official documentation][15] +Below are the keys that can be found in the [`legacy` DocSearch configs][14] and their translation to an [Algolia Crawler config][16]. For more detailed information on the Algolia Crawler, see [the official documentation][15]. | `legacy` | `current` | description | | --- | --- | --- | @@ -84,4 +87,5 @@ Below are the keys that can be found in the [`legacy` DocSearch configs][14] and [29]: /docs/record-extractor [30]: /docs/record-extractor#introduction [31]: /docs/record-extractor#pagerank -[32]: /docs/docsearch +[32]: /docs/v4/docsearch +[33]: /docs/packages/overview diff --git a/packages/website/docs/migrating-from-v4.mdx b/packages/website/docs/migrating-from-v4.mdx new file mode 100644 index 00000000..9217d6d8 --- /dev/null +++ b/packages/website/docs/migrating-from-v4.mdx @@ -0,0 +1,293 @@ +--- +title: Migrate from DocSearch v4 +description: Move a DocSearch v4 integration to the 5.0.0 beta packages and Agent Studio APIs. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +DocSearch v5 separates keyword search from the AI experience and uses Agent Studio for Ask AI. Plan the migration around the experience your site provides. + +Review the complete [v5 breaking changes](./v5-breaking-changes) before releasing. + +## 1. Upgrade the beta packages + +Upgrade every DocSearch package in the integration together with the `^5.0.0-beta` range. + + + + + + + +```bash +npm install @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + + + + + + + +```bash +npm install @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + + + + +If you use the Composable API or Sidepanel, also upgrade `@docsearch/core@^5.0.0-beta`, `@docsearch/modal@^5.0.0-beta`, `@docsearch/sidepanel@^5.0.0-beta`, or `@docsearch/sidepanel-js@^5.0.0-beta`. + +## 2. Choose keyword-only or AI-capable search + +### JavaScript without Ask AI + +The v4 root export rendered the combined component. In v5, the root export is AI-capable and the `/docsearch` subpath is keyword-only. + +Change the import: + +```diff title="app.js" +-import docsearch from '@docsearch/js'; ++import docsearch from '@docsearch/js/docsearch'; +``` + +Your keyword options can remain unchanged while you migrate deprecated options in a later step. + +For a CDN integration, replace the root bundle with the keyword-only UMD file: + +```diff title="index.html" +- ++ +``` + +### JavaScript with Ask AI + +Keep the root import. It now renders the AI-capable `DocSearchAI` component: + +```js title="app.js" +import docsearch from '@docsearch/js'; + +docsearch({ + container: '#docsearch', + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + }, +}); +``` + +For a CDN integration, use `dist/umd/index.js`. It exposes `window.docsearch`, as v4 did. + +### React without Ask AI + +Keep `DocSearch`, but remove any AI props. In v5 it renders keyword search only: + +```jsx title="Search.jsx" +import { DocSearch } from '@docsearch/react'; + +; +``` + +### React with Ask AI + +Replace `DocSearch` with `DocSearchAI`: + +```diff title="Search.jsx" +-import { DocSearch } from '@docsearch/react'; ++import { DocSearchAI } from '@docsearch/react'; + +- +``` + +`DocSearchAI` requires `askAi`. The string shorthand remains supported: + +```jsx title="Search.jsx" + +``` + +## 3. Move Ask AI to Agent Studio + +V5 removes the legacy Ask AI token and chat transport. Create the assistant in [Agent Studio](/docs/agent-studio/getting-started) before switching production traffic. + +Remove `agentStudio` and `useStagingEnv` from `askAi`. Agent Studio is the only Ask AI backend in v5. + +```diff title="app.js" + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', +- agentStudio: true, +- useStagingEnv: false, + } +``` + +The v4 Agent Studio form keyed search parameters by index name. V5 keeps that shape and removes the legacy flat form: + +```diff title="app.js" + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + searchParameters: { +- filters: 'language:en', +- attributesToRetrieve: ['title', 'content', 'url'], ++ docs: { ++ filters: 'language:en', ++ attributesToRetrieve: ['title', 'content', 'url'], ++ }, + }, + } +``` + +Agent Studio search parameters support `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. They don't support `facetFilters` in this object. Put fixed facet conditions in `filters`, or configure dynamic Agent Studio indices. + +V5 adds `askAi.indices`, `askAi.tools`, `askAi.memory`, and `askAi.promptSuggestions`. Keep all Agent Studio configuration inside `askAi`. Keep `interceptAskAiEvent` at the component or `docsearch()` root because it controls view routing. + +## 4. Move keyword configuration to `indices` + +`indexName` and root `searchParameters` still work in v5, but both are deprecated. + +```diff title="app.js" + docsearch({ + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', +- indexName: 'docs', +- searchParameters: { +- facetFilters: ['language:en'], +- }, ++ indices: [ ++ { ++ name: 'docs', ++ searchParameters: { ++ facetFilters: ['language:en'], ++ }, ++ }, ++ ], + }); +``` + +Use one item per index. DocSearch queries them in array order. If you temporarily pass both `indexName` and `indices`, it queries `indexName` first, so remove the old option to avoid duplicate requests. + +## 5. Update result customization + +Existing `transformItems`, `hitComponent`, `resultsFooterComponent`, `transformSearchClient`, navigation, Insights, and translation props remain available. + +V5 changes the result markup and adds breadcrumbs, source sections, facets, and badges. Review custom CSS, DOM selectors, screenshots, and tests that depend on v4 markup. + +To show a badge from a custom record property, add the property to the per-index `attributesToRetrieve`, then set `resultBadgeKey`: + +```jsx title="Search.jsx" + +``` + +## 6. Verify styles and package exports + +The full stylesheet remains available from `@docsearch/css` and the CDN `dist/style.css` file: + +```js title="app.js" +import '@docsearch/css'; +``` + +The React package adds split style entries for variables, button, modal, Ask AI, and Sidepanel. See [Styling](/docs/packages/css/styling). + +`@docsearch/js` now defines an exports map. Replace unsupported deep imports with `@docsearch/js` or `@docsearch/js/docsearch`. Continue to use documented React subpaths such as `@docsearch/react/button`, `/modal`, `/sidepanel`, and `/version`; their generated file names changed, but the package subpaths remain the public API. + +## 7. Verify programmatic controls + +The JavaScript function returns a `DocSearchInstance` with `open`, `close`, `openAskAi`, `destroy`, `isReady`, and `isOpen`. Use `openAskAi` only with the default AI-capable entry. + +React forwards `DocSearchRef`. It also exposes `openSidepanel`, `isSidepanelOpen`, and `isSidepanelSupported` for [hybrid mode](/docs/hybrid-mode). + +Test these cases before release: + +- Open and close by button, `Ctrl/Cmd+K`, `/`, and Escape. +- Search every configured index and apply every facet. +- Open Ask AI, send follow-up questions, submit feedback, and restore a conversation. +- Exercise any custom tools and memory authentication. +- Verify custom hit links, result footers, translations, badges, and Insights events. +- Verify mobile behavior. Hybrid mode uses the modal instead of the Sidepanel on mobile. + +## 8. Update framework integrations + +If Docusaurus manages DocSearch configuration, follow the [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started). For custom provider, button, and modal layouts, review the [Composable API](/docs/composable-api). diff --git a/packages/website/docs/packages/core/api.mdx b/packages/website/docs/packages/core/api.mdx new file mode 100644 index 00000000..93dd4ea1 --- /dev/null +++ b/packages/website/docs/packages/core/api.mdx @@ -0,0 +1,284 @@ +--- +title: Core API reference +description: API reference for @docsearch/core v5 beta. +toc_max_heading_level: 2 +--- + +## `DocSearch` + +`DocSearch` is a ref-forwarding React provider. + +### `children` + +> `type: React.ReactNode` | **required** + +Views and controls that consume DocSearch state. + +### `theme` + +> `type: 'dark' | 'light'` | **optional** + +Sets `document.documentElement.dataset.theme` while mounted. + +### `initialQuery` + +> `type: string` | **optional** + +Initial modal query and reset value after close. Defaults to `''`. + +### `keyboardShortcuts` + +> `type: KeyboardShortcuts` | **optional** + +Overrides individual shortcut defaults. All shortcuts are enabled by default. + +### `onReady` + +> `type: () => void` | **optional** + +Runs after the provider mounts. + +### `onOpen` + +> `type: () => void` | **optional** + +Runs when a modal opens. + +### `onClose` + +> `type: () => void` | **optional** + +Runs when a modal closes to the ready state. + +### `onSidepanelOpen` + +> `type: () => void` | **optional** + +Runs when the Sidepanel opens. + +### `onSidepanelClose` + +> `type: () => void` | **optional** + +Runs when the Sidepanel closes. + +### `KeyboardShortcuts` + +```ts +interface KeyboardShortcuts { + 'Ctrl/Cmd+K'?: boolean; + '/'?: boolean; + 'Ctrl/Cmd+I'?: boolean; +} +``` + +`DEFAULT_KEYBOARD_SHORTCUTS` sets all three fields to `true`. + +## `DocSearchRef` + +Attach this ref to `DocSearch`. + +### `open` + +> `type: () => void` + +Opens the search modal. + +### `close` + +> `type: () => void` + +Returns to the ready state and focuses the registered search button. + +### `openAskAi` + +> `type: (message?: InitialAskAiMessage) => void` + +Opens Ask AI in a registered view. See [Hybrid Mode][1]. + +### `openSidepanel` + +> `type: (message?: InitialAskAiMessage) => void` + +Opens the Sidepanel; it does nothing until that view registers. + +### `isReady` + +> `type: readonly boolean` + +Whether the provider is mounted. + +### `isOpen` + +> `type: readonly boolean` + +Whether a modal is open. + +### `isSidepanelOpen` + +> `type: readonly boolean` + +Whether the Sidepanel is open. + +### `isSidepanelSupported` + +> `type: readonly boolean` + +Whether Sidepanel support is registered. See [Hybrid Mode][1]. + +```ts +type InitialAskAiMessage = { + query: string; + messageId?: string; + suggestedQuestionId?: string; +}; +``` + +## `useDocSearch` + +```ts +function useDocSearch(): DocSearchContext; +``` + +The hook returns the nearest provider value. + +`DocSearchState` is `'modal-askai' | 'modal-search' | 'ready' | 'sidepanel'`. + +`View` is `'modal' | 'sidepanel' | (Record & string)`, so integrations can register another string view. + +### `docsearchState` + +> `type: DocSearchState` + +Active state. + +### `setDocsearchState` + +> `type: (state: DocSearchState) => void` + +Sets active state directly. + +### `searchButtonRef` + +> `type: React.RefObject` + +Ref used to restore focus after close. + +### `initialQuery` + +> `type: string` + +Query for a modal opening. + +### `keyboardShortcuts` + +> `type: Required` + +User options merged with defaults. + +### `openModal` + +> `type: () => void` + +Opens keyword search. + +### `closeModal` + +> `type: () => void` + +Closes the modal and resets its query. + +### `isAskAiActive` + +> `type: boolean` + +Whether the modal is in Ask AI state. + +### `isModalActive` + +> `type: boolean` + +Whether either modal state is active. + +### `onAskAiToggle` + +> `type: OnAskAiToggle` + +Changes the active Ask AI state. See [Hybrid Mode][1]. + +### `initialAskAiMessage` + +> `type: InitialAskAiMessage | undefined` | **optional** + +Initial Sidepanel message. + +### `registerView` + +> `type: (view: View) => void` + +Registers an available view. + +### `isHybridModeSupported` + +> `type: boolean` + +Whether cross-view support is available. See [Hybrid Mode][1]. + +## `useKeyboardShortcuts` + +```ts +function useKeyboardShortcuts( + userShortcuts?: KeyboardShortcuts +): Required; +``` + +Returns the defaults merged with the supplied fields. + +## `useTheme` + +```ts +function useTheme(props: { theme?: 'dark' | 'light' }): void; +``` + +When `theme` differs from the document's existing `data-theme`, the hook sets it and restores the previous value on cleanup. It makes no change when `theme` is omitted. + +## `useDocSearchKeyboardEvents` + +```ts +interface UseDocSearchKeyboardEventsProps { + isOpen: boolean; + onOpen: () => void; + onClose: () => void; + isAskAiActive: boolean; + onAskAiToggle: (active: boolean) => void; + keyboardShortcuts?: KeyboardShortcuts; + onInput?: (event: KeyboardEvent) => void; + searchButtonRef?: React.RefObject; +} +``` + +The hook registers a window `keydown` listener. `Escape` leaves Ask AI first, then closes an open modal. `Control/Command+K` toggles the modal. `/` opens it when the user isn't editing content. + +`onInput` and `searchButtonRef` remain in the type for compatibility but are deprecated and aren't used by the hook. + +## Exports + +The root `@docsearch/core` entry exports: + +| Kind | Exports | +| --- | --- | +| Components and hooks | `DocSearch`, `useDocSearch`, `useDocSearchKeyboardEvents`, `useKeyboardShortcuts`, `useTheme` | +| Constants | `DEFAULT_KEYBOARD_SHORTCUTS` | +| Types | `DocSearchState`, `View`, `InitialAskAiMessage`, `OnAskAiToggle`, `DocSearchRef`, `DocSearchContext`, `DocSearchCallbacks`, `DocSearchProps`, `DocSearchTheme`, `UseThemeProps`, `UseDocSearchKeyboardEventsProps`, `DocSearchModalShortcuts`, `SidepanelShortcuts`, `KeyboardShortcuts` | + +The package also exposes these subpaths: + +| Import path | Exports | +| --- | --- | +| `@docsearch/core/useDocSearchKeyboardEvents` | `useDocSearchKeyboardEvents`, `UseDocSearchKeyboardEventsProps` | +| `@docsearch/core/useKeyboardShortcuts` | `useKeyboardShortcuts`, `DEFAULT_KEYBOARD_SHORTCUTS`, shortcut types | +| `@docsearch/core/useTheme` | `useTheme`, `DocSearchTheme`, `UseThemeProps` | + +`useIsMobile` is internal and isn't a package export. + +[1]: /docs/hybrid-mode diff --git a/packages/website/docs/packages/core/overview.mdx b/packages/website/docs/packages/core/overview.mdx new file mode 100644 index 00000000..0dfad6df --- /dev/null +++ b/packages/website/docs/packages/core/overview.mdx @@ -0,0 +1,124 @@ +--- +title: Core package +description: Understand the shared state and controls in @docsearch/core v5 beta. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/core` provides the React state shared by DocSearch views. It owns open and close state, keyboard events, theme selection, lifecycle callbacks, initial queries, and imperative controls. It doesn't render a search interface by itself. + +:::info v5 beta + +These instructions use the `^5.0.0-beta` range. + +::: + +## Install + + + + +```bash +npm install @docsearch/core@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/core@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/core@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/core@^5.0.0-beta +``` + + + + +Packages such as `@docsearch/modal` and `@docsearch/sidepanel` consume this provider. For component composition instructions, see the [Composable API guide](/docs/composable-api). + +## Configure shared behavior + +```tsx title="SearchState.tsx" +import { DocSearch } from '@docsearch/core'; + +export function SearchState({ children }: { children: React.ReactNode }) { + return ( + track('docsearch_ready')} + onOpen={() => track('search_opened')} + onClose={() => track('search_closed')} + onSidepanelOpen={() => track('assistant_opened')} + onSidepanelClose={() => track('assistant_closed')} + > + {children} + + ); +} +``` + +The default shortcuts enable `Control/Command+K`, `/`, and `Control/Command+I`. Slash doesn't open the modal while focus is in an input, select, textarea, or editable element. + +## Use a ref + +```tsx title="SearchState.tsx" +import { DocSearch, type DocSearchRef } from '@docsearch/core'; +import { useRef } from 'react'; + +export function SearchState({ children }: { children: React.ReactNode }) { + const ref = useRef(null); + + return ( + <> + + {children} + + ); +} +``` + +The ref can open and close registered views and report their state. See the [core API reference](./api#docsearchref). For interactions between views, see [Hybrid Mode](/docs/hybrid-mode). + +## Read provider state + +Call `useDocSearch` only beneath `DocSearch`. The hook throws outside the provider. + +```tsx title="SearchStatus.tsx" +import { useDocSearch } from '@docsearch/core'; + +export function SearchStatus() { + const { docsearchState, openModal, closeModal } = useDocSearch(); + + return ( + + ); +} +``` + +Use the higher-level modal and Sidepanel packages for their standard triggers. Read context directly when your interface needs custom controls. diff --git a/packages/website/docs/packages/css/bundle-exports.mdx b/packages/website/docs/packages/css/bundle-exports.mdx new file mode 100644 index 00000000..b59cc7a8 --- /dev/null +++ b/packages/website/docs/packages/css/bundle-exports.mdx @@ -0,0 +1,101 @@ +--- +title: CSS bundles and exports +description: Choose the @docsearch/css v5 beta bundle for each DocSearch surface. +--- + +`@docsearch/css` publishes compiled CSS and SCSS-named assets in `dist`. The package doesn't define an `exports` map, so import the root entry or a listed `dist` file. + +## Root entry + +The package fields `main`, `unpkg`, and `jsdelivr` all point to `dist/style.css`. + +These imports load the same full search-and-modal bundle: + +```js title="app.js" +import '@docsearch/css'; +import '@docsearch/css/dist/style.css'; +``` + +Use only one of them. + +## Choose imports by surface + +Each surface needs a different set of assets. See [Published assets](#published-assets) for the full file list. + +### Search button only + +```js title="app.js" +import '@docsearch/css/dist/button.css'; +``` + +### Keyword-search modal + +```js title="app.js" +import '@docsearch/css/dist/button.css'; +import '@docsearch/css/dist/modal.css'; +``` + +Use the root bundle instead if your modal can show Agent Studio responses. + +### Agent Studio modal + +```js title="app.js" +import '@docsearch/css'; +``` + +### Sidepanel + +```js title="app.js" +import '@docsearch/css'; +import '@docsearch/css/dist/sidepanel.css'; +``` + +The Sidepanel reuses Agent Studio response and Markdown classes from the root bundle, so `sidepanel.css` isn't the complete Sidepanel presentation by itself. + +## Load from a CDN + +```html title="index.html" + +``` + +Add the Sidepanel asset when needed: + +```html title="index.html" + +``` + +Use the caret beta range so compatible beta updates remain available. + +## Published assets + +| Path | Contents | +| --- | --- | +| `@docsearch/css/dist/style.css` | Variables, search button, modal, and Agent Studio response styles. | +| `@docsearch/css/dist/_variables.css` | Shared light and dark custom properties. | +| `@docsearch/css/dist/button.css` | Variables and search-button styles. | +| `@docsearch/css/dist/modal.css` | Variables and keyword-search modal styles. | +| `@docsearch/css/dist/_askai.css` | Agent Studio modal response and Markdown styles. | +| `@docsearch/css/dist/sidepanel.css` | Variables, Sidepanel button, panel layout, and Sidepanel-specific overrides. | + +Each asset also has an equivalent `.scss` file: `style.scss`, `_variables.scss`, `button.scss`, `modal.scss`, `_askai.scss`, and `sidepanel.scss`. The build writes the compiled bundle to both extensions; these aren't Sass source partials. + +## React style bridge exports + +`@docsearch/react` v5 beta also exposes JavaScript style bridge entry points. They re-export files from `@docsearch/css`: + +| Import path | CSS target | +| ---------------------------------- | ------------------------------------ | +| `@docsearch/react/style` | `@docsearch/css` | +| `@docsearch/react/style/variables` | `@docsearch/css/dist/_variables.css` | +| `@docsearch/react/style/button` | `@docsearch/css/dist/button.css` | +| `@docsearch/react/style/modal` | `@docsearch/css/dist/modal.css` | +| `@docsearch/react/style/askai` | `@docsearch/css/dist/_askai.css` | +| `@docsearch/react/style/sidepanel` | `@docsearch/css/dist/sidepanel.css` | + +Prefer direct `@docsearch/css` imports when your bundler supports CSS package imports. They show which assets enter your bundle and work across the DocSearch React packages. diff --git a/packages/website/docs/packages/css/styling.mdx b/packages/website/docs/packages/css/styling.mdx new file mode 100644 index 00000000..600409cb --- /dev/null +++ b/packages/website/docs/packages/css/styling.mdx @@ -0,0 +1,131 @@ +--- +title: Style DocSearch +description: Load and customize the DocSearch v5 beta CSS. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/css` contains the styles for the search button, modal, Agent Studio responses, and Sidepanel. + +:::info v5 beta + +These instructions use the `^5.0.0-beta` range. + +::: + +## Install and import + + + + +```bash +npm install @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/css@^5.0.0-beta +``` + + + + +For the search button and modal, import the package root: + +```js title="app.js" +import '@docsearch/css'; +``` + +The root stylesheet includes variables, button styles, modal styles, and Agent Studio response styles. It doesn't include Sidepanel layout styles. + +For a Sidepanel, add its stylesheet after the root stylesheet: + +```js title="app.js" +import '@docsearch/css'; +import '@docsearch/css/dist/sidepanel.css'; +``` + +## Override variables + +Load your overrides after DocSearch CSS. + +```css title="custom.css" +:root { + --docsearch-primary-color: #2457d6; + --docsearch-primary-dark-color: #173b99; + --docsearch-focus-color: #0b57d0; + --docsearch-modal-width: 48rem; + --docsearch-modal-radius: 0.75rem; + --docsearch-hit-height: 3.75rem; + --docsearch-border-radius: 0.375rem; +} +``` + +Prefer variables over selector overrides. Variables preserve focus, responsive, and state styles across package updates. + +Frequently used variables include: + +- **Brand and state**: `--docsearch-primary-color`, `--docsearch-primary-dark-color`, `--docsearch-highlight-color`, `--docsearch-focus-color`, `--docsearch-error-color`, `--docsearch-success-color` +- **Text and surfaces**: `--docsearch-text-color`, `--docsearch-secondary-text-color`, `--docsearch-background-color`, `--docsearch-modal-background`, `--docsearch-subtle-color`, `--docsearch-muted-color` +- **Modal**: `--docsearch-modal-width`, `--docsearch-modal-height`, `--docsearch-modal-variable-height`, `--docsearch-modal-radius`, `--docsearch-modal-shadow` +- **Search box and hits**: `--docsearch-searchbox-height`, `--docsearch-searchbox-background`, `--docsearch-hit-height`, `--docsearch-hit-background`, `--docsearch-hit-focus-background` +- **Button**: `--docsearch-search-button-background`, `--docsearch-search-button-text-color` +- **Sidepanel**: `--docsearch-sidepanel-background`, `--docsearch-sidepanel-primary`, `--docsearch-sidepanel-border`, `--docsearch-sidepanel-text-base`, `--docsearch-sidepanel-text-muted` + +## Set dark theme values + +DocSearch applies dark variables under `html[data-theme='dark']`. The `theme="dark"` prop on a DocSearch component sets this attribute. + +Override dark values with the same selector: + +```css title="custom.css" +html[data-theme='dark'] { + --docsearch-modal-background: #111827; + --docsearch-background-color: #1f2937; + --docsearch-text-color: #f3f4f6; + --docsearch-secondary-text-color: #d1d5db; + --docsearch-hit-background: #111827; + --docsearch-hit-focus-background: #263244; +} +``` + +## Add targeted overrides + +All component classes use the `DocSearch-` prefix. Scope selector overrides to a component and preserve visible focus states. + +```css title="custom.css" +.DocSearch-Button { + min-width: 15rem; +} + +.DocSearch-Sidepanel-Container.floating { + box-shadow: 0 1rem 3rem rgb(0 0 0 / 20%); +} + +.DocSearch-Action:focus-visible, +.DocSearch-Button:focus-visible { + outline: 2px solid var(--docsearch-focus-color); + outline-offset: 2px; +} +``` + +Don't remove the visually hidden helpers or reduced-motion rules. They support accessible labels, keyboard use, and user motion preferences. + +See the [CSS bundle and export guide](./bundle-exports) when you need component-specific assets. diff --git a/packages/website/docs/packages/docusaurus-adapter/configuration-reference.mdx b/packages/website/docs/packages/docusaurus-adapter/configuration-reference.mdx new file mode 100644 index 00000000..94dc80bd --- /dev/null +++ b/packages/website/docs/packages/docusaurus-adapter/configuration-reference.mdx @@ -0,0 +1,618 @@ +--- +title: Docusaurus adapter configuration +description: Configure DocSearch v5 search, Ask AI, the Sidepanel, and the search page in Docusaurus. +toc_max_heading_level: 2 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Add supported options under `themeConfig.docsearch`. The adapter doesn't read `themeConfig.algolia`. + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], + }, + }, +}; +``` + +## Compatibility + +| Dependency | Supported version | +| ------------------- | --------------------------------------- | +| Node.js | 20 or later | +| Docusaurus | 3.10.2 or later in the 3.x release line | +| React and React DOM | 18 or 19 | + +Keep the adapter, Docusaurus, React, and React DOM within these ranges. Don't run the adapter beside `@docusaurus/theme-search-algolia`. + +## Root options + +The validator rejects unknown root options. Pass runtime functions such as custom Agent Studio tools through a swizzled `SearchBar` instead of `themeConfig`. + +### `appId` + +> `type: string` | **required** + +Algolia application ID. + +### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +### `indices` + +> `type: Array` | **required** + +Nonempty list of keyword indices, in query order. See [Indices and search parameters](#indices-and-search-parameters). + +### `contextualSearch` + +> `type: boolean` | **optional** + +Whether to add the current Docusaurus locale, default tag, and docs-version tags to search. Defaults to `true`. See [Contextual search](#contextual-search). + +### `externalUrlRegex` + +> `type: string` | **optional** + +Regular expression that identifies result URLs that require full-page navigation. See [URL processing](#url-processing). + +### `replaceSearchResultPathname` + +> `type: { from: string | RegExp, to: string }` | **optional** + +Replace a result pathname before adding the Docusaurus base URL. See [URL processing](#url-processing). + +### `facets` + +> `type: Array<{ key: string, label?: string }>` | **optional** + +Facet controls in the search modal. Defaults to `[]`. See [Modal facets](#modal-facets). + +### `initialQuery` + +> `type: string` | **optional** + +Query placed in the modal when it opens. Defaults to `''`. + +### `insights` + +> `type: boolean | object` | **optional** + +Whether to enable Algolia Insights, or an object that configures it. Defaults to `false`. + +### `placeholder` + +> `type: string` | **optional** + +Search input placeholder. Defaults to the built-in translation. + +### `translations` + +> `type: DocSearchTranslations` | **optional** + +Search button and modal text overrides. Defaults to the Docusaurus translations. + +### `maxResultsPerGroup` + +> `type: number` | **optional** + +Maximum results shown in each modal result group. + +### `disableUserPersonalization` + +> `type: boolean` | **optional** + +Whether to disable recent searches, favorites, and stored AI conversations. Defaults to `false`. + +### `getMissingResultsUrl` + +> `type: ({ query }) => string` | **optional** + +Build the no-results report URL. + +### `keyboardShortcuts` + +> `type: object` | **optional** + +Enable or disable `Ctrl/Cmd+K`, `/`, and `Ctrl/Cmd+I`. All shortcuts are enabled by default. + +### `recentSearchesLimit` + +> `type: number` | **optional** + +Maximum recent searches when no favorites exist. Defaults to `7`. + +### `recentSearchesWithFavoritesLimit` + +> `type: number` | **optional** + +Maximum recent searches when favorites exist. Defaults to `4`. + +### `resultBadgeKey` + +> `type: string` | **optional** + +Hit property rendered as a badge in modal results. See [Result badges](#result-badges). + +### `searchPage` + +> `type: false | SearchPageConfig` | **optional** + +Configure or disable the search results page. Defaults to `{ path: 'search' }`. See [Search page](#search-page). + +### `askAi` + +> `type: AskAiConfig` | **optional** + +Configure Agent Studio for the modal and Sidepanel. See [Ask AI](#ask-ai). + +### `sidePanel` + +> `type: boolean | SidePanelConfig` | **optional** + +Whether to enable the Ask AI Sidepanel, or an object that configures it. Defaults to `false`. See [Sidepanel](#sidepanel). + +## Indices and search parameters + +Define at least one keyword index. Use a string for its default settings or an object for per-index settings: + +```js title="docusaurus.config.mjs" +indices: [ + 'docs_en', + { + name: 'api_reference', + searchParameters: { + facetFilters: ['version:v5'], + filters: 'visibility:public', + attributesToRetrieve: [ + 'content', + 'hierarchy', + 'type', + 'url', + 'version', + ], + restrictSearchableAttributes: ['hierarchy', 'content'], + distinct: true, + }, + }, +], +``` + +`searchParameters` accepts Algolia search parameters. The validator explicitly accepts `facetFilters`, `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`, and preserves other Algolia parameters. + +The modal queries every index in array order. The search page queries only the first index. + +## Contextual search + +Keep `contextualSearch: true` to limit results to the current locale and Docusaurus docs versions. The adapter merges these conditions into each index's `facetFilters` instead of replacing your filters. + +Contextual search also applies to each `askAi.indices` item. Define dynamic Agent Studio indices if Ask AI must receive these facet filters. + +Set `contextualSearch: false` when your records don't contain Docusaurus `language` and `docusaurus_tag` attributes: + +```js title="docusaurus.config.mjs" +docsearch: { + // ... + contextualSearch: false, +}, +``` + +## Modal facets + +Use root `facets` to add filter controls to the modal: + +```js title="docusaurus.config.mjs" +docsearch: { + // ... + facets: [ + { key: 'language', label: 'Language' }, + { key: 'version', label: 'Version' }, + ], +}, +``` + +Configure each attribute as an Algolia facet. The modal supports up to five unique, nonempty facet keys. It merges facet values from every keyword index and hides facets with no values. + +These controls don't configure the search page sidebar. Use `searchPage.facets` for that page. + +## Result badges + +Set `resultBadgeKey` to a property path returned by each keyword index: + +```js title="docusaurus.config.mjs" +docsearch: { + // ... + indices: [ + { + name: 'docs', + searchParameters: { + attributesToRetrieve: [ + 'content', + 'hierarchy', + 'type', + 'url', + 'version', + ], + }, + }, + ], + resultBadgeKey: 'version', +}, +``` + +Dot paths and array indices work, including `hierarchy.lvl1`, `tags[2]`, and `tags.2`. The adapter displays the badge in modal results. The built-in search page doesn't render result badges. + +## Search page + +The adapter creates `/search` by default. Change the path and sidebar facets with an object: + +```js title="docusaurus.config.mjs" +searchPage: { + path: 'find', + facets: [ + { attribute: 'hierarchy.lvl0', label: 'Section' }, + { attribute: 'version', label: 'Version' }, + ], +}, +``` + +Each facet requires `attribute`; `label` defaults to the attribute name. If `facets` is missing or empty, the page shows `hierarchy.lvl0` with the label `Section`. + +The page uses the first `indices` item and its `searchParameters`. It shows 15 results per request, stores refinements in the URL, and adds docs-version controls when contextual search and Docusaurus versioning are active. Configure every sidebar attribute as an Algolia facet. + +Disable the route, modal footer link, and OpenSearch metadata with: + +```js title="docusaurus.config.mjs" +searchPage: false, +``` + +## Ask AI + +Create an assistant by following [Get started with Agent Studio](/docs/agent-studio/getting-started). Set `askAi` to an object: + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + suggestedQuestions: true, + searchParameters: { + docs: { + filters: 'visibility:public', + attributesToRetrieve: ['title', 'content', 'url'], + distinct: true, + }, + }, + memory: { + enabled: true, + userToken: 'SERVER_GENERATED_JWT', + }, + promptSuggestions: { + indexName: 'docs_prompt_suggestions', + hitsPerPage: 3, + }, +}, +``` + +### `assistantId` + +> `type: string` | **required** + +Agent Studio assistant ID. + +### `suggestedQuestions` + +> `type: boolean` | **optional** + +Whether to show published assistant questions on the new-conversation screen. Defaults to `false`. + +### `searchParameters` + +> `type: Record` | **optional** + +Search parameters keyed by index name. Root `askAi.searchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. Don't add `facetFilters` at this level. + +### `indices` + +> `type: AgentStudioIndex[]` | **optional** + +Dynamic indices available to Agent Studio search tools. See [dynamic indices][1]. + +Use `askAi.indices` to describe dynamic indices: + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + indices: [ + { + index: 'docs_markdown', + description: 'Product documentation.', + enhancedDescription: 'Use for setup and API questions.', + searchParameters: { + facetFilters: ['language:en'], + }, + }, + ], +}, +``` + +Each item requires `index` and `description`. It can also include `enhancedDescription`, `searchParameters`, and `searchControls`. Search controls can configure `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and custom properties. + +### `memory` + +> `type: { enabled?: boolean, userToken?: string }` | **optional** + +Show memory tool calls and send a user JWT. Memory is disabled by default. See [user-scoped memory][2]. + +### `promptSuggestions` + +> `type: { indexName: string, hitsPerPage?: number }` | **optional** + +Show prompt suggestions with keyword results. `hitsPerPage` defaults to `3`. See [Configure prompt suggestions](/docs/agent-studio/prompt-suggestions). + +## Sidepanel + +Set `sidePanel: true` for the default panel. `askAi` is required whenever the Sidepanel is enabled. + +```js title="docusaurus.config.mjs" +sidePanel: { + variant: 'inline', + side: 'right', + width: 420, + expandedWidth: '60vw', + pushSelector: '#__docusaurus', + suggestedQuestions: true, + hideButton: false, + keyboardShortcuts: { + 'Ctrl/Cmd+I': true, + }, +}, +``` + +Review [hybrid mode](/docs/hybrid-mode) before changing panel behavior. + +### `variant` + +> `type: 'floating' | 'inline'` | **optional** + +Float above content or push selected content. Defaults to `'inline'`. + +### `side` + +> `type: 'left' | 'right'` | **optional** + +Side where the panel opens. Defaults to `'right'`. + +### `width` + +> `type: number | string` | **optional** + +Collapsed panel width. Numbers represent pixels. Defaults to `360px`. + +### `expandedWidth` + +> `type: number | string` | **optional** + +Expanded panel width. Numbers represent pixels. Defaults to `580px`. + +### `pushSelector` + +> `type: string` | **optional** + +Element pushed by the inline panel. Defaults to `#__docusaurus`. + +### `suggestedQuestions` + +> `type: boolean` | **optional** + +Whether to show suggested questions in the panel. Defaults to `askAi.suggestedQuestions`. + +### `translations` + +> `type: SidepanelTranslations` | **optional** + +Panel text overrides. Defaults to the built-in strings. + +### `hideButton` + +> `type: boolean` | **optional** + +Whether to hide the Sidepanel button while keeping the panel registered. Defaults to `false`. + +### `portalContainer` + +> `type: DocumentFragment | Element | null` | **optional** + +Element that receives the panel portal. Defaults to `document.body`. Pass this option through a swizzled `SearchBar` because a DOM element isn't available while Docusaurus evaluates its server configuration. + +### `keyboardShortcuts` + +> `type: { 'Ctrl/Cmd+I'?: boolean }` | **optional** + +Enable or disable the panel shortcut. The shortcut is enabled by default. + +### `indices` + +> `type: AgentStudioIndex[]` | **optional** + +Override Agent Studio indices for the panel. Defaults to `askAi.indices`. See [dynamic indices][1]. + +### `memory` + +> `type: { enabled?: boolean, userToken?: string }` | **optional** + +Override memory for the panel. Defaults to `askAi.memory`. See [user-scoped memory][2]. + +## Custom tools + +Docusaurus can't serialize tool functions in `themeConfig`. The adapter rejects both `askAi.tools` and `sidePanel.tools` there. + +Swizzle `SearchBar` from `@docsearch/docusaurus-adapter`, then pass tools as component props: + +```bash +npm run swizzle -- @docsearch/docusaurus-adapter SearchBar --eject +``` + +Replace the generated component with one of these examples: + + + + +```tsx title="src/theme/SearchBar/index.tsx" +import type { DocusaurusSearchBarProps } from '@docsearch/docusaurus-adapter'; +import type { ToolCalls } from '@docsearch/react'; +import OriginalSearchBar from '@theme-original/SearchBar'; + +const tools: ToolCalls = { + getReleaseStatus: { + render: ({ message }) => JSON.stringify(message.output), + }, +}; + +export default function SearchBar(props: DocusaurusSearchBarProps) { + return ( + + ); +} +``` + + + + +```jsx title="src/theme/SearchBar/index.js" +import OriginalSearchBar from '@theme-original/SearchBar'; + +const tools = { + getReleaseStatus: { + render: ({ message }) => JSON.stringify(message.output), + }, +}; + +export default function SearchBar(props) { + return ( + + ); +} +``` + + + + +Passing `askAi` or `sidePanel` as a prop replaces that nested theme-config value. Include every nested option that you want to keep in the prop object. See [Agent Studio tools](/docs/agent-studio/tools) for tool renderers and client-side handlers. + +## Translations + +Override only the modal strings you need: + +```js title="docusaurus.config.mjs" +translations: { + button: { + buttonText: 'Search API docs', + buttonAriaLabel: 'Search API docs', + }, + modal: { + searchBox: { + placeholderText: 'Search API docs', + }, + facets: { + clearAllLabel: 'Reset filters', + }, + resultsScreen: { + resultBadgeLabelText: 'Version', + }, + }, +}, +``` + +The adapter uses Docusaurus translation IDs for its default search button, modal, and search page strings. Run the Docusaurus `write-translations` command to localize built-in strings. Put Sidepanel overrides under `sidePanel.translations`. + +## URL processing + +The adapter parses each result URL. It leaves URLs matching `externalUrlRegex` unchanged and uses full-page navigation for them. For other URLs, it keeps the pathname, query, and hash, applies `replaceSearchResultPathname`, and adds the Docusaurus base URL. + +```js title="docusaurus.config.mjs" +docsearch: { + // ... + externalUrlRegex: '^https://external\\.example\\.com/', + replaceSearchResultPathname: { + from: '/legacy-docs/', + to: '/docs/', + }, +}, +``` + +A string `from` value is treated literally. A `RegExp` is converted to its source during validation. + +## Validation errors + +The adapter reports dedicated errors for removed or unsupported v4 options. Use the replacement named in each message: + +```text +`themeConfig.algolia` is no longer supported by @docsearch/docusaurus-adapter v5. Move the configuration to `themeConfig.docsearch`. + +`themeConfig.docsearch.indexName` was removed. Use `themeConfig.docsearch.indices` instead. + +`themeConfig.docsearch.searchParameters` was removed. Configure `searchParameters` on each `themeConfig.docsearch.indices` entry instead. + +`themeConfig.docsearch.searchPagePath` was removed. Use `themeConfig.docsearch.searchPage` instead. + +`themeConfig.docsearch.askAi` must be an object with `assistantId`. + +`themeConfig.docsearch.askAi.agentStudio` was removed. The adapter now only supports Agent Studio. + +`themeConfig.docsearch.askAi.indexName`, `apiKey`, and `appId` were removed. Use the top-level DocSearch credentials instead. + +`themeConfig.docsearch.askAi.sidePanel` was removed. Use `themeConfig.docsearch.sidePanel` instead. + +`themeConfig.docsearch.sidePanel` requires `themeConfig.docsearch.askAi`. +``` + +Tool definitions report these errors: + +```text +`themeConfig.docsearch.askAi.tools` is not supported because Docusaurus removes function values when serializing theme config. Pass custom tools through a swizzled `@theme/SearchBar` component instead: use `askAi` for the modal and `sidePanel` for the side panel. + +`themeConfig.docsearch.sidePanel.tools` is not supported because Docusaurus removes function values when serializing theme config. Pass custom tools through a swizzled `@theme/SearchBar` component instead: use `askAi` for the modal and `sidePanel` for the side panel. +``` + +The schema also reports these messages for missing or invalid required configuration: + +```text +"themeConfig.docsearch" is required +"docsearch.appId" is required. If you haven't migrated to the new DocSearch infra, please refer to the blog post for instructions: https://docusaurus.io/blog/2021/11/21/algolia-docsearch-migration +"docsearch.apiKey" is required +"docsearch.indices" is required +"docsearch.indices" must contain at least 1 items +"docsearch.unknownKey" is not allowed +"docsearch.askAi.indices" must contain at least 1 items +"docsearch.askAi.indices[0].description" is required +"docsearch.sidePanel.indices" must contain at least 1 items +"docsearch.sidePanel.indices[0].description" is required +``` + +Replace `unknownKey` with the rejected option name. Other invalid nested values use the same Joi path format. + +[1]: /docs/agent-studio/dynamic-indices +[2]: /docs/agent-studio/memory diff --git a/packages/website/docs/packages/docusaurus-adapter/getting-started.mdx b/packages/website/docs/packages/docusaurus-adapter/getting-started.mdx new file mode 100644 index 00000000..7523afb2 --- /dev/null +++ b/packages/website/docs/packages/docusaurus-adapter/getting-started.mdx @@ -0,0 +1,142 @@ +--- +title: Docusaurus adapter +description: Add DocSearch v5 keyword search and Agent Studio answers to a Docusaurus site. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Use `@docsearch/docusaurus-adapter` to add keyword search, a search results page, Ask AI, and an Ask AI Sidepanel to Docusaurus. + +## Before you start + +Collect these values: + +- An Algolia application ID. +- A Search API key with access to your DocSearch indices. +- At least one DocSearch index name. +- An Agent Studio assistant ID if you want Ask AI or the Sidepanel. Follow [Get started with Agent Studio](/docs/agent-studio/getting-started) to create one. + +Use Node.js 20 or later, Docusaurus 3.10.2 or later in the Docusaurus 3 release line, and React 18 or 19. + +## Install the adapter + +Install `@docsearch/docusaurus-adapter@^5.0.0-beta`: + + + + +```bash +npm install @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +Keep `@docusaurus/preset-classic`. Don't add `@docusaurus/theme-search-algolia` as another search integration. + +## Configure keyword search + +Add the adapter to `plugins`. Configure it under `themeConfig.docsearch`: + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [{ name: 'YOUR_INDEX_NAME' }], + }, + }, +}; +``` + +`indices` is required and must contain at least one index. Use an object to set search parameters for one index: + +```js title="docusaurus.config.mjs" +indices: [ + { + name: 'docs', + searchParameters: { + facetFilters: ['language:en'], + attributesToRetrieve: [ + 'content', + 'hierarchy', + 'type', + 'url', + 'version', + ], + }, + }, +], +``` + +Start Docusaurus and open the search modal. The adapter also creates `/search` and links to it from the modal. Change or disable that route with [`searchPage`](./configuration-reference#search-page). + +## Add Ask AI + +Set `askAi` to an object with your Agent Studio assistant ID: + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [{ name: 'YOUR_INDEX_NAME' }], + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + }, + }, + }, +}; +``` + +The adapter uses Agent Studio for Ask AI. Pass an object, not an assistant ID string. It reuses the root `appId`, `apiKey`, and first keyword index unless you configure dynamic Agent Studio indices. + +## Add the Sidepanel + +Set `sidePanel` at the root of `docsearch`. You must also configure `askAi`: + +```js title="docusaurus.config.mjs" +docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [{ name: 'YOUR_INDEX_NAME' }], + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + }, + sidePanel: true, +}, +``` + +Pass an object instead of `true` to configure its placement, width, questions, translations, memory, or indices. The modal and Sidepanel share the DocSearch provider. Review [hybrid mode](/docs/hybrid-mode) for their responsive behavior. + +## Next steps + +- Review every adapter option in the [configuration reference](./configuration-reference). +- Follow [Migrate from v4](./migrating-from-v4) if your site uses `themeConfig.algolia`, `indexName`, root `searchParameters`, or `askAi.sidePanel`. +- Review the package-level [DocSearch v4 migration guide](/docs/migrating-from-v4). diff --git a/packages/website/docs/packages/docusaurus-adapter/migrating-from-v4.mdx b/packages/website/docs/packages/docusaurus-adapter/migrating-from-v4.mdx new file mode 100644 index 00000000..3983aee9 --- /dev/null +++ b/packages/website/docs/packages/docusaurus-adapter/migrating-from-v4.mdx @@ -0,0 +1,388 @@ +--- +title: Migrate the Docusaurus adapter from v4 +description: Move a Docusaurus DocSearch adapter configuration from v4 to the v5 beta. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +DocSearch v5 requires `themeConfig.docsearch`, a nonempty `indices` array, and Agent Studio for Ask AI. Update the adapter and configuration together. + +Review the broader [DocSearch v4 migration guide](/docs/migrating-from-v4) for changes outside the Docusaurus adapter. + +## 1. Check compatibility + +Upgrade the site to Node.js 20 or later and Docusaurus 3.10.2 or later in the Docusaurus 3 release line. Use React and React DOM 18 or 19. + +## 2. Install the v5 adapter + +Install `@docsearch/docusaurus-adapter@^5.0.0-beta`: + + + + +```bash +npm install @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/docusaurus-adapter@^5.0.0-beta +``` + + + + +Keep the adapter in `plugins` and don't add `@docusaurus/theme-search-algolia` as another search integration. + +## 3. Move to `themeConfig.docsearch` + +V4 accepted `themeConfig.algolia` as an alias. V5 rejects it. + + + + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + algolia: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indexName: 'docs', + }, + }, +}; +``` + + + + +```js title="docusaurus.config.mjs" +export default { + plugins: ['@docsearch/docusaurus-adapter'], + themeConfig: { + docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [{ name: 'docs' }], + }, + }, +}; +``` + + + + +Don't define both keys during the migration. V5 accepts only `themeConfig.docsearch`. + +## 4. Replace `indexName` and root search parameters + +Move every keyword index into `indices`. Move root `searchParameters` onto the matching index: + + + + +```js title="docusaurus.config.mjs" +docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indexName: 'docs', + searchParameters: { + facetFilters: ['language:en'], + attributesToRetrieve: ['content', 'hierarchy', 'type', 'url'], + }, +}, +``` + + + + +```js title="docusaurus.config.mjs" +docsearch: { + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: [ + { + name: 'docs', + searchParameters: { + facetFilters: ['language:en'], + attributesToRetrieve: ['content', 'hierarchy', 'type', 'url'], + }, + }, + ], +}, +``` + + + + +`indices` is required and must contain at least one item. The modal queries all items in order. The search page uses the first item. + +## 5. Replace `searchPagePath` + +V5 replaces the path value with an object that can also configure facets: + + + + +```js title="docusaurus.config.mjs" +searchPagePath: 'find', +``` + + + + +```js title="docusaurus.config.mjs" +searchPage: { + path: 'find', + facets: [ + { attribute: 'hierarchy.lvl0', label: 'Section' }, + { attribute: 'version', label: 'Version' }, + ], +}, +``` + + + + +Use `searchPage: false` to disable the route. An empty object uses the default `search` path and the default `hierarchy.lvl0` section facet. + +## 6. Move Ask AI to Agent Studio + +Create an assistant by following [Get started with Agent Studio](/docs/agent-studio/getting-started). V5 accepts only an `askAi` object and always uses Agent Studio. + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + appId: 'ASK_AI_APPLICATION_ID', + apiKey: 'ASK_AI_SEARCH_API_KEY', + indexName: 'docs_markdown', + agentStudio: true, +}, +``` + +V4 also accepted this shorthand: + +```js title="docusaurus.config.mjs" +askAi: 'YOUR_ASSISTANT_ID', +``` + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + indices: [ + { + index: 'docs_markdown', + description: 'Product documentation.', + }, + ], +}, +``` + + + + +Remove `agentStudio`, `appId`, `apiKey`, and `indexName` from `askAi`. The adapter reuses the root credentials. Without `askAi.indices`, it uses the first keyword index as the Ask AI index. + +V4 supported flat search parameters for the legacy Ask AI backend. V5 requires Agent Studio search parameters keyed by index name: + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + searchParameters: { + filters: 'language:en', + attributesToRetrieve: ['title', 'content', 'url'], + }, +}, +``` + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + searchParameters: { + docs: { + filters: 'language:en', + attributesToRetrieve: ['title', 'content', 'url'], + }, + }, +}, +``` + + + + +Root `askAi.searchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. Put `facetFilters` on a dynamic `askAi.indices` item's `searchParameters` instead. + +## 7. Move the Sidepanel to the root + +Move `sidePanel` out of `askAi`: + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + sidePanel: { + variant: 'inline', + side: 'right', + }, +}, +``` + + + + +```js title="docusaurus.config.mjs" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', +}, +sidePanel: { + variant: 'inline', + side: 'right', +}, +``` + + + + +The root `sidePanel` requires `askAi`. It can override Agent Studio `indices`, `memory`, `suggestedQuestions`, and translations for the panel. Review [hybrid mode](/docs/hybrid-mode) for modal and panel behavior. + +## 8. Move custom tools into `SearchBar` + +V5 rejects `askAi.tools` and `sidePanel.tools` in `docusaurus.config` because Docusaurus removes functions while serializing theme config. Swizzle `@theme/SearchBar` and pass tools as component props. + +```bash +npm run swizzle -- @docsearch/docusaurus-adapter SearchBar --eject +``` + + + + +```tsx title="src/theme/SearchBar/index.tsx" +import type { DocusaurusSearchBarProps } from '@docsearch/docusaurus-adapter'; +import type { ToolCalls } from '@docsearch/react'; +import OriginalSearchBar from '@theme-original/SearchBar'; + +const tools: ToolCalls = { + getReleaseStatus: { + render: ({ message }) => JSON.stringify(message.output), + }, +}; + +export default function SearchBar(props: DocusaurusSearchBarProps) { + return ( + + ); +} +``` + + + + +```jsx title="src/theme/SearchBar/index.js" +import OriginalSearchBar from '@theme-original/SearchBar'; + +const tools = { + getReleaseStatus: { + render: ({ message }) => JSON.stringify(message.output), + }, +}; + +export default function SearchBar(props) { + return ( + + ); +} +``` + + + + +Include every nested `askAi` and `sidePanel` option that you want to keep because component props replace those nested theme-config values. See [Agent Studio tools](/docs/agent-studio/tools) for complete tool definitions. + +## 9. Add v5 search features + +Configure modal facets at the `docsearch` root: + +```js title="docusaurus.config.mjs" +facets: [ + { key: 'language', label: 'Language' }, + { key: 'version', label: 'Version' }, +], +``` + +Configure search-page facets separately under `searchPage.facets`. Configure every facet attribute in your Algolia index. + +Show a custom hit property in modal results with `resultBadgeKey`. Add that property to each index's `attributesToRetrieve`: + +```js title="docusaurus.config.mjs" +indices: [ + { + name: 'docs', + searchParameters: { + attributesToRetrieve: [ + 'content', + 'hierarchy', + 'type', + 'url', + 'version', + ], + }, + }, +], +resultBadgeKey: 'version', +``` + +## 10. Verify the migration + +Run the production Docusaurus build, then verify these paths: + +- Open keyword search with the button, `Ctrl/Cmd+K`, and `/`. +- Search every configured index and apply each modal facet. +- Open the search page, apply its facets, and check docs-version filtering. +- Open Ask AI and submit a follow-up question. +- Open the Sidepanel with its button and `Ctrl/Cmd+I`. +- Check contextual results in every locale and docs version. +- Follow internal, replaced, and external result URLs. +- Check translated strings and result badges. +- Test mobile behavior. Hybrid mode uses the modal instead of the Sidepanel on mobile. + +Use the [configuration reference](./configuration-reference) to resolve validation messages and review every v5 option. diff --git a/packages/website/docs/packages/js/api-reference.mdx b/packages/website/docs/packages/js/api-reference.mdx new file mode 100644 index 00000000..58f2e03c --- /dev/null +++ b/packages/website/docs/packages/js/api-reference.mdx @@ -0,0 +1,487 @@ +--- +title: JS package API reference +description: Configure @docsearch/js 5.0.0-beta.0 and control its returned instance. +toc_max_heading_level: 2 +--- + +## `docsearch(options)` + +Renders DocSearch in `options.container` and returns a `DocSearchInstance`. + +```ts title="load-docsearch.ts" +import docsearch from '@docsearch/js'; + +const instance = docsearch(options); +``` + +The default export from `@docsearch/js` is AI-capable and uses `DocSearchAI`. The default export from `@docsearch/js/docsearch` is keyword-only and uses `DocSearch`. + +## JavaScript options + +### `container` + +> `type: HTMLElement | string` | **required** + +Container element or CSS selector for the search button. A selector resolves against `environment.document` and must match an element. + +### `environment` + +> `type: typeof window` | **optional** + +Browser-like environment used to resolve a string `container`. Defaults to `window`. + +### `onReady` + +> `type: () => void` | **optional** + +Callback after DocSearch mounts. + +### `onOpen` + +> `type: () => void` | **optional** + +Callback when the modal opens. + +### `onClose` + +> `type: () => void` | **optional** + +Callback when the modal closes. + +### `interceptAskAiEvent` + +> `type: (initialMessage: InitialAskAiMessage) => boolean | void` | **optional** + +Callback before DocSearch starts an Ask AI request. Return `true` to prevent the modal from toggling or sending the message. Use this option to route the request to another view, such as the Sidepanel. + +`InitialAskAiMessage` contains `query` and can contain `messageId` or `suggestedQuestionId`. + +## Search options + +These options apply to both package entries. + +### `appId` + +> `type: string` | **required** + +Algolia application ID. + +### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +### `indices` + +> `type: Array` | **optional** + +Indices used for keyword search, in display order. There's no default, and at least `indices` or `indexName` is required. + +Use a string for default search parameters or a `DocSearchIndex` for per-index parameters: + +```ts +interface DocSearchIndex { + name: string; + searchParameters?: SearchParamsObject; +} +``` + +```js title="docsearch-options.js" +indices: [ + { + name: 'docs_en', + searchParameters: { + facetFilters: ['version:v5'], + attributesToRetrieve: [ + 'hierarchy.lvl0', + 'hierarchy.lvl1', + 'hierarchy.lvl2', + 'hierarchy.lvl3', + 'hierarchy.lvl4', + 'hierarchy.lvl5', + 'hierarchy.lvl6', + 'content', + 'type', + 'url', + 'version', + ], + }, + }, + 'docs_fr', +]; +``` + +If you pass both `indexName` and `indices`, DocSearch queries `indexName` first, then each `indices` item. `indexName` and the root `searchParameters` remain available for v4 compatibility but are deprecated. + +### `indexName` + +> `type: string` | **optional** + +Deprecated index name. There's no default. Use `indices`. + +### `facets` + +> `type: DocSearchFacet[]` | **optional** + +Facet controls populated from the configured indices. Defaults to `[]`. + +```ts +interface DocSearchFacet { + key: string; + label?: string; +} +``` + +DocSearch supports up to five facets. It compares trimmed, lowercase keys to ignore duplicates and empty keys, fetches values from all configured indices, and displays only facets that have values. Selecting a value adds a `facetFilters` entry to every index query while retaining that index's configured filters. + +```js title="docsearch-options.js" +facets: [ + { key: 'language', label: 'Language' }, + { key: 'version', label: 'Version' }, +]; +``` + +Configure each attribute for faceting in the Algolia index before exposing it here. + +### `theme` + +> `type: 'light' | 'dark'` | **optional** + +Theme written to `document.documentElement.dataset.theme`. By default, DocSearch leaves the current theme unchanged. + +### `placeholder` + +> `type: string` | **optional** + +Search input placeholder. The default is experience-specific. + +### `searchParameters` + +> `type: SearchParamsObject` | **optional** + +Deprecated search parameters for `indexName`. There's no default. Put them on an `indices` item. + +### `maxResultsPerGroup` + +> `type: number` | **optional** + +Maximum results in each result group. There's no default. + +### `transformItems` + +> `type: (items: DocSearchHit[]) => DocSearchHit[]` | **optional** + +Function that transforms hits before grouping and rendering. Defaults to the identity function. + +### `hitComponent` + +> `type: template function` | **optional** + +Template for a result link. Defaults to the built-in hit template. See [Templates](#templates). + +### `resultsFooterComponent` + +> `type: template function` | **optional** + +Template below the result collections. There's no default. See [Templates](#templates). + +### `transformSearchClient` + +> `type: (client) => client` | **optional** + +Function that wraps or replaces the Algolia search client. Defaults to the identity function. + +### `disableUserPersonalization` + +> `type: boolean` | **optional** + +Whether to disable recent searches, favorites, and stored AI conversations. Defaults to `false`. + +### `initialQuery` + +> `type: string` | **optional** + +Query placed in the input when the modal opens. Defaults to `''`. + +### `navigator` + +> `type: AutocompleteOptions['navigator']` | **optional** + +Autocomplete navigation implementation. Defaults to the default navigator. + +### `translations` + +> `type: DocSearchTranslations` | **optional** + +Button and modal text overrides. Defaults to the English strings. + +### `getMissingResultsUrl` + +> `type: ({ query }) => string` | **optional** + +Function that builds the no-results report URL. There's no default. + +### `insights` + +> `type: AutocompleteOptions['insights']` | **optional** + +Algolia Insights integration options. Defaults to `false`. + +### `portalContainer` + +> `type: DocumentFragment | Element` | **optional** + +Element that receives the modal portal. Defaults to `document.body`. + +### `recentSearchesLimit` + +> `type: number` | **optional** + +Maximum recent searches without favorites. Defaults to `7`. + +### `recentSearchesWithFavoritesLimit` + +> `type: number` | **optional** + +Maximum recent searches when favorites exist. Defaults to `4`. + +### `keyboardShortcuts` + +> `type: DocSearchModalShortcuts` | **optional** + +Whether `Ctrl/Cmd+K` and `/` open the modal. Both shortcuts are enabled by default. Escape always closes it. + +### `resultBadgeKey` + +> `type: string` | **optional** + +Hit property rendered as a result badge. There's no default. + +The key supports property paths such as `version`, `hierarchy.lvl1`, `tags[2]`, and `tags.2`. Primitive values render as text. Arrays of primitive values render as a comma-separated list. + +Add custom badge data to `attributesToRetrieve`. Otherwise the property isn't present in the hit: + +```js title="docsearch-options.js" +indices: [ + { + name: 'docs', + searchParameters: { + attributesToRetrieve: [ + 'hierarchy.lvl0', + 'hierarchy.lvl1', + 'hierarchy.lvl2', + 'hierarchy.lvl3', + 'hierarchy.lvl4', + 'hierarchy.lvl5', + 'hierarchy.lvl6', + 'content', + 'type', + 'url', + 'version', + ], + }, + }, +], +resultBadgeKey: 'version', +``` + +Set `translations.modal.resultsScreen.resultBadgeLabelText` to describe the badge to screen-reader users. Its default is `Category`. + +### Templates + +`hitComponent` receives `{ hit, children }`. `resultsFooterComponent` receives `{ state }`. JavaScript templates can return a Preact element, a string, or a component function. The optional second argument provides an `html` tagged-template helper. + +```js title="docsearch-options.js" +hitComponent({ hit, children }, { html }) { + return html`${children}`; +} +``` + +String returns render as text, not HTML. + +## Ask AI options + +Ask AI is available from the default `@docsearch/js` entry. Its `askAi` option is required by that entry's `DocSearchProps` type. + +### `askAi` + +> `type: string | DocSearchAskAi` | **required** + +Assistant ID or Agent Studio configuration. The default entry requires it. + +```js title="docsearch-options.js" +askAi: 'YOUR_ASSISTANT_ID'; +``` + +Use an object for additional controls. + +Follow [Get started with Agent Studio](/docs/agent-studio/getting-started) to create the assistant and [hybrid mode](/docs/hybrid-mode) to route AI requests to a Sidepanel. + +#### `assistantId` + +> `type: string` | **required** + +Agent Studio assistant ID. + +#### `appId` + +> `type: string` | **optional** + +Application ID used by Ask AI. Defaults to the root `appId`. + +#### `apiKey` + +> `type: string` | **optional** + +API key used by Ask AI. Defaults to the root `apiKey`. + +#### `indexName` + +> `type: string` | **optional** + +Index used by Ask AI. Defaults to the first normalized keyword index. + +#### `suggestedQuestions` + +> `type: boolean` | **optional** + +Whether to show published assistant questions on the new-conversation screen. Defaults to `false`. + +#### `searchParameters` + +> `type: AgentStudioSearchParameters` | **optional** + +Search parameters keyed by index name. There's no default. + +Each value supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. This Agent Studio shape doesn't accept `facetFilters`. + +```js title="docsearch-options.js" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + searchParameters: { + docs: { + filters: 'language:en', + attributesToRetrieve: ['title', 'content', 'url'], + distinct: true, + }, + }, +} +``` + +#### `indices` + +> `type: AgentStudioIndices[]` | **optional** + +Dynamic indices available to the Agent Studio search tool. There's no default. + +Each `AgentStudioIndices` item requires `index` and `description`. It can also define `enhancedDescription`, `searchParameters`, and `searchControls`. + +`searchControls` supports `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`. The `exposed` flag controls whether the model can set a value. Constraints set allowed numeric ranges or string-array values. + +```js title="docsearch-options.js" +askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + indices: [ + { + index: 'api_reference', + description: 'API symbols and parameter reference', + enhancedDescription: 'Use for questions about methods and options.', + searchControls: { + hits_per_page: { + exposed: true, + default: 7, + constraint: { min: 1, max: 10 }, + }, + facets: { + exposed: false, + default: ['version'], + }, + }, + }, + ], +} +``` + +#### `tools` + +> `type: ToolCalls` | **optional** + +Custom Agent Studio tool renderers and handlers. Defaults to `{}`. + +`ToolCalls` maps Agent Studio tool names to `ToolDefinition` objects. `render` converts the tool input and output to displayed text. `onToolCall` handles a client-side tool and must call `addToolOutput` when it produces a result. `translations.callingToolText` changes the pending label. + +#### `memory` + +> `type: Memory` | **optional** + +Agent Studio memory display and user token. Memory is disabled by default. + +```js title="docsearch-options.js" +memory: { + enabled: true, + userToken: 'SERVER_GENERATED_JWT_TOKEN', +} +``` + +`enabled` controls whether memory tool calls appear. `userToken` is the JWT sent in the `x-algolia-secure-user-token` header. + +#### `promptSuggestions` + +> `type: PromptSuggestions` | **optional** + +Prompt suggestions displayed with keyword results. There's no default. + +```js title="docsearch-options.js" +promptSuggestions: { + indexName: 'docsearch_prompt_suggestions', + hitsPerPage: 3, +} +``` + +The index records must contain a `prompt` attribute. `hitsPerPage` defaults to `3`. + +## `DocSearchInstance` + +### `isReady` + +> `type: readonly boolean` + +Whether the instance is mounted. + +### `isOpen` + +> `type: readonly boolean` + +Whether the modal is open. + +### `open` + +> `type: () => void` + +Opens keyword search. + +### `close` + +> `type: () => void` + +Closes the modal. + +### `openAskAi` + +> `type: (initialMessage?: InitialAskAiMessage) => void` + +Opens Ask AI with an optional query. Use with the AI-capable entry. + +### `destroy` + +> `type: () => void` + +Unmounts DocSearch and marks the instance not ready. + +## Compatibility and deprecations + +- The bundles target ES2017 browsers. +- `indexName` and root `searchParameters` remain supported but are deprecated. Move to `indices`. +- The default entry uses Agent Studio. The v4 Ask AI transport and `askAi.agentStudio` switch aren't available. +- The keyword-only `/docsearch` export is the smaller choice when you don't configure Ask AI. diff --git a/packages/website/docs/packages/js/getting-started.mdx b/packages/website/docs/packages/js/getting-started.mdx new file mode 100644 index 00000000..9bbfcf29 --- /dev/null +++ b/packages/website/docs/packages/js/getting-started.mdx @@ -0,0 +1,168 @@ +--- +title: JS package +description: Add DocSearch v5 keyword search or Agent Studio answers to a JavaScript site. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +Use `@docsearch/js` to render DocSearch into an HTML element. The default entry includes keyword search and Ask AI. A separate entry includes keyword search only. + +## Before you start + +Collect your Algolia application ID, Search API key, and index name. To add Ask AI, also create an assistant in [Agent Studio](/docs/agent-studio/getting-started) and copy its assistant ID. + +## Install the packages + + + + +```bash +npm install @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Add a container where you want the search button: + +```html title="index.html" +
+``` + +Pass a container element or a selector that matches one. Don't pass an `input`; DocSearch renders the search button and input. + +## Add keyword search and Ask AI + +Import the default entry and provide an `askAi` configuration: + +```js title="app.js" +import docsearch from '@docsearch/js'; + +import '@docsearch/css'; + +const search = docsearch({ + container: '#docsearch', + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], + askAi: { + assistantId: 'YOUR_ASSISTANT_ID', + }, +}); +``` + +The default entry bundles both experiences. `askAi` accepts an assistant ID string or a configuration object. See the [JavaScript API reference](./api-reference#ask-ai-options). + +## Add keyword search only + +Import the `/docsearch` entry to exclude Ask AI code: + +```js title="app.js" +import docsearch from '@docsearch/js/docsearch'; + +import '@docsearch/css'; + +const search = docsearch({ + container: '#docsearch', + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], +}); +``` + +## Load DocSearch from a CDN + +Load the complete stylesheet and one JavaScript bundle. Both UMD bundles expose `window.docsearch`. + +### Keyword search and Ask AI + +```html title="index.html" + + + +``` + +### Keyword search only + +```html title="index.html" + + + +``` + +Don't load both UMD bundles on the same page. The second bundle replaces the same `window.docsearch` global. + +## Control the instance + +`docsearch()` returns a `DocSearchInstance`: + +```js title="app.js" +const search = docsearch({ + container: '#docsearch', + appId: 'YOUR_APP_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + indices: ['YOUR_INDEX_NAME'], + askAi: 'YOUR_ASSISTANT_ID', +}); + +search.open(); +search.close(); +search.openAskAi({ query: 'How do I configure search?' }); + +// Unmount DocSearch when your application removes this view. +search.destroy(); +``` + +Use `openAskAi()` only with the default AI-capable entry. + +## Next steps + +- Review every option in the [JavaScript API reference](./api-reference). +- Add multiple indices, facets, or result badges in the [React examples](../react/examples). The configuration options also apply to JavaScript. +- Customize the design in [Styling](/docs/packages/css/styling). +- Combine the modal and Sidepanel in [hybrid mode](/docs/hybrid-mode). diff --git a/packages/website/docs/packages/modal/api.mdx b/packages/website/docs/packages/modal/api.mdx new file mode 100644 index 00000000..ea81a814 --- /dev/null +++ b/packages/website/docs/packages/modal/api.mdx @@ -0,0 +1,343 @@ +--- +title: Modal API reference +description: API reference for @docsearch/modal v5 beta. +--- + +## `DocSearchButton` + +> `type: React.ComponentType` + +Renders the search trigger. It runs your `onClick` handler, then opens the modal through the nearest `DocSearch` provider. + +`DocSearchButtonProps` accepts standard React `button` props and the following prop. Configure `theme` and `keyboardShortcuts` on `DocSearch`, not on this component. + +### `translations` + +> `type: { buttonText?: string; buttonAriaLabel?: string }` | **optional** + +Sets the visible and accessible button text. Both values default to English labels. + +## `DocSearchModal` + +> `type: React.ComponentType` + +Renders a keyword-search modal when its provider is active. It renders in `document.body` unless you set [`portalContainer`](#portalcontainer). + +### Required props + +#### `appId` + +> `type: string` | **required** + +Algolia application ID. + +#### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +#### `indices` + +> `type: Array` | **required** + +Indices to search. You can omit this prop only if you use the deprecated [`indexName`](#indexname). + +### Search props + +#### `indexName` + +> `type: string` | **optional** | **deprecated** + +Sets one index to search. Use [`indices`](#indices) instead. + +#### `facets` + +> `type: Array<{ key: string; label?: string }>` | **optional** + +Adds filter controls that use facet values from the configured indices. Defaults to `[]`. + +#### `placeholder` + +> `type: string` | **optional** + +Sets the search input placeholder. Defaults to `Search docs`. A translation can override this value. + +#### `searchParameters` + +> `type: SearchParamsObject` | **optional** | **deprecated** + +Merges parameters into search requests. Set parameters on each [`indices`](#indices) entry instead. + +#### `maxResultsPerGroup` + +> `type: number` | **optional** + +Limits the displayed hits in each result group. + +#### `transformItems` + +> `type: (items: DocSearchHit[]) => DocSearchHit[]` | **optional** + +Changes hits before rendering. Defaults to the identity function. + +#### `transformSearchClient` + +> `type: (client: DocSearchTransformClient) => DocSearchTransformClient` | **optional** + +Wraps or changes the search client. Defaults to the identity function. + +#### `navigator` + +> `type: AutocompleteOptions['navigator']` | **optional** + +Controls link navigation. + +#### `insights` + +> `type: AutocompleteOptions['insights']` | **optional** + +Configures Algolia Insights. Defaults to `false`. + +#### `resultBadgeKey` + +> `type: string` | **optional** + +Reads a hit property and displays it as a result badge. Include the property in `attributesToRetrieve`. + +### Rendering and behavior props + +#### `initialQuery` + +> `type: string` | **optional** + +Prefills the search input. This value takes precedence over the provider value and defaults to `''` if neither value is set. + +#### `portalContainer` + +> `type: DocumentFragment | Element` | **optional** + +Receives the modal portal. Defaults to `document.body`. + +#### `hitComponent` + +> `type: (props, helpers?) => JSX.Element` | **optional** + +Renders an individual result. Defaults to the built-in hit component. + +#### `resultsFooterComponent` + +> `type: (props, helpers?) => JSX.Element | null` | **optional** + +Renders content below the results. Defaults to `null`. + +#### `disableUserPersonalization` + +> `type: boolean` | **optional** + +Disables storing and using recent and favorite searches. Defaults to `false`. + +#### `recentSearchesLimit` + +> `type: number` | **optional** + +Limits saved and displayed recent searches. Defaults to `7`. + +#### `recentSearchesWithFavoritesLimit` + +> `type: number` | **optional** + +Limits recent searches when favorites exist. Defaults to `4`. + +#### `getMissingResultsUrl` + +> `type: ({ query }: { query: string }) => string` | **optional** + +Builds the missing-results report URL. + +#### `translations` + +> `type: ModalTranslations` | **optional** + +Supplies partial strings for `searchBox`, `footer`, `facets`, `errorScreen`, `startScreen`, `noResultsScreen`, and `resultsScreen`. Defaults to `{}`. + +`DocSearchModal` receives `theme`, `keyboardShortcuts`, and close behavior from the provider. It doesn't accept these props directly. + +### `DocSearchIndex` + +#### `name` + +> `type: string` | **required** + +Index to search. + +#### `searchParameters` + +> `type: SearchParamsObject` | **optional** + +Sets search parameters for this index. + +## `DocSearchAskAiModal` + +> `type: React.ComponentType` + +Renders the Agent Studio-enabled modal. It accepts every `DocSearchModal` prop, requires [`askAi`](#askai), and adds Agent Studio translations. + +### `askAi` + +> `type: string | DocSearchAskAi` | **required** + +Sets the Agent Studio agent ID or the complete Agent Studio configuration. + +### `interceptAskAiEvent` + +> `type: (message: InitialAskAiMessage) => boolean | void` | **optional** + +Runs before the default Ask AI action. Return `true` to prevent the action. + +### `translations` + +> `type: DocSearchAskAiModalTranslations` | **optional** + +Adds `askAiScreen`, `newConversation`, and Agent Studio search-box strings to the search translations. Defaults to `{}`. + +The component receives its active state and close behavior from `DocSearch`. It doesn't accept `isAskAiActive`, `isHybridModeSupported`, `onAskAiToggle`, `onClose`, `theme`, or `keyboardShortcuts`. See [Hybrid Mode][1] for cross-view behavior. + +## `DocSearchAskAi` + +The object form of [`askAi`](#askai). It accepts the following fields. + +### `assistantId` + +> `type: string` | **required** + +Agent Studio agent ID. + +### `appId` + +> `type: string` | **optional** + +Overrides the root `appId` for Agent Studio. + +### `apiKey` + +> `type: string` | **optional** + +Overrides the root `apiKey` for Agent Studio. + +### `indexName` + +> `type: string` | **optional** + +Sets the index for conversation storage and Agent Studio requests. Defaults to the first root index. + +### `suggestedQuestions` + +> `type: boolean` | **optional** + +Shows configured suggested questions on the new-conversation screen. Defaults to `false`. + +### `searchParameters` + +> `type: Record` | **optional** + +Sends search parameters keyed by index name. `AgentStudioIndexSearchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. It doesn't support `facetFilters`. + +### `indices` + +> `type: AgentStudioIndices[]` | **optional** + +Defines dynamic indices available to Agent Studio search tools. + +### `tools` + +> `type: Record` | **optional** + +Handles and renders custom Agent Studio tools. Defaults to `{}`. + +### `memory` + +> `type: { enabled?: boolean; userToken?: string }` | **optional** + +Displays memory tool activity and sends a secure user token. + +### `promptSuggestions` + +> `type: { indexName: string; hitsPerPage?: number }` | **optional** + +Configures prompt suggestions in keyword search. `hitsPerPage` defaults to `3`. + +## Dynamic indices + +Each dynamic index accepts the following fields: + +### `index` + +> `type: string` | **required** + +Index available to Agent Studio search tools. + +### `description` + +> `type: string` | **required** + +Describes the index contents to Agent Studio. + +### `enhancedDescription` + +> `type: string` | **optional** + +Provides more context about the index contents. + +### `searchParameters` + +> `type: SearchParamsObject` | **optional** + +Sets search parameters for the dynamic index. + +### `searchControls` + +> `type: AgentStudioSearchControls` | **optional** + +Configures `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom` controls. Text, number, and string-array controls use an `exposed` flag and can define defaults or constraints. + +## Custom tools + +Each `ToolDefinition` accepts the following fields: + +### `render` + +> `type: (params: { message: { input: unknown; output: unknown } }) => string` | **required** + +Renders the tool input and output. + +### `onToolCall` + +> `type: (params: ToolCallParameters) => Promise | void` | **optional** + +Handles a client-side tool call. `ToolCallParameters` includes `input`, `addToolOutput`, `toolCallId`, `toolName`, and the optional `dynamic` flag. + +### `translations` + +> `type: { callingToolText?: string }` | **optional** + +Overrides the text shown while the tool runs. + +When `onToolCall` handles a client-side tool, call `addToolOutput` with the result. Define the tools object outside your component or memoize it to keep its identity stable. + +## Memory + +Set `memory.enabled` to render Agent Studio memory tool calls. Set `memory.userToken` to send the JSON Web Token (JWT) as the `x-algolia-secure-user-token` request header. + +Generate the JWT on your server. Don't put signing secrets in browser code. + +## Exports + +| Import path | Value exports | Type exports | +| --- | --- | --- | +| `@docsearch/modal` | `DocSearchButton`, `DocSearchModal`, `DocSearchAskAiModal` | `DocSearchButtonProps`, `DocSearchModalProps`, `DocSearchAskAiModalProps` | +| `@docsearch/modal/button` | `DocSearchButton` | `DocSearchButtonProps` | +| `@docsearch/modal/modal` | `DocSearchModal` | `DocSearchModalProps` | +| `@docsearch/modal/askai` | `DocSearchAskAiModal` | `DocSearchAskAiModalProps` | + +[1]: /docs/hybrid-mode diff --git a/packages/website/docs/packages/modal/overview.mdx b/packages/website/docs/packages/modal/overview.mdx new file mode 100644 index 00000000..63791ff2 --- /dev/null +++ b/packages/website/docs/packages/modal/overview.mdx @@ -0,0 +1,139 @@ +--- +title: Modal package +description: Add the composable DocSearch modal to a React application. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/modal` provides the DocSearch search button, keyword-search modal, and Agent Studio-enabled modal for React. Render these components inside the `DocSearch` provider from `@docsearch/core`. + +:::info v5 beta + +These instructions use the `^5.0.0-beta` range. Use the same range for every DocSearch package. + +::: + +For the complete component workflow, see the [Composable API guide](/docs/composable-api). + +## Install + + + + +```bash +npm install @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/core@^5.0.0-beta @docsearch/modal@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +## Add keyword search + +Import the main stylesheet once, near your application entry point. + +```tsx title="Search.tsx" +import { DocSearch } from '@docsearch/core'; +import { DocSearchButton, DocSearchModal } from '@docsearch/modal'; + +import '@docsearch/css'; + +export function Search() { + return ( + + + + + ); +} +``` + +Use a search-only API key. Don't expose an Algolia Admin API key in browser code. + +## Add Agent Studio + +In v5, Ask AI uses Agent Studio. Pass an Agent Studio agent ID through `askAi.assistantId`. There's no `agentStudio` boolean in the v5 API. + +```tsx title="Search.tsx" +import { DocSearch } from '@docsearch/core'; +import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal'; + +import '@docsearch/css'; + +export function Search() { + return ( + + + + + ); +} +``` + +The `askAi` object also supports custom tools, conversation memory, and dynamic indices. See the [`DocSearchAskAiModal` API](./api#docsearchaskaimodal). + +## Set provider options + +The modal package reads theme, keyboard shortcut, and lifecycle state from `DocSearch`. + +```tsx title="Search.tsx" + track('search_opened')} + onClose={() => track('search_closed')} +> + + + +``` + +See the [`@docsearch/core` API](../core/api) for provider props and refs. + +## Load smaller entry points + +The package exposes component-specific entry points for code splitting: + +```tsx title="Search.tsx" +import { DocSearchAskAiModal } from '@docsearch/modal/askai'; +import { DocSearchButton } from '@docsearch/modal/button'; +import { DocSearchModal } from '@docsearch/modal/modal'; +``` + +See the [modal API reference](./api) for all exports and props. diff --git a/packages/website/docs/packages/overview.mdx b/packages/website/docs/packages/overview.mdx new file mode 100644 index 00000000..9b6cb184 --- /dev/null +++ b/packages/website/docs/packages/overview.mdx @@ -0,0 +1,84 @@ +--- +title: DocSearch packages +description: Choose the DocSearch v5 package that matches your framework and search experience. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +DocSearch v5 provides keyword search, AI answers powered by Agent Studio, and lower-level packages for custom integrations. + +Start with `@docsearch/js` for a browser integration or `@docsearch/react` for a React application. Both packages support the same keyword search options. + +## Choose a package + +| Package | Use it for | +| --- | --- | +| [`@docsearch/js`](./js/getting-started) | JavaScript sites, including sites that don't use React. The default entry includes keyword search and Ask AI. | +| [`@docsearch/react`](./react/getting-started) | React applications. Choose `DocSearch` for keyword search or `DocSearchAI` for keyword search and Ask AI. | +| [`@docsearch/css`](./css/styling) | The complete button and modal stylesheet. See [Styling](/docs/packages/css/styling). | +| [`@docsearch/core`](./core/overview) | Shared state, keyboard handling, and the provider for the [Composable API](/docs/composable-api). | +| [`@docsearch/modal`](./modal/overview) | Search button, keyword modal, and Ask AI modal components for the Composable API. | +| [`@docsearch/sidepanel`](./sidepanel/getting-started) | React Sidepanel components for persistent AI conversations. | +| [`@docsearch/sidepanel-js`](./sidepanel-js/getting-started) | JavaScript wrapper for the AI Sidepanel. | + +If your Docusaurus site uses the DocSearch adapter, follow the [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started). + +## Choose a search experience + +### Keyword search + +Use keyword search when you only need results from Algolia indices. It has no Ask AI runtime. + +- JavaScript: import `@docsearch/js/docsearch`. +- React: render `DocSearch` from `@docsearch/react`. + +### Keyword search and Ask AI + +Use the AI-capable integration when you have an Agent Studio assistant. + +- JavaScript: use the default `@docsearch/js` export. +- React: render `DocSearchAI` from `@docsearch/react`. + +Create and configure the assistant before adding it to DocSearch. See [Get started with Agent Studio](/docs/agent-studio/getting-started). + +### Composable and hybrid experiences + +Use the [Composable API](/docs/composable-api) to control the provider, button, and modal separately. Use [hybrid mode](/docs/hybrid-mode) to combine the modal with the AI Sidepanel. + +## Beta version + +Install the v5 beta with the caret range: + + + + +```bash +npm install @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +For an existing v4 integration, read [Migrate from v4](/docs/migrating-from-v4) and [v5 breaking changes](/docs/v5-breaking-changes). diff --git a/packages/website/docs/packages/react/api-reference.mdx b/packages/website/docs/packages/react/api-reference.mdx new file mode 100644 index 00000000..c325bdb1 --- /dev/null +++ b/packages/website/docs/packages/react/api-reference.mdx @@ -0,0 +1,418 @@ +--- +title: React API reference +description: Reference for the components, props, ref, and exports in @docsearch/react 5.0.0-beta.0. +--- + +## Components + +### `DocSearch` + +> `type: React.ForwardRefExoticComponent` + +Renders keyword search. It accepts the [common props](#common-props) and forwards a [`DocSearchRef`](#docsearchref). + +```tsx title="Search.tsx" +import { DocSearch } from '@docsearch/react'; +``` + +### `DocSearchAI` + +> `type: React.ForwardRefExoticComponent` + +Renders keyword search and Ask AI. It accepts the [common props](#common-props), requires [`askAi`](#askai), and forwards a [`DocSearchRef`](#docsearchref). + +```tsx title="Search.tsx" +import { DocSearchAI } from '@docsearch/react'; +``` + +## Common props + +### `appId` + +> `type: string` | **required** + +Algolia application ID. + +### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +### `indices` + +> `type: Array` | **optional** + +Indices to search in display order. Provide `indices` or the deprecated [`indexName`](#indexname). + +```tsx title="Search.tsx" + +``` + +### `indexName` + +> `type: string` | **optional** | **deprecated** + +Single index to search. Use [`indices`](#indices) instead. If you pass both options, DocSearch queries `indexName` first. + +### `facets` + +> `type: DocSearchFacet[]` | **optional** + +Facet controls populated from the configured indices. Defaults to `[]`. + +DocSearch supports up to five facets. It ignores empty and duplicate keys, merges sorted values from all configured indices, and hides facets with no values. Configure each attribute for faceting in the Algolia index. + +### `theme` + +> `type: 'light' | 'dark'` | **optional** + +Theme written to `document.documentElement.dataset.theme`. By default, DocSearch doesn't change the current theme. + +### `placeholder` + +> `type: string` | **optional** + +Search input placeholder. The active experience supplies the default. + +### `searchParameters` + +> `type: SearchParamsObject` | **optional** | **deprecated** + +Search parameters for `indexName`. Set `searchParameters` on an [`indices`](#indices) item instead. + +### `maxResultsPerGroup` + +> `type: number` | **optional** + +Maximum results to show in each result group. + +### `transformItems` + +> `type: (items: DocSearchHit[]) => DocSearchHit[]` | **optional** + +Transforms hits before DocSearch groups and renders them. Defaults to the identity function. + +### `hitComponent` + +> `type: React.ComponentType` | **optional** + +Renders one result link. The default component renders the standard result content. + +```tsx title="Hit.tsx" +function Hit({ hit, children }: HitProps): JSX.Element { + return ( + + {children} + + ); +} +``` + +Preserve `children` to retain the default hit content. `hit` is an `InternalDocSearchHit | StoredDocSearchHit`. + +### `resultsFooterComponent` + +> `type: React.ComponentType` | **optional** + +Renders below result collections. It receives the current Autocomplete state. By default, DocSearch doesn't render a footer. + +### `transformSearchClient` + +> `type: (client: SearchClient) => SearchClient` | **optional** + +Wraps or replaces the Algolia search client. Defaults to the identity function. + +### `disableUserPersonalization` + +> `type: boolean` | **optional** + +Disables recent searches, favorites, and stored AI conversations. Defaults to `false`. + +### `initialQuery` + +> `type: string` | **optional** + +Query to place in the input when the modal opens. Defaults to an empty string. + +### `navigator` + +> `type: AutocompleteOptions['navigator']` | **optional** + +Autocomplete navigation implementation. Defaults to the Autocomplete navigator. + +### `translations` + +> `type: DocSearchTranslations` | **optional** + +Overrides button and modal text. Defaults to English strings. + +`DocSearchTranslations` groups overrides under `button` and `modal`. Modal groups include `searchBox`, `footer`, `facets`, `errorScreen`, `startScreen`, `noResultsScreen`, and `resultsScreen`. `DocSearchAI` also supports `askAiScreen` and `newConversation`. + +```tsx title="Search.tsx" + +``` + +### `getMissingResultsUrl` + +> `type: ({ query }: { query: string }) => string` | **optional** + +Builds the no-results report URL. + +### `insights` + +> `type: AutocompleteOptions['insights']` | **optional** + +Configures Algolia Insights. Defaults to `false`. + +### `portalContainer` + +> `type: DocumentFragment | Element` | **optional** + +Element that receives the modal portal. Defaults to `document.body`. + +### `recentSearchesLimit` + +> `type: number` | **optional** + +Maximum recent searches when the user has no favorites. Defaults to `7`. + +### `recentSearchesWithFavoritesLimit` + +> `type: number` | **optional** + +Maximum recent searches when the user has favorites. Defaults to `4`. + +### `keyboardShortcuts` + +> `type: DocSearchModalShortcuts` | **optional** + +Enables `Ctrl/Cmd+K` and `/` to open the modal. Both shortcuts are enabled by default. Escape always closes the modal. + +### `resultBadgeKey` + +> `type: string` | **optional** + +Property path for a value on each hit. Paths support dot and array-index notation, such as `hierarchy.lvl1`, `tags[2]`, and `tags.2`. + +Add custom properties to `attributesToRetrieve`: + +```tsx title="Search.tsx" + +``` + +Primitive values render as text and arrays of primitives render as a comma-separated list. Set `translations.modal.resultsScreen.resultBadgeLabelText` to replace the default screen-reader label, `Category`. + +## Ask AI props + +### `askAi` + +> `type: string | DocSearchAskAi` | **required** + +Agent Studio assistant ID or configuration. This prop is required by `DocSearchAI`. + +#### `assistantId` + +> `type: string` | **required** + +Agent Studio assistant ID. + +#### `appId` + +> `type: string` | **optional** + +Application ID for Agent Studio. Defaults to the root `appId`. + +#### `apiKey` + +> `type: string` | **optional** + +API key for Agent Studio. Defaults to the root `apiKey`. + +#### `indexName` + +> `type: string` | **optional** + +Index for Agent Studio. Defaults to the first normalized keyword index. + +#### `suggestedQuestions` + +> `type: boolean` | **optional** + +Shows published assistant questions on the new-conversation screen. Defaults to `false`. + +#### `searchParameters` + +> `type: AgentStudioSearchParameters` | **optional** + +Search parameters keyed by index name. Each value supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. + +```tsx title="Search.tsx" + +``` + +#### `indices` + +> `type: AgentStudioIndices[]` | **optional** + +Dynamic indices for Agent Studio. Each item requires `index` and `description`. It can also define `enhancedDescription`, `searchParameters`, and `searchControls`. + +`searchControls` supports `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`. + +#### `tools` + +> `type: ToolCalls` | **optional** + +Custom Agent Studio tool renderers and handlers. Defaults to `{}`. Each `ToolDefinition` requires `render({ message })`; `onToolCall` can handle client-side work and call `addToolOutput({ output })`. + +#### `memory` + +> `type: Memory` | **optional** + +Agent Studio memory display and user token. Memory is disabled by default. `Memory.userToken` is the user JWT sent to Agent Studio. + +#### `promptSuggestions` + +> `type: PromptSuggestions` | **optional** + +Prompt suggestions displayed with keyword results. `indexName` selects an index whose records contain a `prompt` attribute. `hitsPerPage` defaults to `3`. + +### `interceptAskAiEvent` + +> `type: (initialMessage: InitialAskAiMessage) => boolean | void` | **optional** + +Runs before DocSearch starts an Ask AI request. Return `true` to prevent the modal from toggling or sending the message. Use it to route Ask AI to another view. + +## `DocSearchRef` + +Ref interface for `DocSearch` and `DocSearchAI`. + +### `isReady` + +> `type: readonly boolean` + +Whether the provider is mounted. + +### `isOpen` + +> `type: readonly boolean` + +Whether the modal is open. + +### `isSidepanelOpen` + +> `type: readonly boolean` + +Whether the registered Sidepanel is open. + +### `isSidepanelSupported` + +> `type: readonly boolean` + +Whether a Sidepanel is registered and the viewport isn't mobile. + +### `open` + +> `type: () => void` + +Opens keyword search. + +### `close` + +> `type: () => void` + +Closes the modal. + +### `openAskAi` + +> `type: (initialMessage?: InitialAskAiMessage) => void` + +Opens Ask AI in the Sidepanel when hybrid mode is available, or in the modal otherwise. + +### `openSidepanel` + +> `type: (initialMessage?: InitialAskAiMessage) => void` + +Opens a registered Sidepanel. Does nothing when no Sidepanel is registered. + +`InitialAskAiMessage` requires `query` and can include `messageId` or `suggestedQuestionId`. + +## Compatibility and deprecations + +- `react`, `react-dom`, and `@types/react` support versions `>=16.8.0 <20.0.0`. +- `search-insights` supports versions `>=1 <3` and is optional. +- The browser build targets ES2017. +- `indexName` and root `searchParameters` remain supported but are deprecated. Move to `indices`. +- `UseDocSearchKeyboardEventsProps.onInput` and `searchButtonRef` remain accepted for compatibility but are deprecated. +- `DocSearch` is keyword-only in v5. Use `DocSearchAI` for Ask AI. + +## Package exports + +The root package exports `DocSearch`, `DocSearchAI`, `DocSearchAskAiModal`, `DocSearchButton`, `DocSearchModal`, `useDocSearchKeyboardEvents`, `version`, and public types. + +| Import | Export | +| --- | --- | +| `@docsearch/react/askaiModal` | `DocSearchAskAiModal` | +| `@docsearch/react/button` | `DocSearchButton` | +| `@docsearch/react/docsearchAi` | `DocSearchAI` and AI types | +| `@docsearch/react/modal` | `DocSearchModal` | +| `@docsearch/react/sidepanel` | `DocSearchSidepanel` and Sidepanel components | +| `@docsearch/react/useDocSearchKeyboardEvents` | `useDocSearchKeyboardEvents` | +| `@docsearch/react/useTheme` | `useTheme` | +| `@docsearch/react/version` | `version` | + +For provider and modal composition, see [Composable API](/docs/composable-api). For modal and Sidepanel composition, see [hybrid mode](/docs/hybrid-mode). + +## Style exports + +Import `@docsearch/css` for the complete modal stylesheet. The React package also exports `@docsearch/react/style` and split `style/variables`, `style/button`, `style/modal`, `style/askai`, and `style/sidepanel` entries for component-level builds. See [Styling](/docs/packages/css/styling). diff --git a/packages/website/docs/packages/react/examples.mdx b/packages/website/docs/packages/react/examples.mdx new file mode 100644 index 00000000..3a783592 --- /dev/null +++ b/packages/website/docs/packages/react/examples.mdx @@ -0,0 +1,271 @@ +--- +title: React examples +description: Configure DocSearch v5 indices, facets, result badges, templates, Agent Studio, and refs. +--- + +These examples build on the [React getting started guide](./getting-started). Replace all placeholder credentials before using them. + +## Search multiple indices + +Pass strings or per-index objects. Results follow the array order. + +```jsx title="MultiIndexSearch.jsx" + +``` + +## Add facet filters + +Configure the attributes for faceting in Algolia, then expose up to five controls: + +```jsx title="FacetedSearch.jsx" + +``` + +DocSearch loads available values from all configured indices and appends selected values to each index's `facetFilters`. + +## Show a result badge + +Retrieve the property and pass its path to `resultBadgeKey`: + +```jsx title="ResultBadgeSearch.jsx" + +``` + +Nested paths such as `hierarchy.lvl1` and `tags[2]` also work. + +## Customize result links + +Use `hitComponent` to change the link while preserving DocSearch's result content: + +```jsx title="SearchHit.jsx" +function SearchHit({ hit, children }) { + return ( + console.info('Opened result', hit.objectID)} + > + {children} + + ); +} + +; +``` + +## Add a results footer + +Use the Autocomplete state to show query-level information: + +```jsx title="ResultsFooter.jsx" +function ResultsFooter({ state }) { + const count = state.context.nbHits ?? 0; + + return

{count} matching records

; +} + +; +``` + +## Transform results + +Return the hits in the order you want DocSearch to group and render them: + +```jsx title="TransformedSearch.jsx" + + items.filter((item) => item.hierarchy.lvl0 !== 'Archived') + } +/> +``` + +## Open search from another control + +```tsx title="SearchTrigger.tsx" +import { useRef } from 'react'; +import { DocSearch, type DocSearchRef } from '@docsearch/react'; + +function Search() { + const searchRef = useRef(null); + + return ( + <> + + + + ); +} +``` + +## Add Agent Studio search parameters + +Use `DocSearchAI`. Key Ask AI search parameters by index name: + +```jsx title="AskAiSearch.jsx" + +``` + +See [Get started with Agent Studio](/docs/agent-studio/getting-started) before configuring the component. + +## Add dynamic Agent Studio indices + +Describe each index so the agent can select the right source: + +```jsx title="DynamicIndicesSearch.jsx" +const askAi = { + assistantId: 'YOUR_ASSISTANT_ID', + indices: [ + { + index: 'product_docs', + description: 'Product guides and conceptual documentation', + searchControls: { + hits_per_page: { + exposed: true, + default: 7, + constraint: { min: 1, max: 10 }, + }, + }, + }, + { + index: 'api_reference', + description: 'API symbols, options, and return values', + }, + ], +}; + +; +``` + +Define stable objects outside the component, or memoize them, when they contain `tools`. + +## Add prompt suggestions + +Show matching prompts next to keyword results: + +```jsx title="PromptSuggestionsSearch.jsx" + +``` + +`suggestedQuestions` shows published assistant questions on a new conversation. `promptSuggestions` searches your prompt index while the user types a keyword query. + +## Route Ask AI to another view + +Return `true` from `interceptAskAiEvent` after handling the message: + +```jsx title="InterceptAskAi.jsx" + { + openCustomAssistant(initialMessage); + return true; + }} +/> +``` + +For the supported modal and Sidepanel integration, use [hybrid mode](/docs/hybrid-mode). diff --git a/packages/website/docs/packages/react/getting-started.mdx b/packages/website/docs/packages/react/getting-started.mdx new file mode 100644 index 00000000..c163e214 --- /dev/null +++ b/packages/website/docs/packages/react/getting-started.mdx @@ -0,0 +1,140 @@ +--- +title: React package +description: Add DocSearch v5 keyword search or Agent Studio answers to a React application. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/react` exports separate components for keyword search and Ask AI. Choose the component that matches your application. + +## Before you start + +Collect your Algolia application ID, Search API key, and index name. To add Ask AI, create an assistant in [Agent Studio](/docs/agent-studio/getting-started) and copy its assistant ID. + +## Install the packages + + + + +```bash +npm install @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/react@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +The package supports React and React DOM versions from 16.8 through 19. + +## Add keyword search + +Render `DocSearch` when your site only needs keyword results: + +```jsx title="Search.jsx" +import { DocSearch } from '@docsearch/react'; + +import '@docsearch/css'; + +export function Search() { + return ( + + ); +} +``` + +`DocSearch` doesn't include the Ask AI experience. + +## Add keyword search and Ask AI + +Render `DocSearchAI` and pass the Agent Studio assistant: + +```jsx title="Search.jsx" +import { DocSearchAI } from '@docsearch/react'; + +import '@docsearch/css'; + +export function Search() { + return ( + + ); +} +``` + +`askAi` also accepts the assistant ID as a string. Use the object form for Agent Studio search parameters, dynamic indices, tools, memory, and prompt suggestions. + +## Control DocSearch with a ref + +Both components forward a `DocSearchRef`: + +```tsx title="Search.tsx" +import { useRef } from 'react'; +import { DocSearchAI, type DocSearchRef } from '@docsearch/react'; + +export function Search() { + const searchRef = useRef(null); + + return ( + <> + + + + ); +} +``` + +Use `open()` and `close()` for keyword search. Sidepanel methods become useful when you register a Sidepanel through [hybrid mode](/docs/hybrid-mode). + +## Next steps + +- Review every component option in the [React API reference](./api-reference). +- Start from the [React examples](./examples) for indices, facets, badges, templates, and refs. +- Use the [Composable API](/docs/composable-api) for separate provider, button, and modal components. +- Customize the design in [Styling](/docs/packages/css/styling). +- For Docusaurus, follow the [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started). diff --git a/packages/website/docs/packages/sidepanel-js/api.mdx b/packages/website/docs/packages/sidepanel-js/api.mdx new file mode 100644 index 00000000..48beae71 --- /dev/null +++ b/packages/website/docs/packages/sidepanel-js/api.mdx @@ -0,0 +1,230 @@ +--- +title: Sidepanel JS API reference +description: API reference for @docsearch/sidepanel-js v5 beta. +toc_max_heading_level: 2 +--- + +## `sidepanel` + +```ts +function sidepanel(props: SidepanelProps): SidepanelInstance; +``` + +The function resolves `container`, mounts the component, and returns immediately. Use `onReady` or `instance.isReady` to detect the mounted state. + +### Mounting props + +#### `container` + +> `type: HTMLElement | string` | **required** + +Element or CSS selector that receives the Sidepanel application. + +#### `environment` + +> `type: typeof window` | **optional** + +Environment used to resolve a selector. Defaults to the browser `window`. A selector without a browser environment throws. + +The function throws if a selector doesn't match an element. + +### Connection props + +#### `appId` + +> `type: string` | **required** + +Algolia application ID. + +#### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +#### `assistantId` + +> `type: string` | **required** + +Agent Studio agent ID. + +#### `indexName` + +> `type: string` | **required** + +Primary index for Agent Studio and conversation storage. + +The public `SidepanelProps` type in `5.0.0-beta.0` doesn't include the React Sidepanel's top-level `searchParameters` field. + +### UI props + +#### `theme` + +> `type: 'light' | 'dark'` | **optional** + +Sets `data-theme` on the document root while mounted. + +#### `keyboardShortcuts` + +> `type: { 'Ctrl/Cmd+I'?: boolean }` | **optional** + +Enables or disables the Sidepanel shortcut. The shortcut is enabled by default. + +#### `button` + +> `type: SidepanelButtonProps` | **optional** + +Configures the built-in button. Defaults to `{}`. + +`button` accepts `variant: 'floating' | 'inline'` and `translations.buttonText` or `translations.buttonAriaLabel`. + +#### `panel` + +> `type: SidepanelPanelProps` | **optional** + +Configures layout, suggested questions, and translations. Defaults to `{}`. + +`panel` accepts `variant`, `side`, `pushSelector`, `width`, `expandedWidth`, `portalContainer`, `suggestedQuestions`, `translations`, `tools`, `memory`, and `indices`. Panel-level `tools`, `memory`, and `indices` override their root values. Don't set `panel.keyboardShortcuts`; configure shortcuts at the root. + +### Callbacks + +#### `onReady` + +> `type: () => void` | **optional** + +Runs once after the component mounts. + +#### `onOpen` + +> `type: () => void` | **optional** + +Runs when the Sidepanel opens. + +#### `onClose` + +> `type: () => void` | **optional** + +Runs when the Sidepanel closes. + +Use these Sidepanel-specific callbacks rather than the inherited React provider callback names. + +## Agent Studio options + +### `tools` + +> `type: Record` | **optional** + +Handles and renders custom Agent Studio tools. Defaults to `{}`. + +### `memory` + +> `type: { enabled?: boolean; userToken?: string }` | **optional** + +Configures memory-tool rendering and authentication. + +### `indices` + +> `type: AgentStudioIndices[]` | **optional** + +Defines dynamic indices available to Agent Studio. + +These fields are root props: + +```js title="load-sidepanel.js" +const assistant = sidepanel({ + container: '#docsearch-sidepanel', + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + assistantId: 'YOUR_AGENT_ID', + indexName: 'docs', + memory: { + enabled: true, + userToken: userMemoryToken, + }, + indices: [ + { + index: 'docs', + description: 'Product documentation and API references.', + }, + { + index: 'support_articles', + description: 'Troubleshooting and support articles.', + }, + ], + tools: { + getReleaseChannel: { + async onToolCall({ input, addToolOutput }) { + const channel = await readReleaseChannel(input); + await addToolOutput({ output: { channel } }); + }, + render({ message }) { + return `Release channel: ${message.output.channel}`; + }, + }, + }, +}); +``` + +`AgentStudioIndices` requires `index` and `description`. It also accepts `enhancedDescription`, `searchParameters`, and `searchControls`. + +`ToolDefinition` requires `render({ message: { input, output } })`, which returns a string. It can also define `onToolCall` and `translations.callingToolText`. If you handle a client-side tool, call `addToolOutput`. + +Generate `memory.userToken` on your server. The package sends it as `x-algolia-secure-user-token`. + +## `SidepanelInstance` + +Calls to `open` and `close` before the internal ref is ready are no-ops. + +`InitialAskAiMessage` is: + +```ts title="types.ts" +type InitialAskAiMessage = { + query: string; + messageId?: string; + suggestedQuestionId?: string; +}; +``` + +### `isReady` + +> `type: readonly boolean` + +Whether the component is mounted. + +### `isOpen` + +> `type: readonly boolean` + +Whether the panel is open. + +### `open` + +> `type: (initialMessage?: InitialAskAiMessage) => void` + +Opens the panel, optionally with a question or stored-message IDs. + +### `close` + +> `type: () => void` + +Closes the panel. + +### `destroy` + +> `type: () => void` + +Unmounts the component and marks the instance not ready. + +## Exports + +`@docsearch/sidepanel-js` has one value export: the default `sidepanel` function. + +It also exports the `SidepanelProps`, `SidepanelInstance`, and `SidepanelCallbacks` TypeScript types. It doesn't provide a named `sidepanel` export or package subpaths. + +```ts title="load-sidepanel.ts" +import sidepanel, { + type SidepanelCallbacks, + type SidepanelInstance, + type SidepanelProps, +} from '@docsearch/sidepanel-js'; +``` diff --git a/packages/website/docs/packages/sidepanel-js/getting-started.mdx b/packages/website/docs/packages/sidepanel-js/getting-started.mdx new file mode 100644 index 00000000..ee7c3842 --- /dev/null +++ b/packages/website/docs/packages/sidepanel-js/getting-started.mdx @@ -0,0 +1,120 @@ +--- +title: Sidepanel JS package +description: Mount and control the v5 beta Agent Studio Sidepanel without React application code. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/sidepanel-js` mounts the Agent Studio Sidepanel into an existing HTML element. It bundles its rendering dependencies and returns an imperative instance. + +:::info v5 beta + +These instructions use the `^5.0.0-beta` range. + +::: + +## Install + + + + +```bash +npm install @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/sidepanel-js@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +Add a container to your page: + +```html title="index.html" +
+``` + +Mount the Sidepanel and retain the returned instance: + +```js title="load-sidepanel.js" +import sidepanel from '@docsearch/sidepanel-js'; + +import '@docsearch/css'; +import '@docsearch/css/dist/sidepanel.css'; + +const assistant = sidepanel({ + container: '#docsearch-sidepanel', + appId: 'YOUR_APPLICATION_ID', + apiKey: 'YOUR_SEARCH_API_KEY', + assistantId: 'YOUR_AGENT_ID', + indexName: 'YOUR_INDEX_NAME', + onReady() { + console.info('DocSearch sidepanel is ready'); + }, +}); + +document.querySelector('#ask-docs').addEventListener('click', () => { + assistant.open(); +}); +``` + +Use a search-only API key. The `assistantId` is an Agent Studio agent ID. V5 doesn't provide an `agentStudio` switch. + +## Open with a question + +Pass an initial message to `open`: + +```js title="load-sidepanel.js" +assistant.open({ + query: 'How do I configure a search-only API key?', +}); +``` + +Call `assistant.destroy()` before removing the container or remounting another Sidepanel in it. + +## Load from a CDN + +```html title="index.html" + + + +
+ + + +``` + +See the [JavaScript Sidepanel API](./api) for configuration, Agent Studio options, callbacks, and instance methods. diff --git a/packages/website/docs/packages/sidepanel/advanced-use-cases.mdx b/packages/website/docs/packages/sidepanel/advanced-use-cases.mdx new file mode 100644 index 00000000..67ad70f6 --- /dev/null +++ b/packages/website/docs/packages/sidepanel/advanced-use-cases.mdx @@ -0,0 +1,162 @@ +--- +title: React Sidepanel advanced use cases +description: Control Sidepanel layout, refs, Agent Studio tools, memory, and indices. +--- + +## Push page content + +Use the `inline` panel variant to add a margin to the first element that matches `pushSelector`. On screens up to 768 pixels wide, the panel overlays the page instead. + +```tsx title="Docs.tsx" + + +``` + +Keep `pushSelector` narrow enough to identify one layout container. The implementation uses the first matching element and restores its inline margin and transition when it unmounts. + +## Render into another container + +Both the floating button and panel default to `document.body`. Set `portalContainer` on the panel and `portalcontainer` on the button to use another element. The button prop is lower-case in the v5 beta API. + +```tsx title="AssistantPortal.tsx" +const assistantRoot = document.getElementById('assistant-root'); + + + + +; +``` + +An inline `SidepanelButton` renders where it appears in the React tree and doesn't use its portal container. + +## Control the panel with a ref + +Attach a `DocSearchRef` to the provider. `openSidepanel` accepts an optional initial message. + +```tsx title="Support.tsx" +import { DocSearch, type DocSearchRef } from '@docsearch/core'; +import { Sidepanel } from '@docsearch/sidepanel'; +import { useRef } from 'react'; + +export function Support() { + const docsearchRef = useRef(null); + + return ( + + + + + ); +} +``` + +Call the method after the Sidepanel has mounted and registered its view. Check `isSidepanelOpen` to read its open state. See [Hybrid Mode](/docs/hybrid-mode) for cross-view ref behavior. + +## Handle Agent Studio tools + +Key each client tool by the name emitted by your agent. Always return tool output through `addToolOutput` when you provide `onToolCall`. + +```tsx title="tools.tsx" +const tools = { + getReleaseChannel: { + translations: { callingToolText: 'Reading release settings' }, + async onToolCall({ input, addToolOutput }) { + const channel = await readReleaseChannel(input); + await addToolOutput({ output: { channel } }); + }, + render({ message }) { + const output = message.output as { channel: string }; + return `Release channel: ${output.channel}`; + }, + }, +}; + +; +``` + +Define `tools` outside the component or memoize it. Tool errors don't render a tool result. + +## Enable memory + +Pass a server-generated Agent Studio user JWT. `enabled` controls whether memory tool activity appears in the conversation; `userToken` authenticates the user's memory requests. + +```tsx title="Memory.tsx" + +``` + +Don't generate or sign the token in the browser. + +## Provide dynamic indices + +Use `indices` to describe the indices Agent Studio can select at request time. This list is separate from the required `indexName`, which remains the Sidepanel's primary index. + +```tsx title="DynamicIndices.tsx" + +``` + +Search parameters are keyed by index name. See the [Sidepanel API](./api#agent-studio-options) for the supported fields. diff --git a/packages/website/docs/packages/sidepanel/api.mdx b/packages/website/docs/packages/sidepanel/api.mdx new file mode 100644 index 00000000..965cfdbb --- /dev/null +++ b/packages/website/docs/packages/sidepanel/api.mdx @@ -0,0 +1,229 @@ +--- +title: React Sidepanel API reference +description: API reference for @docsearch/sidepanel v5 beta. +toc_max_heading_level: 2 +--- + +## `Sidepanel` + +Render `Sidepanel` inside `DocSearch` from `@docsearch/core`. + +Set `theme` on `DocSearch`; `SidepanelProps` omits it. Set lifecycle callbacks such as `onSidepanelOpen` and `onSidepanelClose` on the provider. Don't pass inherited `onOpen` or `onClose` callbacks to `Sidepanel`, because they replace the wrapper's state handlers in this beta. + +### Connection props + +#### `appId` + +> `type: string` | **required** + +Algolia application ID. + +#### `apiKey` + +> `type: string` | **required** + +Public API key with search permission. + +#### `assistantId` + +> `type: string` | **required** + +Agent Studio agent ID. + +#### `indexName` + +> `type: string` | **required** + +Primary index for Agent Studio and conversation storage. + +#### `searchParameters` + +> `type: Record` | **optional** + +Search parameters keyed by index name. + +`AgentStudioIndexSearchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. + +### Layout props + +#### `variant` + +> `type: 'floating' | 'inline'` | **optional** + +Overlays the page or pushes matching page content on desktop. Defaults to `'floating'`. + +#### `side` + +> `type: 'left' | 'right'` | **optional** + +Sets the side from which the panel opens. Defaults to `'right'`. + +#### `pushSelector` + +> `type: string` | **optional** + +Selects the first element pushed by the inline panel. Defaults to `'#root, main, .app, body'`. + +#### `width` + +> `type: number | string` | **optional** + +Sets the normal width. Numbers use pixels. Defaults to `360`. + +#### `expandedWidth` + +> `type: number | string` | **optional** + +Sets the expanded width. Numbers use pixels. Defaults to `580`. + +#### `portalContainer` + +> `type: DocumentFragment | Element | null` | **optional** + +Receives the panel portal. Defaults to `document.body`. + +### Behavior props + +#### `keyboardShortcuts` + +> `type: { 'Ctrl/Cmd+I'?: boolean }` | **optional** + +Enables or disables the Sidepanel shortcut. The shortcut is enabled by default. + +#### `suggestedQuestions` + +> `type: boolean` | **optional** + +Whether to show Agent Studio suggested questions on the new-conversation screen. Defaults to `false`. + +#### `translations` + +> `type: SidepanelTranslations` | **optional** + +Supplies partial strings for `header`, `promptForm`, `conversationScreen`, `newConversationScreen`, and `logo`. Defaults to `{}`. + +#### `tools` + +> `type: Record` | **optional** + +Handles and renders custom Agent Studio tools. Defaults to `{}`. + +#### `memory` + +> `type: { enabled?: boolean; userToken?: string }` | **optional** + +Configures Agent Studio memory rendering and authentication. + +#### `indices` + +> `type: AgentStudioIndices[]` | **optional** + +Defines dynamic indices available to Agent Studio. + +### Translation groups + +| Group | Keys | +| --- | --- | +| `header` | `title`, `conversationHistoryTitle`, `newConversationText`, `viewConversationHistoryText` | +| `promptForm` | `promptPlaceholderText`, `promptAnsweringText`, `promptAskAnotherQuestionText`, `promptDisclaimerText`, `promptLabelText`, `promptAriaLabelText` | +| `newConversationScreen` | `titleText`, `introductionText` | +| `logo` | `poweredByText` | +| `conversationScreen` | Tool status, source, copy, feedback, error, disclaimer, and suggested-prompt strings exposed by `ConversationScreenTranslations` | + +## Agent Studio options + +V5 uses Agent Studio for Sidepanel conversations. It doesn't expose an `agentStudio` prop. + +### `AgentStudioIndices` + +```ts +interface AgentStudioIndices { + index: string; + description: string; + enhancedDescription?: string; + searchParameters?: SearchParamsObject; + searchControls?: AgentStudioSearchControls; +} +``` + +`searchControls` accepts `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`. Controls specify whether Agent Studio may expose a value to the model and can include defaults and constraints. + +### `ToolDefinition` + +```ts +type ToolDefinition = { + render: (params: { message: { input: unknown; output: unknown } }) => string; + onToolCall?: (params: { + input: unknown; + addToolOutput: (props: { output: unknown }) => Promise; + toolCallId: string; + toolName: string; + dynamic?: boolean; + }) => Promise | void; + translations?: { callingToolText?: string }; +}; +``` + +### `memory` + +`enabled` defaults to `false` and controls memory-tool status rendering. `userToken` is sent as the `x-algolia-secure-user-token` header. + +## `SidepanelButton` + +### `variant` + +> `type: 'floating' | 'inline'` | **optional** + +Renders an icon-only floating button or an inline button with text. Defaults to `'floating'`. + +### `translations` + +> `type: { buttonText?: string; buttonAriaLabel?: string }` | **optional** + +Changes visible and accessible text. `buttonText` applies to the inline variant. Defaults to the English labels. + +### `portalcontainer` + +> `type: DocumentFragment | Element | null` | **optional** + +Receives the floating button portal. Defaults to `document.body`. This beta prop uses a lower-case `c`. + +The wrapper supplies its click handler and keyboard shortcut configuration from `DocSearch`. An inline button renders at its position in the React tree. + +## Programmatic control + +`Sidepanel` doesn't expose its lower-level `SidepanelRef` directly. Attach a `DocSearchRef` to the provider and use: + +### `openSidepanel` + +> `type: (initialMessage?: InitialAskAiMessage) => void` + +Opens a registered Sidepanel. + +### `close` + +> `type: () => void` + +Returns the provider to its ready state. + +### `isSidepanelOpen` + +> `type: boolean` + +Whether the Sidepanel is open. + +### `isReady` + +> `type: boolean` + +Whether the provider is mounted. + +`InitialAskAiMessage` is `{ query: string; messageId?: string; suggestedQuestionId?: string }`. See the [`@docsearch/core` API](../core/api) for the full ref. + +## Exports + +| Import path | Value exports | Type exports | +| --- | --- | --- | +| `@docsearch/sidepanel` | `Sidepanel`, `SidepanelButton` | `SidepanelProps`, `SidepanelButtonProps` | +| `@docsearch/sidepanel/sidepanel` | `Sidepanel` | `SidepanelProps` | +| `@docsearch/sidepanel/button` | `SidepanelButton` | `SidepanelButtonProps` | diff --git a/packages/website/docs/packages/sidepanel/getting-started.mdx b/packages/website/docs/packages/sidepanel/getting-started.mdx new file mode 100644 index 00000000..700fea50 --- /dev/null +++ b/packages/website/docs/packages/sidepanel/getting-started.mdx @@ -0,0 +1,101 @@ +--- +title: Sidepanel package +description: Add the v5 beta Agent Studio Sidepanel to a React application. +--- + +import TabItem from '@theme/TabItem'; +import Tabs from '@theme/Tabs'; + +`@docsearch/sidepanel` provides composable React components for an Agent Studio chat panel. + +:::info v5 beta + +These instructions use the `^5.0.0-beta` range. Use the same range for every DocSearch package. + +::: + +## Install + + + + +```bash +npm install @docsearch/core@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +yarn add @docsearch/core@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +pnpm add @docsearch/core@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +```bash +bun add @docsearch/core@^5.0.0-beta @docsearch/sidepanel@^5.0.0-beta @docsearch/css@^5.0.0-beta +``` + + + + +## Render the Sidepanel + +Import both the main DocSearch stylesheet and the Sidepanel stylesheet. + +```tsx title="HelpAssistant.tsx" +import { DocSearch } from '@docsearch/core'; +import { Sidepanel, SidepanelButton } from '@docsearch/sidepanel'; + +import '@docsearch/css'; +import '@docsearch/css/dist/sidepanel.css'; + +export function HelpAssistant() { + return ( + + + + + ); +} +``` + +Use a search-only API key. The `assistantId` is an Agent Studio agent ID. V5 doesn't provide the legacy Ask AI backend or an `agentStudio` switch. + +The default button and panel float over the page. Press `Control+I` or `Command+I` to toggle the panel, and press `Escape` to close it. + +## Configure the provider + +Set the theme and lifecycle callbacks on `DocSearch`. + +```tsx title="HelpAssistant.tsx" + track('assistant_opened')} + onSidepanelClose={() => track('assistant_closed')} +> + + + +``` + +Continue with [advanced use cases](./advanced-use-cases) or review the [Sidepanel API](./api). For a combined search and assistant experience, see [Hybrid Mode](/docs/hybrid-mode). diff --git a/packages/website/docs/record-extractor.md b/packages/website/docs/record-extractor.md index c94ccd84..c762c149 100644 --- a/packages/website/docs/record-extractor.md +++ b/packages/website/docs/record-extractor.md @@ -1,18 +1,19 @@ --- title: Record Extractor +description: Configure the DocSearch record extractor for Algolia Crawler records. --- ## Introduction :::info -This documentation will only contain information regarding the **helpers.docsearch** method, see **[Algolia Crawler Documentation][7]** for more information on the **[Algolia Crawler][8]**. +This page documents the **helpers.docsearch** method. See the **[Algolia Crawler documentation][7]** for information about the **[Algolia Crawler][8]**. ::: -Pages are extracted by a [`recordExtractor`][9]. These extractors are assigned to [`actions`][12] via the [`recordExtractor`][9] parameter. This parameter links to a function that returns the data you want to index, organized in an array of JSON objects. +Set the [`recordExtractor`][9] parameter on an [`action`][12] to extract each page. Its function returns the data to index as an array of JSON objects. -_The helpers are a collection of functions to help you extract content and generate Algolia records._ +The helpers are functions for extracting content and generating Algolia records. ### Useful links @@ -21,7 +22,7 @@ _The helpers are a collection of functions to help you extract content and gener ## Usage -The most common way to use the DocSearch helper, is to return its result to the [`recordExtractor`][9] function. +The most common way to use the DocSearch helper is to return its result to the [`recordExtractor`][9] function. ```js recordExtractor: ({ helpers }) => { @@ -77,7 +78,7 @@ recordExtractor: ({ $, helpers }) => { // `.exists h1` will be selected if `.exists-probably h1` does not exists. lvl0: { selectors: [".exists-probably h1", ".exists h1"], - } + }, lvl1: "article h2", lvl2: "article h3", lvl3: "article h4", @@ -131,7 +132,7 @@ recordExtractor: ({ $, helpers }) => { _These selectors also support [`defaultValue`](#provide-raw-text-defaultvalue) and [fallback selectors](#provide-fallback-selectors)_ -You might want to index content that will be used as filters in your frontend (e.g. `version` or `lang`), you can defined any custom variable to the `recordProps` object to add them to your Algolia records: +To index content for frontend filters, such as `version` or `language`, define custom variables in `recordProps`. The helper adds them to each matching Algolia record: ```js recordExtractor: ({ helpers }) => { @@ -164,15 +165,19 @@ recordExtractor: ({ helpers }) => { }, ``` -The following `version`, `lang` and `foo` attributes will be available in your records: +The `version`, `language`, and `foo` attributes are then available in your records: ```json -foo: "valueFromBarSelector", -language: ["en", "en-US"], -version: ["latest", "stable"] +{ + "foo": "valueFromBarSelector", + "language": ["en", "en-US"], + "version": ["latest", "stable"] +} ``` -You can now use them to [filter your search in the frontend][16] +Add every filter attribute to the index's `attributesForFaceting`, then expose up to five of them with the v5 [`facets` option][16]. If you display one with `resultBadgeKey`, also add that attribute to `attributesToRetrieve`; see the [`resultBadgeKey` reference][17]. + +V5 result breadcrumbs use the `hierarchy.lvl0` through `hierarchy.lvl6` values generated from your selectors. Keep the heading levels ordered and include the hierarchy attributes in `attributesToRetrieve`. ### Boost search results with `pageRank` @@ -209,7 +214,7 @@ You can view the computed weight directly from the Algolia dashboard (dashboard. ### Reduce the number of records -If you encounter the `Extractors returned too many records` error when your page outputs more than 750 records. The [`aggregateContent`](#aggregatecontent) option helps you reducing the number of records at the `content` level of the extractor. +If you encounter the `Extractors returned too many records` error when your page outputs more than 750 records, the [`aggregateContent`](#aggregatecontent) option helps you reduce the number of records at the `content` level of the extractor. ```js { @@ -236,7 +241,7 @@ If you encounter the `Extractors returned too many records` error when your page ### Reduce the record size -If you encounter the `Records extracted are too big` error when crawling your website, it's mostly because there was too many informations in your records, or that your page is too big. The [`recordVersion`](#recordversion) option helps you reducing the records size by removing informations that are only used with [DocSearch v2](/docs/legacy/dropdown). +If you encounter the `Records extracted are too big` error, your records or source page might contain too much information. The [`recordVersion`](#recordversion) option reduces record size by removing fields used only by the [DocSearch v2 UI](/docs/legacy/dropdown). ```js { @@ -303,7 +308,7 @@ type CustomVariable = }; ``` -Custom variables are used to [`filter your search`](/docs/v3/docsearch#filtering-your-search), you can define them in the [`recordProps`](#indexing-content-for-faceting) +Define custom variables in [`recordProps`](#indexing-content-for-faceting). You can use them with v5 [`facets` and per-index filters][16]. ## `helpers.docsearch` API Reference @@ -317,7 +322,7 @@ Custom variables are used to [`filter your search`](/docs/v3/docsearch#filtering > `type: 'v3' | 'v2'` | default: `v2` | **optional** -This option remove content from the Algolia records that are only used for [DocSearch v2](/docs/legacy/dropdown). If you are using [the latest version of DocSearch](/docs/v3/docsearch), you can [set it to `v3`](#reduce-the-record-size). +This option selects the crawler record schema. It doesn't select the DocSearch UI package version. Set it to `v3` to remove fields used only by the [DocSearch v2 UI](/docs/legacy/dropdown). The `v3` value is also the current record schema for DocSearch v5 frontends. ### `indexHeadings` @@ -328,7 +333,6 @@ This option tells the crawler if the `headings` (`lvlX`) should be indexed. - When `false`, only records for the `content` level will be created. - When `from, to` is provided, only records for the `lvlX` to `lvlY` will be created. -[1]: /docs/v3/docsearch [2]: https://github.com/algolia/docsearch/ [3]: https://github.com/algolia/docsearch/tree/master [4]: /docs/legacy/dropdown @@ -342,4 +346,5 @@ This option tells the crawler if the `headings` (`lvlX`) should be indexed. [12]: https://www.algolia.com/doc/tools/crawler/apis/configuration/actions/ [13]: /docs/record-extractor#indexing-content-for-faceting [15]: https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/ -[16]: /docs/v3/docsearch/#filtering-your-search +[16]: /docs/packages/js/api-reference#facets +[17]: /docs/packages/js/api-reference#resultbadgekey diff --git a/packages/website/docs/required-configuration.mdx b/packages/website/docs/required-configuration.mdx index d52447f9..c6a856bd 100644 --- a/packages/website/docs/required-configuration.mdx +++ b/packages/website/docs/required-configuration.mdx @@ -1,20 +1,21 @@ --- title: Required configuration +description: Structure website content and crawler settings for DocSearch indexing. --- -This section, gives you the best practices to optimize our crawl. Adopting this following specification is required to let our crawler build the best experience from your website. You will need to update your website and follow these rules. +Follow these requirements so the crawler can extract structured records from your website. Update your markup and crawler configuration where needed. :::info -If your website is generated, thanks to one of [our supported tools][1], you do not need to change your website as it is already compliant with our requirements. +If your website uses one of [the supported framework integrations][1], its generated markup might already meet these requirements. Confirm that the crawler selectors match your framework and version. ::: -## The generic configuration example +## Generic configuration example -You can find the default DocSearch config template below and tweak it with some examples from our [`complex extractors` section][12]. +Start with the default DocSearch configuration template. For more customization options, see [complex record extractors][12]. -If you are using one of [our integrations][13], please see [the templates page][11]. +If you use a [framework integration][13], see the [configuration templates][11].
docsearch-default.js @@ -53,7 +54,7 @@ new Crawler({ ], initialIndexSettings: { YOUR_INDEX_NAME: { - attributesForFaceting: ['type', 'lang'], + attributesForFaceting: ['type', 'lang', 'language', 'version'], attributesToRetrieve: [ 'hierarchy', 'content', @@ -61,6 +62,9 @@ new Crawler({ 'url', 'url_without_anchor', 'type', + 'lang', + 'language', + 'version', ], attributesToHighlight: ['hierarchy', 'content'], attributesToSnippet: ['content:10'], @@ -110,67 +114,73 @@ new Crawler({
+`recordVersion: 'v3'` selects the crawler record schema. It isn't the DocSearch UI version and works with the v5 frontend packages. If you expose `lang`, `language`, or `version` as v5 facets, add those attributes to `attributesForFaceting`. Keep a badge attribute in `attributesToRetrieve` when you pass it to [`resultBadgeKey`][15]. + ### Overview of a clear layout -A website implementing these good practises will look simple and crystal clear. It can have this following aspect: +Use a page layout that separates documentation content from navigation and other page elements: Recommended layout for your page -The main blue element will be your `.DocSearch-content` container. More details in the following guidelines. +Use the main blue element as your `.DocSearch-content` container. Follow the next guidelines to structure its contents. ### Use the right classes as [`recordProps`][2] -You can add some specific static classes to help us find your content role. These classes can not involve any style changes. These dedicated classes will help us to create a great learn-as-you-type experience from your documentation. +Add static classes to identify each content role. These classes don't need to change the page's appearance. The crawler uses them to extract structured records. -- Add a static class `DocSearch-content` to the main container of your textual content. Most of the time, this tag is a `
` or an `
` HTML element. +- Add a static `DocSearch-content` class to the main container for your text. This container is usually a `
` or `
` element. -- Every searchable `lvl` element outside this main documentation container (for instance in a sidebar) must be a `global` selector. They will be globally picked up and injected to every record built from your page. Be careful, the level value matters and every matching element must have an increasing level along the HTML flow. A level `X` (for `lvlX`) should appear after a level `Y` while `X > Y`. +- Configure every searchable `lvl` element outside the main documentation container, such as a sidebar item, as a `global` selector. The crawler adds these elements to every record from the page. Keep levels in increasing order in the document flow: `lvlX` should follow `lvlY` when `X > Y`. -- `lvlX` selectors should use the standard title tags like `h1`, `h2`, `h3`, etc. You can also use static classes. Set a unique `id` or `name` attribute to these elements as detailed below. +- Use standard heading elements, such as `h1`, `h2`, and `h3`, for `lvlX` selectors. You can also use static classes. Add a unique `id` or `name` attribute to each matching element. -- Every DOM element matching the `lvlX` selectors must have a unique `id` or `name` attribute. This will help the redirection to directly scroll down to the exact place of the matching elements. These attributes define the right anchor to use. +- Give every element that matches an `lvlX` selector a unique `id` or `name` attribute. DocSearch uses this anchor to open the page at the matching element. -- Every textual element (recordProps `content`) must be wrapped in a `

` or `

  • ` tag. This content must be atomic and split into small entities. Be careful to never nest one matching element into another one as it will create duplicates. +- V5 builds result breadcrumbs from the populated `hierarchy.lvl0` through `hierarchy.lvl6` attributes. Keep heading levels ordered, avoid gaps where possible, and retrieve the full `hierarchy` object. -- Stay consistent and do not forget that we need to have some consistency along the HTML flow. +- Wrap every element that matches the `recordProps.content` selector in a `

    ` or `

  • ` element. Split text into focused blocks, and don't nest matching elements because this creates duplicate records. + +- Keep the content structure consistent throughout the document. ## Introduce global information as meta tags -Our crawler automatically extracts information from our DocSearch specific meta tags: +The crawler automatically extracts information from DocSearch-specific meta tags: -```html +```html title="index.html" ``` -The crawl adds the `content` value of these `meta` tags to all records extracted from the page. The meta tags `name` must follow the `docsearch:$NAME` pattern. `$NAME` is the name of the attribute set to all records. +The crawler adds the `content` value of these `meta` tags to every record extracted from the page. Each tag's `name` attribute must follow the `docsearch:$NAME` pattern, where `$NAME` is the record attribute to set. The `docsearch:version` meta tag can be a set [of comma-separated tokens][5], each of which is a version relevant to the page. These tokens must be compliant with [the SemVer specification][6] or only contain alphanumeric characters (e.g. `latest`, `next`, etc.). As facet filters, these version tokens are case-insensitive. -For example, all records extracted from a page with the following meta tag: +For example, add the following meta tag to assign two versions to every record on a page: -```html +```html title="index.html" ``` -The `version` attribute of these records will be : +The crawler adds the following `version` attribute to each record: -```json -version:["2.0.0-alpha.62", "latest"] +```json title="record.json" +{ + "version": ["2.0.0-alpha.62", "latest"] +} ``` -You can then [transform these attributes as `facetFilters`][3] to [filter over them from the UI][10]. +Add these attributes to `attributesForFaceting`. You can then use them in per-index `facetFilters` or expose up to five controls with the v5 [`facets` option][10]. To show `version` in each result, retrieve it and set [`resultBadgeKey`][15] to `version`. ## Nice to have -- Your website should have [an updated sitemap][7]. This is key to let our crawler know what should be updated. Do not worry, we will still crawl your website and discover embedded hyperlinks to find your great content. +- Keep your [sitemap][7] up to date so the crawler can identify changed pages. The crawler also discovers eligible links from crawled pages. -- Every page needs to have their full context available. Using global elements might help (see above). +- Ensure that every page provides its full context. Use global elements where appropriate. -- Make sure your documentation content is also available without JavaScript rendering on the client-side. If you absolutely need JavaScript turned on, you need to [set `renderJavaScript: true` in your configuration][8]. +- Make your documentation content available without client-side JavaScript rendering. If your website requires JavaScript rendering, [set `renderJavaScript: true` in your configuration][8]. Any questions? Connect with us on [Discord][14] or [support][9]. @@ -182,8 +192,9 @@ Any questions? Connect with us on [Discord][14] or [support][9]. [7]: https://www.sitemaps.org/ [8]: https://www.algolia.com/doc/tools/crawler/apis/configuration/render-java-script/ [9]: https://support.algolia.com/ -[10]: /docs/v3/docsearch#filtering-your-search +[10]: /docs/packages/js/api-reference#facets [11]: /docs/templates [12]: /docs/record-extractor#introduction [13]: /docs/integrations [14]: https://alg.li/discord +[15]: /docs/packages/js/api-reference#resultbadgekey diff --git a/packages/website/docs/sidepanel/advanced-use-cases.mdx b/packages/website/docs/sidepanel/advanced-use-cases.mdx index 6d51e9d0..618b7ba1 100644 --- a/packages/website/docs/sidepanel/advanced-use-cases.mdx +++ b/packages/website/docs/sidepanel/advanced-use-cases.mdx @@ -1,144 +1,8 @@ --- -title: Advanced use cases +title: Advanced sidepanel use cases +description: Configure advanced DocSearch Agent Studio sidepanel behavior. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +See [Advanced `@docsearch/sidepanel` use cases](/docs/packages/sidepanel/advanced-use-cases) for dynamic indices, tools, memory, layout options, and programmatic control. -## Introduction - -This guide will cover some advanced implementations/use cases for the Sidepanel. The examples below assume you're using the Sidepanel React package, -available from `@docsearch/sidepanel`. The `@docsearch/sidepanel` package can be installed as follows: - - - - -```bash -npm install @docsearch/sidepanel -``` - - - - - -```bash -yarn add @docsearch/sidepanel -``` - - - - - -```bash -pnpm add @docsearch/sidepanel -``` - - - - - -```bash -bun add @docsearch/sidepanel -``` - - - - -> Or using your package manager of choice - -## Complex implementation - -Below is an example of a more complex implementation with `searchParameters`, a different `variant`, and some translations. - -```tsx -import { DocSearch } from '@docsearch/core'; -import { SidepanelButton, Sidepanel } from '@docsearch/sidepanel' - -function App() { - return ( - - - - - ); -} -``` - -## Dynamic importing - -Sidepanel is built in a way that allows for dynamic importing of its components to help reduce bundle size. Below is a brief example of how to do so: - -```tsx -import { DocSearch } from '@docsearch/core'; -import { SidepanelButton } from '@docsearch/sidepanel/button'; -import type { Sidepanel as SidepanelType} from '@docsearch/sidepanel/sidepanel'; -import { useState } from 'react'; - -let Sidepanel: typeof SidepanelType | null = null; - -async function importSidepanelIfNeeded() { - if (Sidepanel) { - return; - } - - const { Sidepanel: Panel } = await import('@docsearch/sidepanel/sidepanel'); - - Sidepanel = Panel; -} - -export default function DynamicSidepanel() { - const [sidepanelLoaded, setSidepanelLoaded] = useState(false); - - const loadSidepanel = () => { - importSidepanelIfNeeded().then(() => { - setSidepanelLoaded(true); - }); - }; - - return ( - - - {sidepanelLoaded && Sidepanel && ( - - )} - - ); -} -``` - -## Hybrid Mode - -Hybrid Mode allows you to combine the Sidepanel and the original DocSearch Modal in one integrated experience. - -You can trigger the Modal for search and the Sidepanel for AI-powered assistance. - -Learn more in the [Hybrid Mode guide][1]. - -[1]: /docs/sidepanel/hybrid +For JavaScript, see the [`@docsearch/sidepanel-js` API](/docs/packages/sidepanel-js/api). diff --git a/packages/website/docs/sidepanel/api-reference.mdx b/packages/website/docs/sidepanel/api-reference.mdx index b0a78b0b..783dbf63 100644 --- a/packages/website/docs/sidepanel/api-reference.mdx +++ b/packages/website/docs/sidepanel/api-reference.mdx @@ -1,148 +1,9 @@ --- -title: Sidepanel API Reference +title: Sidepanel API references +description: Reference the DocSearch sidepanel APIs and configuration options. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +Choose the API reference for your application: -## `appId` - -> `type: string` | **required** - -Your Algolia application ID. - -## `apiKey` - -> `type: string` | **required** - -Your Algolia Search API key. - -## `assistantId` - -> `type: string` | **required** - -The ID for which Ask AI assistant to use. - -## `indexName` - -> `type: string` | **required** - -The name of the index to be used with the Ask AI service. - -## `agentStudio` - -> `type: boolean` | **optional** | **experimental** - -:::warning[Experimental] - -`agentStudio` is currently an experimental property. It is targeted to be stable in release `5.0.0`. - -::: - -If `agentStudio` is true, the Ask AI chat will use Algolia's [Agent Studio][2] as the chat backend instead of the Ask AI backend. More can be learned about setting up Agent Studio on their dedicated [documentation page][3]. - -## `searchParameters` - -## `variant` - -> `type: 'floating' | 'inline'` | default: `'floating'` | **optional** - -Variant of the Sidepanel positioning. - -- `inline` pushes page content when opened. -- `floating` is positioned above all other content on the page. - -## `side` - -> `type: 'right' | 'left'` | default: `'right'` | **optional** - -The side of the page which the panel will originate from. - -## `width` - -> `type: number | string` | default: `'360px'` | **optional** - -Width of the Sidepanel (px or any CSS width) while in it's default state. - -## `expandedWidth` - -> `type: number | string` | default: `'580px'` | **optional** - -Width of the Sidepanel (px or any CSS width) while in it's expanded state. - -## `suggestedQuestions` - -> `type: boolean` | default: `false` | **optional** - -Enables displaying suggested questions on new conversation screen. - -More information on setting up Suggested Questions can be found on [Algolia Docs][1] - -## `keyboardShortcuts` - -> `type: { 'Ctrl/Cmd+I': boolean }` | **optional** - -Configuration for keyboard shortcuts. Allows enabling/disabling specific shortcuts. - -### Default behavior: - -- `Ctrl/Cmd+I` - Opens and closes the Sidepanel - -### Interface: - -```ts -interface SidepanelShortcuts { - 'Ctrl/Cmd+I'?: boolean; // default: true -} -``` - -## `theme` - -> `type: 'light' | 'dark'` | default: `'light'` | **optional** - -## `portalContainer` (React only) - -> `type: Element | DocumentFragment` | default: `document.body` | **optional** - -The container element where the panel should be portaled to. Use this when you need the Sidepanel to render in a custom DOM node. - -:::warning -This prop only exists in the React based versions of Sidepanel. If you are using the `@docsearch/sidepanel-js` package, use the `container` option instead. -::: - - - - ```tsx - // assume you have a dedicated DOM node in your HTML -
    - - const portalEl = document.getElementById('sidepanel-root'); - - - ``` - - - - ```js - sidepanel({ - // The element that will contain the Sidepanel Button and Sidepanel - container: '#sidepanel-root', - indexName: 'YOUR_INDEX_NAME', - appId: 'YOUR_APP_ID', - apiKey: 'YOUR_SEARCH_API_KEY', - assistantId: 'YOUR_ASSISTANT_ID', - }) - ``` - - - -[1]: https://www.algolia.com/doc/guides/algolia-ai/askai/guides/suggested-questions -[2]: https://www.algolia.com/products/ai/agent-studio -[3]: https://www.algolia.com/doc/guides/algolia-ai/agent-studio +- [`@docsearch/sidepanel` API](/docs/packages/sidepanel/api) +- [`@docsearch/sidepanel-js` API](/docs/packages/sidepanel-js/api) diff --git a/packages/website/docs/sidepanel/getting-started.mdx b/packages/website/docs/sidepanel/getting-started.mdx index 67237a56..dd1ee4cd 100644 --- a/packages/website/docs/sidepanel/getting-started.mdx +++ b/packages/website/docs/sidepanel/getting-started.mdx @@ -1,136 +1,11 @@ --- -title: Get started with Sidepanel +title: Get started with the sidepanel +description: Add the DocSearch Agent Studio sidepanel to your site. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +Choose the sidepanel package for your application: -:::info -Sidepanel is available from version `>= 4.4` -::: +- Use [`@docsearch/sidepanel`](/docs/packages/sidepanel/getting-started) with React. +- Use [`@docsearch/sidepanel-js`](/docs/packages/sidepanel-js/getting-started) with JavaScript. -## Introduction - -DocSearch Sidepanel is a new experience separate from the DocSearch Modal experience. Sidepanel is built entirely for usage with Ask AI and can be used completely standalone or in [Hybrid mode][1] with the Modal. - -## Installation - -To get started with Sidepanel, first you will need to install the needed packages: - - - - -```bash -npm install @docsearch/react @docsearch/css - -# Or if using JS based package - -npm install @docsearch/sidepanel-js @docsearch/css -``` - - - - - -```bash -yarn add @docsearch/react @docsearch/css - -# Or if using JS based package - -yarn add @docsearch/sidepanel-js @docsearch/css -``` - - - - - -```bash -pnpm add @docsearch/react @docsearch/css - -# Or if using JS based package - -pnpm add @docsearch/sidepanel-js @docsearch/css -``` - - - - - -```bash -bun add @docsearch/react @docsearch/css - -# Or if using JS based package - -bun add @docsearch/sidepanel-js @docsearch/css -``` - - - - -> Or using your package manager of choice - -### Without package manager - -```html - - - - -``` - -## Implementation - -The simplest implementation of Sidepanel would be as follows: - - - -```tsx -import { DocSearchSidepanel } from '@docsearch/react/sidepanel'; - -import '@docsearch/css/dist/style.css'; -import '@docsearch/css/dist/sidepanel.css'; - -function App() { - return ( - - ); -} -``` - - - -You will need a `container` DOM node to render the Sidepanel into: - -```html -
    -``` - -```js -import sidepanel from '@docsearch/sidepanel-js'; - -import '@docsearch/css/dist/style.css'; -import '@docsearch/css/dist/sidepanel.css'; - -sidepanel({ - container: '#docsearch-sidepanel', - indexName: 'YOUR_INDEX_NAME', - appId: 'YOUR_APP_ID', - apiKey: 'YOUR_SEARCH_API_KEY', - assistantId: 'YOUR_ASSISTANT_ID', -}); -``` -
    -
    - -This is just the most basic form of implementation. To learn about other implementation methods, you can read our [Advanced use cases][2]. - -To learn more about the different configuration options for Sidepanel, you can read our [Sidepanel API References][3] - -[1]: /docs/sidepanel/hybrid -[2]: /docs/sidepanel/advanced-use-cases -[3]: /docs/sidepanel/api-reference +To combine the sidepanel with keyword search, follow the [Hybrid Mode guide](/docs/hybrid-mode). diff --git a/packages/website/docs/sidepanel/hybrid.mdx b/packages/website/docs/sidepanel/hybrid.mdx index 4549010b..748bb87a 100644 --- a/packages/website/docs/sidepanel/hybrid.mdx +++ b/packages/website/docs/sidepanel/hybrid.mdx @@ -1,167 +1,8 @@ --- title: Hybrid Mode +description: Combine DocSearch keyword search with the Agent Studio sidepanel. --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +Use [Hybrid Mode](/docs/hybrid-mode) to combine the keyword-search modal with an Agent Studio sidepanel. -## Introduction - -Sidepanel can run alongside the DocSearch Modal through what we call "Hybrid Mode." When a user initiates an Ask AI action from within -the DocSearch Modal, such as submitting a prompt or selecting an AI-related suggestion, the interface automatically transitions into the Sidepanel for -the continuation of the conversation. - -## Set up - -To set up the Hybrid Mode experience, you will need the following: - -- [DocSearch Modal][1] packages installed -- [Sidepanel Component][2] package installed - -The needed packages can be installed as follows: - - - - -```bash -npm install @docsearch/css @docsearch/modal @docsearch/sidepanel - -# Or if using JS based packages - -npm install @docsearch/css @docsearch/js @docsearch/sidepanel-js -``` - - - - - -```bash -yarn add @docsearch/css @docsearch/modal @docsearch/sidepanel - -# Or if using JS based packages - -yarn add @docsearch/css @docsearch/js @docsearch/sidepanel-js -``` - - - - - -```bash -pnpm add @docsearch/css @docsearch/modal @docsearch/sidepanel - -# Or if using JS based packages - -pnpm add @docsearch/css @docsearch/js @docsearch/sidepanel-js -``` - - - - - -```bash -bun add @docsearch/css @docsearch/modal @docsearch/sidepanel - -# Or if using JS based packages - -bun add @docsearch/css @docsearch/js @docsearch/sidepanel-js -``` - - - - -> Or using your package manager of choice - -## Implementation - -Once everything is installed, you can set up Hybrid Mode as such: - - - - -```tsx -import { DocSearch } from '@docsearch/core'; -import { DocSearchButton, DocSearchModal } from '@docsearch/modal'; -import { SidepanelButton, Sidepanel } from '@docsearch/sidepanel'; - -import '@docsearch/css/dist/style.css'; -import '@docsearch/css/dist/sidepanel.css'; - -function HybridMode() { - return ( - - - - - - - - ); -} -``` - -There is no manual opt-in for Hybrid Mode to work. When both the Modal and Sidepanel are rendered inside the same `` context, Hybrid Mode is enabled automatically. No additional configuration is required. - - - - - -```html -
    -
    -``` - -```js -import docsearch from '@docsearch/js'; -import sidepanel from '@docsearch/sidepanel-js'; - -import '@docsearch/css/dist/style.css'; -import '@docsearch/css/dist/sidepanel.css'; - -let docsearchInstance = undefined; -let sidepanelInstance = undefined; - -sidepanelInstance = sidepanel({ - container: "#sidepanel", - indexName: "YOUR_INDEX_NAME", - appId: "YOUR_APP_ID", - apiKey: "YOUR_SEARCH_API_KEY", - assistantId: "YOUR_ASSISTANT_ID", - onOpen: () => { - docsearchInstance?.close(); - } -}); - -docsearchInstance = docsearch({ - container: "#docsearch", - indices: ["YOUR_INDEX_NAME"], - appId: "YOUR_APP_ID", - apiKey: "YOUR_SEARCH_API_KEY", - askAi: "YOUR_ASSISTANT_ID", // Or configuration object - interceptAskAiEvent: (initialMessage) => { - docsearchInstance?.close(); - sidepanelInstance.open(initialMessage); - return true; - }, - onOpen: () => { - sidepanelInstance?.close(); - } -}); - -``` - -
    -
    - -[1]: /docs/docsearch#installation -[2]: /docs/sidepanel/getting-started#installation +The guide covers React, JavaScript, and Docusaurus integrations. diff --git a/packages/website/docs/styling.md b/packages/website/docs/styling.md index 0146763f..d3f85039 100644 --- a/packages/website/docs/styling.md +++ b/packages/website/docs/styling.md @@ -1,46 +1,11 @@ --- -title: Styling +title: Styling DocSearch +description: Customize the appearance of DocSearch v5 with CSS packages and bundles. --- -:::info +Use [`@docsearch/css`][1] to style DocSearch v5. -The following content is for **[DocSearch v4][2]**. If you are using **[DocSearch v3][3]**, see the **[legacy][4]** documentation. +The package provides a complete stylesheet and separate bundles for the button, keyword modal, Ask AI interface, and sidepanel. See [CSS bundles and exports][2] to choose the files for your integration. -::: - -## Introduction - -DocSearch v4 comes with a theme package called `@docsearch/css`, which offers a sleek out of the box theme! - -:::note - -This package is a dependency of [`@docsearch/js`][1] and [`@docsearch/react`][1], you don't need to install it if you are using a package manager! - -::: - -## Installation - -```bash -npm install @docsearch/css@4 -``` - -If you don’t want to use a package manager, you can use a standalone endpoint: - -```html - -``` - -## Files - -``` -@docsearch/css -β”œβ”€β”€ dist/style.css # all styles -β”œβ”€β”€ dist/_variables.css # CSS variables -β”œβ”€β”€ dist/button.css # CSS for the button -└── dist/modal.css # CSS for the modal -``` - -[1]: /docs/docsearch -[2]: https://github.com/algolia/docsearch/ -[3]: https://github.com/algolia/docsearch/tree/master -[4]: /docs/v3/docsearch +[1]: /docs/packages/css/styling +[2]: /docs/packages/css/bundle-exports diff --git a/packages/website/docs/templates.mdx b/packages/website/docs/templates.mdx index b6185ed4..091bdbad 100644 --- a/packages/website/docs/templates.mdx +++ b/packages/website/docs/templates.mdx @@ -1,22 +1,27 @@ --- title: Config Templates +description: Start a DocSearch crawler configuration from a framework template. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -To help you create the best search experience for your users, we provide out-of-the-box crawler config templates for multiple websites generators. If you'd like to add a new template to our list, or believe we should update an existing one, please [let us know on Discord][1] or [open a pull request][2]. +Use these crawler configuration templates as a starting point for supported website generators. To add or update a template, [contact us on Discord][1] or [open a pull request][2]. > If you want to better understand the default parameters of the configs below, take a look at the [Crawler documentation](https://www.algolia.com/doc/tools/crawler/apis/configuration/). -## Getting Started +## Getting started -Once approved for DocSearch, we will automatically create a Crawler on your behalf, include your URL, and the Algolia creditials for your appId, apiKey, and indexName. If we detected that you are using any of the predefined generators, we'll attempt to automatically assign the proper template that matches your generator. However, this is not gauranteed. If no specific generator is detected, we will apply the default template seen below. +After approval, the onboarding flow creates a crawler with your URL and Algolia credentials. If it detects one of the listed generators, it can assign the matching template. Otherwise, it applies the default template. -## Updating the Template +These templates configure indexing, not the installed DocSearch frontend package. In a template, `recordVersion: 'v3'` means the crawler's v3 record schema; it doesn't mean DocSearch UI v3. -You can manually update the crawler template by going to dashboard.algolia.com, click "Data sources", select your crawler, and go to the editor page. From there you can edit the Javascript directly. Note that you can make draft changes without saving, test the changes using the "URL Tester", and then "Save" once you're happy with your changes. +For v5 facets, add each custom filter attribute to `attributesForFaceting` and expose no more than five keys in the frontend. For `resultBadgeKey`, add the selected property to `attributesToRetrieve`. Keep `hierarchy.lvl0` through `hierarchy.lvl6` populated and retrievable so v5 can render result breadcrumbs. See the [v5 JavaScript API reference](/docs/packages/js/api-reference#facets). -## Default Template +## Update a template + +You can manually update the crawler template by going to dashboard.algolia.com, click "Data sources", select your crawler, and go to the editor page. From there you can edit the JavaScript directly. Note that you can make draft changes without saving, test the changes using the "URL Tester", and then "Save" once you're happy with your changes. + +## Default template
    default.js @@ -117,7 +122,7 @@ new Crawler({
    -## Docusaurus v1 Template +## Docusaurus v1 template
    docusaurus-v1.js @@ -274,7 +279,7 @@ new Crawler({
    -## Docusaurus v2 & v3 Template +## Docusaurus v2 and later template
    docusaurus-v2.js @@ -296,12 +301,14 @@ new Crawler({ pathsToMatch: ['https://YOUR_WEBSITE_URL/**'], recordExtractor: ({ $, helpers }) => { // priority order: deepest active sub list header -> navbar active item -> 'Documentation' + // Extracting the breadcrumb titles for better accessibility. + const navbarTitle = $('.navbar__item.navbar__link--active').text(); + const pageBreadcrumbTitles = $('.breadcrumbs__link') + .toArray() + .map((item) => $(item).text().trim()) + .filter(Boolean); const lvl0 = - $( - '.menu__link.menu__link--sublist.menu__link--active, .navbar__item.navbar__link--active' - ) - .last() - .text() || 'Documentation'; + [navbarTitle, ...pageBreadcrumbTitles].join(' / ') || 'Documentation'; return helpers.docsearch({ recordProps: { @@ -413,23 +420,23 @@ new Crawler({ // Get the top level menu item const lvl0 = $('details:has(a[aria-current="page"])') - .find("summary") - .find("span") - .text() || "Documentation"; + .find('summary') + .find('span') + .text() || 'Documentation'; return helpers.docsearch({ recordProps: { lvl0: { - selectors: "", + selectors: '', defaultValue: lvl0, }, - lvl1: "main h1", - lvl2: "main h2", - lvl3: "main h3", - lvl4: "main h4", - lvl5: "main h5", - lvl6: "main h6", - content: "main p, main li", + lvl1: 'main h1', + lvl2: 'main h2', + lvl3: 'main h3', + lvl4: 'main h4', + lvl5: 'main h5', + lvl6: 'main h6', + content: 'main p, main li', }, indexHeadings: true, aggregateContent: true, @@ -439,16 +446,8 @@ new Crawler({ ], initialIndexSettings: { YOUR_INDEX_NAME: { - attributesForFaceting: [ - 'type', - 'lang', - ], - attributesToRetrieve: [ - 'hierarchy', - 'content', - 'anchor', - 'url', - ], + attributesForFaceting: ['type', 'lang'], + attributesToRetrieve: ['hierarchy', 'content', 'anchor', 'url'], attributesToHighlight: ['hierarchy', 'content'], attributesToSnippet: ['content:10'], camelCaseAttributes: ['hierarchy', 'content'], @@ -813,37 +812,34 @@ new Crawler({ pathsToMatch: ['https://YOUR_WEBSITE_URL/**'], recordExtractor: ({ $, helpers }) => { const lvl0 = - $(".rspress-nav-menu-item.rspress-nav-menu-item-active") + $('.rspress-nav-menu-item.rspress-nav-menu-item-active') .first() - .text() || "Documentation"; + .text() || 'Documentation'; return helpers.docsearch({ recordProps: { lvl0: { - selectors: "", + selectors: '', defaultValue: lvl0, }, - lvl1: ".rspress-doc h1", - lvl2: ".rspress-doc h2", - lvl3: ".rspress-doc h3", - lvl4: ".rspress-doc h4", - lvl5: ".rspress-doc h5", - lvl6: ".rspress-doc pre > code", // if you want to search code blocks, add this line - content: ".rspress-doc p, .rspress-doc li", + lvl1: '.rspress-doc h1', + lvl2: '.rspress-doc h2', + lvl3: '.rspress-doc h3', + lvl4: '.rspress-doc h4', + lvl5: '.rspress-doc h5', + lvl6: '.rspress-doc pre > code', // if you want to search code blocks, add this line + content: '.rspress-doc p, .rspress-doc li', }, indexHeadings: true, aggregateContent: true, - recordVersion: "v3", + recordVersion: 'v3', }); }, }, ], initialIndexSettings: { YOUR_INDEX_NAME: { - attributesForFaceting: [ - 'type', - 'lang', - ], + attributesForFaceting: ['type', 'lang'], attributesToRetrieve: [ 'hierarchy', 'content', diff --git a/packages/website/docs/tips.md b/packages/website/docs/tips.md index 57d1c4fa..7bcaebcb 100644 --- a/packages/website/docs/tips.md +++ b/packages/website/docs/tips.md @@ -1,71 +1,76 @@ --- title: Tips for a good search +description: Improve DocSearch relevance with clear content structure and crawler selectors. --- -DocSearch can work with almost any website, but we've found that some site structures yield more relevant results or faster indexing time. On this page we'll share some tips on how to make the most out of DocSearch. +DocSearch works with many website structures, but consistent structure can improve relevance and indexing time. Follow these recommendations to improve your DocSearch results. ## Use a `sitemap.xml` -If you provide a sitemap in your configuration, DocSearch will use it to directly browse the pages to index. Pages are still crawled which means we extract every compliant link. +If you provide a sitemap in your crawler configuration, DocSearch uses it to find pages to index. The crawler also follows eligible links on those pages. -We highly recommend you add a `sitemap.xml` to your website if you don't have one already. This will not only make the indexing faster, but also provide you more control over which pages to index. +Add a `sitemap.xml` to your website if you don't have one. A sitemap can reduce indexing time and gives you more control over which pages are indexed. -Sitemaps are also considered good practice for other aspects, including SEO ([more information on sitemaps][1]). +Sitemaps can also improve search engine optimization. For more information, see the [sitemaps specification][1]. ## Structure the hierarchy of information -DocSearch works better on structured documentation. Relevance of results is based on the structural hierarchy of content. In simpler terms, it means that we read the `

    `, ..., `

    ` headings of your page to guess the hierarchy of information. This hierarchy brings contextual information to your records. +DocSearch works better on structured documentation. Result relevance uses the structural hierarchy of your content. The crawler reads the `

    ` through `

    ` headings or equivalent selectors to build `hierarchy.lvl0` through `hierarchy.lvl6`. -Documentation starts by explaining generic concepts first and then goes deeper into specifics. This is represented in your HTML markup by the hierarchy of headings you're using. For example, concepts discussed under a `

    ` are more specific than concepts discussed under a `

    ` in the same page. The sooner the information comes up within the page, the higher is it ranked. +Documentation usually introduces general concepts before covering details. Represent this structure with an ordered heading hierarchy. For example, content under an `

    ` is more specific than content under an `

    ` on the same page. Content that appears earlier on the page ranks higher. -DocSearch uses this structure to fine-tune the relevance of results as well as to provide potential filtering. Documentations that follow this pattern often have better relevance in their search results. +DocSearch uses this structure to improve relevance. V5 also uses the populated hierarchy levels to render result breadcrumbs. Keep headings in order and avoid skipping levels where possible so each result retains its page context. -Finding the right depth of your documentation tree and how to split up your content are two of the most complex tasks. For large pages, we recommend having 4 levels (from `lvl0` to `lvl3`). We recommend at least three different levels. +Choose a documentation depth that gives each result enough context. For large pages, use four levels, from `lvl0` to `lvl3`. Use at least three levels. -_Note that you don't have to use `` tags and can use classes instead (e.g., `` )._ +You can use classes, such as ``, instead of `` elements. ## Set a unique class to the element holding the content DocSearch extracts content based on the HTML structure. We recommend that you add a custom `class` to the HTML element wrapping all your textual content. This will help narrow selectors to the relevant content. -Having such a unique identifier will make your configuration more robust as it will make sure indexed content is relevant content. We found that this is the most reliable way to exclude content in headers, sidebars, and footers that are not relevant to the search. +A unique identifier makes your configuration more robust and limits indexing to relevant content. Use it to exclude unrelated headers, sidebars, and footers. ## Add anchors to headings -When using headings (as mentioned above), you should also try to add a custom anchor to each of them. Anchors are specified by HTML attributes (`name` or `id`) added to headers that allow browsers to directly scroll to the right position in the page. They're accessible by clicking a link with `#` followed by the anchor. +Add a custom anchor to each heading. Define anchors with an `id` or `name` HTML attribute so browsers can scroll directly to the corresponding position. Links can target an anchor with `#` followed by its value. -DocSearch will honor such anchors and automatically bring your users to the anchor closest to the search result they selected. +DocSearch uses these anchors to send users to the location of the selected result. -## Marking the active page(s) in the navigation +## Mark active pages in the navigation -If you're using a multi-level navigation, we recommend that you mark each active level with a custom CSS class. This will make it easier for DocSearch to know _where_ the current page fits in the website hierarchy. +If you use multi-level navigation, mark each active level with a custom CSS class. The crawler can use this class to determine where the current page fits in the website hierarchy. For example, if your `troubleshooting.html` page is located under the "Installation" menu in your sidebar, we recommend that you add a custom CSS class to the "Installation" and "Troubleshooting" links in your sidebar. -The name of the CSS class does not matter, as long as it's something that can be used as part of a CSS selector. +Use any valid CSS class name that can be part of a CSS selector. ## Consistency of your content -Consistency is a pillar of meaningful documentation. It increases the **intelligibility** of a document and shortens the time required for a user to find the coveted information. The document **topic** should be **identifiable** and its **outline** should be demarcated. +Use the same heading structure across documentation pages. Make each page topic and outline clear, and avoid selectors that create records without enough context, such as standalone introductions or asides. -The hierarchy should always have the same size. Try to **avoid orphan records** such as the introduction/conclusion, or asides. The selectors must be efficient for **every document** and highlight the proper hierarchy. They need to match the coveted elements depending on their level. Be careful to avoid the **edge effect** by matching unexpected **superfluous elements**. +Write selectors that match documentation pages but exclude landing pages, tables of contents, and other unrelated content. Add a dedicated class, such as `.DocSearch-content`, to the main documentation container. -Selectors should match information from **real document web pages** and stay ineffective for others ones (e.g., landing page, table of content, etc.). We urge the maintainer to define a **dedicated class** for the **main DOM container** that includes the actual document content such as `.DocSearch-content` +Use consistent terms for the same concepts. You can also configure [synonyms][5] for terms your users search interchangeably. -Since documentation should be **interactive**, it is a key point to **verbalize concepts with standardized words**. This **redundancy**, empowered with the **search experience** (dropdown), will even enable the **learn-as-you-type experience**. The **way to find the information** plays a key role in **leading** the user to the **retrieved knowledge**. You can also use the **synonym feature**. +## Avoid duplicate content -## Avoid duplicates by promoting unicity +Split broad topics into focused pages. Avoid catch-all pages that make it difficult to identify the relevant result. -The more time-consuming reading documentation is, the more painful and reluctant its use will be. You must avoid hazy points or catch-all. With being unhelpful, the catch-all document may be **confusing** and **counterproductive**. +Duplicate content adds noise and can mislead users. Don't repeat all documentation content on a landing or summary page. If you need duplicate records for separate datasets, such as different versions, use [facets][3] to distinguish them. -Duplicates introduce noise and mislead users. This is why you should always focus on the relevant content and avoid duplicating content within your site (for example landing page which contains all information, summing up, etc.). If duplicates are expected because they belong to multiple datasets (for example a different version), you should use [facets][3]. +## Index metadata for v5 + +Add each attribute used by the v5 `facets` option to `attributesForFaceting`. DocSearch supports up to five facet controls. For a result badge, index a short value such as `version`, include it in `attributesToRetrieve`, and pass its property path to `resultBadgeKey`. See the [v5 JavaScript API reference][4]. ## Conciseness -What is clearly thought out is clearly and concisely expressed. +Keep content focused on one task or concept, and use short headings and paragraphs. -We highly recommend that you read this blog post about [how to build a helpful search for technical documentation][2]. +For more guidance, read [How to build a helpful search for technical documentation][2]. [1]: https://www.sitemaps.org/index.html [2]: https://blog.algolia.com/how-to-build-a-helpful-search-for-technical-documentation-the-laravel-example/ [3]: https://www.algolia.com/doc/guides/searching/faceting/ +[4]: /docs/packages/js/api-reference#facets +[5]: https://www.algolia.com/doc/guides/managing-results/must-do/searchable-attributes/#synonyms diff --git a/packages/website/docs/v5-breaking-changes.mdx b/packages/website/docs/v5-breaking-changes.mdx new file mode 100644 index 00000000..f3ec2ef5 --- /dev/null +++ b/packages/website/docs/v5-breaking-changes.mdx @@ -0,0 +1,236 @@ +--- +title: v5 breaking changes +description: Complete user-facing breaking changes and compatibility notes for DocSearch v5. +--- + +This page lists the user-facing changes between the v4.6.0 package source and `5.0.0-beta.0`. Use it with the [v4 migration guide](./migrating-from-v4). + +## JavaScript entry points + +### The root export is AI-capable + +In v4, the root `@docsearch/js` export rendered the combined component and allowed Ask AI to be omitted. In v5, it renders `DocSearchAI`, and its `DocSearchProps` type requires `askAi`. + +Use the root entry when you configure Agent Studio: + +```js title="app.js" +import docsearch from '@docsearch/js'; +``` + +### Keyword-only search moved to `/docsearch` + +Use the new subpath when you don't need Ask AI: + +```js title="app.js" +import docsearch from '@docsearch/js/docsearch'; +``` + +This entry excludes Ask AI code. + +### The UMD bundle is split + +- `dist/umd/index.js` includes keyword search and Ask AI. +- `dist/umd/docsearch.js` includes keyword search only. +- Both bundles expose `window.docsearch`. +- Loading both bundles causes the later script to replace the same global. + +### An exports map restricts JavaScript imports + +`@docsearch/js` now exports only `.` and `./docsearch`. Replace imports of internal distribution files with one of these public entry points. Direct CDN URLs to the two documented UMD files remain supported by the package layout. + +## React components + +### `DocSearch` is keyword-only + +V4's `DocSearch` accepted `askAi` and `interceptAskAiEvent`. V5's `DocSearch` contains keyword search only and no longer declares those props. + +### `DocSearchAI` owns the AI experience + +Use `DocSearchAI` for keyword search and Ask AI: + +```jsx title="Search.jsx" +import { DocSearchAI } from '@docsearch/react'; +``` + +`DocSearchAIProps` extends `DocSearchProps`, requires `askAi`, and adds `interceptAskAiEvent`. + +The package also adds `@docsearch/react/docsearchAi` and `@docsearch/react/askaiModal` subpaths. + +### The Ask AI modal is separate + +`DocSearchModal` is keyword-only. `DocSearchAskAiModal` contains the combined keyword and AI modal. Composable integrations that rendered `DocSearchModal` with `askAi` must switch to `DocSearchAskAiModal` and its required provider callbacks. Review the [Composable API](/docs/composable-api) instead of constructing these props without the provider. + +`@docsearch/modal` exports the AI modal from its root and from `@docsearch/modal/askai`. + +## Ask AI and Agent Studio + +### The legacy transport is removed + +V5 no longer requests a legacy Ask AI token or sends chat requests to the v4 Ask AI endpoint. All Ask AI conversations use the Agent Studio completions endpoint. + +Create and configure an assistant in [Agent Studio](/docs/agent-studio/getting-started) before upgrading. + +### `askAi.agentStudio` is removed + +The backend switch is no longer needed because Agent Studio is the only backend. Remove both `agentStudio: true` and `agentStudio: false`. + +### `askAi.useStagingEnv` is removed + +The staging endpoint switch isn't part of `DocSearchAskAi` in v5. + +### Flat Ask AI search parameters are removed + +`DocSearchAskAi.searchParameters` now always uses `AgentStudioSearchParameters`: an object keyed by index name. + +```js title="app.js" +searchParameters: { + docs: { + filters: 'language:en', + attributesToRetrieve: ['title', 'content', 'url'], + distinct: true, + }, +} +``` + +Each value supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. The Agent Studio type omits `facetFilters`. + +### Agent Studio credentials are sent directly + +Ask AI requests use the configured application ID and API key in `x-algolia-application-id` and `x-algolia-api-key` headers. Memory authentication adds `x-algolia-secure-user-token`. Check the permissions and domain restrictions of keys that were issued for the legacy transport. + +### Feedback uses Agent Studio + +Feedback now posts to Agent Studio and supports negative-feedback reason tags and notes. Stored conversation messages can contain `feedbackTags` and `feedbackNotes` in addition to the like or dislike value. + +### Agent Studio configuration is nested under `askAi` + +Dynamic `indices`, custom `tools`, `memory`, and keyword `promptSuggestions` belong inside the `askAi` object. `interceptAskAiEvent` remains a top-level integration callback. + +### Suggested questions have two sources + +- `askAi.suggestedQuestions` determines whether DocSearch loads published questions for the assistant from `algolia_ask_ai_suggested_questions` on the new-conversation screen. +- `askAi.promptSuggestions` searches a configured index containing a `prompt` attribute and displays those prompts with keyword results. + +These options aren't interchangeable. + +## Search configuration + +### The Docusaurus adapter configuration changed + +The v5 adapter reads `themeConfig.docsearch` and rejects the former `themeConfig.algolia` key. It also requires `indices` and rejects `indexName` and root `searchParameters`. + +Replace `searchPagePath` with `searchPage`. Move `askAi.sidePanel` to the root `sidePanel` option. Remove legacy Ask AI credentials and the `askAi.agentStudio` switch. Follow [Migrate the Docusaurus adapter from v4](/docs/packages/docusaurus-adapter/migrating-from-v4) for before-and-after configurations. + +### At least one index is required at runtime + +Pass `indices` or `indexName`. V5 throws this error when neither produces an index: + +```text +Must supply either `indexName` or `indices` for DocSearch to work +``` + +### `indexName` remains deprecated + +`indexName` still works; it isn't removed in v5. If present, DocSearch places it before all `indices` entries. Passing the same index through both options sends duplicate requests. + +### Root `searchParameters` remains deprecated + +The root option applies only to `indexName`. Move search parameters to each `DocSearchIndex` in `indices`. + +### Multiple indices share one result flow + +V5 creates one source for each index response and combines hit totals across responses. Result order follows the normalized index order. Review code that assumes one index or source identifier. + +## New keyword search behavior + +### Facets add requests and filters + +The new `facets` option fetches facet values with a zero-hit query for every configured index. DocSearch merges and sorts values, supports at most five keys after trimmed, lowercase duplicate checks, and displays only facets with values. + +A selected value is appended to that index's existing `facetFilters`. Account for the additional facet-value request in analytics, rate estimates, and search-client mocks. + +### Result badges require retrieved attributes + +The new `resultBadgeKey` reads a property path from each hit. The default `attributesToRetrieve` list doesn't include custom badge properties. Add them to each relevant index's `searchParameters.attributesToRetrieve`. + +### Result markup and grouping changed + +V5 refreshes the modal and result markup, renders breadcrumbs, introduces source panels, and adds facet and badge elements. CSS selectors, DOM tests, snapshots, and custom overrides that target v4 internals can break. + +Use public component props for behavior and review [Styling](/docs/packages/css/styling) for visual changes. + +## Styles and builds + +### Ask AI styles have a separate source bundle + +The complete `@docsearch/css` stylesheet still imports button, modal, and Ask AI rules. React also exposes split style entries: + +- `@docsearch/react/style/variables` +- `@docsearch/react/style/button` +- `@docsearch/react/style/modal` +- `@docsearch/react/style/askai` +- `@docsearch/react/style/sidepanel` + +If you assemble styles by component, add `style/askai` for `DocSearchAI` or `DocSearchAskAiModal`. + +### Generated React file names changed + +The documented package subpaths remain stable, but their targets changed from names such as `dist/esm/DocSearchModal.js` to generated entry files such as `dist/esm/modal.js`. Imports that bypassed the package exports can break. + +### The React `main` field now points to ESM + +`@docsearch/react` changes `main` from `dist/umd/index.js` to `dist/esm/index.js`. Consumers that resolve `main` instead of the package exports need an ESM-compatible build pipeline. The explicit `unpkg` and `jsdelivr` fields continue to point to `dist/umd/index.js`. + +### The browser target is ES2017 + +V5's tsdown builds target ES2017. Provide transpilation or polyfills if your browser support policy extends below that target. + +## Public controls + +### JavaScript instances don't expose Sidepanel state + +`DocSearchInstance` exposes `open`, `close`, `openAskAi`, `destroy`, `isReady`, and `isOpen`. It doesn't expose `openSidepanel`, `isSidepanelOpen`, or `isSidepanelSupported`. + +### React refs include Sidepanel controls + +`DocSearchRef` exposes the JavaScript-style modal controls plus `openSidepanel`, `isSidepanelOpen`, and `isSidepanelSupported`. `openSidepanel` does nothing until a Sidepanel view registers. On mobile, `openAskAi` and standard Ask AI actions fall back to the modal. + +See [hybrid mode](/docs/hybrid-mode) for the supported integration. + +### Deprecated keyboard hook fields remain + +`UseDocSearchKeyboardEventsProps.onInput` and `searchButtonRef` are accepted for compatibility but are deprecated and aren't used by the v5 React hook implementation. + +## Compatibility + +### React peer range + +`@docsearch/react`, `@docsearch/core`, `@docsearch/modal`, and `@docsearch/sidepanel` declare these optional peers: + +- `react`: `>=16.8.0 <20.0.0` +- `react-dom`: `>=16.8.0 <20.0.0` +- `@types/react`: `>=16.8.0 <20.0.0` + +`@docsearch/react` also accepts optional `search-insights` versions `>=1 <3`. + +### Package versions must match + +The `5.0.0-beta.0` packages depend on matching beta versions of the other DocSearch packages. Don't mix v4 and v5 packages in a Composable API or Sidepanel tree. + +### CSS remains a separate install for top-level integrations + +Install `@docsearch/css@^5.0.0-beta`, then import `@docsearch/css`. For a CDN integration, load `dist/style.css` from the same caret beta range. + +## Additive v5 APIs + +These additions aren't breaking by themselves, but they replace common v4 custom implementations: + +- `facets` and `DocSearchFacet` for keyword filters. +- `resultBadgeKey` for hit metadata. +- `DocSearchAI` and `DocSearchAskAiModal` for AI-capable React views. +- `AgentStudioIndices` and `AgentStudioSearchControls` for dynamic search tools. +- `ToolCalls` and `ToolDefinition` for custom Agent Studio tools. +- `Memory` for user-scoped Agent Studio memory. +- `PromptSuggestions` for keyword-query prompt suggestions. +- Ask AI feedback tags and notes. +- Split JavaScript, React, and style entries for smaller keyword-only builds. diff --git a/packages/website/docs/what-is-docsearch.md b/packages/website/docs/what-is-docsearch.md index 5b9cc3c9..cd0ecc17 100644 --- a/packages/website/docs/what-is-docsearch.md +++ b/packages/website/docs/what-is-docsearch.md @@ -1,24 +1,27 @@ --- title: What is DocSearch? +description: Understand how DocSearch provides search for technical documentation. sidebar_label: What is DocSearch? --- ## Why? -We created DocSearch because we are scratching our own itch. As developers, we spend a lot of time reading documentation, and it can be hard to find relevant information in large documentations. We're not blaming anyone here: building good search is a challenge. +We created DocSearch because developers spend a lot of time reading documentation, and finding relevant information in large documentation sites can be difficult. Building good search is a challenge. -It happens that we are a search company and we actually have a lot of experience building search interfaces. We wanted to use those skills to help others. That's why we created a way to automatically extract content from tech documentation and make it available to everyone from the first keystroke. +Algolia has extensive experience building search interfaces. We use that experience to extract content from technical documentation and make it searchable from the first keystroke. -## Quick description +## Overview -We split DocSearch into a crawler and a frontend library. +DocSearch has two independent parts: indexing and the frontend search experience. -- Crawls are handled by the [Algolia Crawler][4] and scheduled to run once a week by default, you can then trigger new crawls yourself and monitor them directly from the [Crawler interface][5], which also offers a live editor where you can maintain your config. -- The frontend library is built on top of [Algolia Autocomplete][6] and provides an immersive search experience through its modal. +- The [Algolia Crawler][4] extracts your documentation into an Algolia index. Use the [Crawler interface][5] to edit the crawler configuration, monitor crawls, and trigger new crawls. +- The [DocSearch v5 packages][7] query that index and render keyword search or Ask AI in your frontend. They are built on [Algolia Autocomplete][6]. + +Crawler configuration and record schema versions don't select the installed DocSearch frontend package version. You can update the frontend package without changing how the crawler is scheduled. ## How to feature DocSearch? -DocSearch is entirely free and automated. The one thing we'll need from you is to read [our checklist][2] and apply! After that, we'll share with you the snippet needed to add DocSearch to your website. We ask that you keep the "Search by Algolia" link displayed. +DocSearch is free for eligible documentation sites. Read [the eligibility requirements][2] and apply. After approval and indexing, add a [DocSearch v5 package][7] or a supported framework integration to your website. Keep the "Search by Algolia" link displayed. DocSearch is [one of our ways][1] to give back to the open source community for everything it did for us already. @@ -30,3 +33,4 @@ You can now [apply to the program][3] [4]: https://www.algolia.com/products/search-and-discovery/crawler/ [5]: https://dashboard.algolia.com/crawler [6]: https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/ +[7]: /docs/packages/overview diff --git a/packages/website/docs/who-can-apply.md b/packages/website/docs/who-can-apply.md index 320814d0..317b2249 100644 --- a/packages/website/docs/who-can-apply.md +++ b/packages/website/docs/who-can-apply.md @@ -1,30 +1,32 @@ --- title: Who can apply? +description: Check whether your documentation project is eligible for DocSearch. --- -**Open for all developer documentation and technical blogs.** +**Open to developer documentation and technical blogs.** -We built DocSearch from the ground up with the idea of improving search on large technical documentations. For this reason, we are offering a free hosting version to all online technical documentations and technical blogs. +We built DocSearch to improve search on large technical documentation sites. We offer the free DocSearch program to public technical documentation and technical blogs. We usually turn down applications when they are not production ready or have non-technical content on the website. ## Application process -To [apply][1] to the DocSearch program, follow the DocSearch onboarding process in the Algolia dashboard where you'll submit your domain for an automated validation check against our requirements. If your domain meets all criteria, you'll be quickly approved to proceed with creating your DocSearch crawler. +To [apply][1] to the DocSearch program, follow the onboarding process in the Algolia dashboard. Submit your domain for validation against the program requirements. If your domain meets the criteria, you can create your DocSearch crawler. -- βœ… Using one of our official integrations will streamline your implementation process after data ingestion. +- Use one of our [supported integrations][3] or a [DocSearch v5 package][5] after your content is indexed. -- βœ… You must verify your domain ownership within 7 days of approval to continue using the crawler. +- Verify your domain ownership within 7 days of approval to continue using the crawler. -- βœ… Please review [DocSearch Plan Terms and Conditions][2]. +- Review the [DocSearch Plan Terms and Conditions][2]. ## Process duration -DocSearch application process includes automated validation for faster processing. However, if we can't automatically determine your eligibility, we'll conduct a manual review that may take 1-2 business days. +The application process includes automated validation. If we can't determine your eligibility automatically, we'll conduct a manual review that may take one to two business days. -Once approved, you can continue the onboarding process to create your DocSearch crawler. After your data is ingested into Algolia, you'll need to implement the search UI using either our provided code snippet or one of our [integrations][3]. +Once approved, continue the onboarding process to create your DocSearch crawler. After the crawler indexes your data, choose the frontend package or framework integration separately. Updating the frontend doesn't change your crawler or index format. [1]: https://dashboard.algolia.com/users/sign_up?selected_plan=docsearch&utm_source=docsearch.algolia.com&utm_medium=referral&utm_campaign=docsearch&utm_content=apply [2]: https://www.algolia.com/policies/docsearch-plan-specific-terms [3]: integrations.md [4]: https://alg.li/discord +[5]: /docs/packages/overview diff --git a/packages/website/docusaurus.config.mjs b/packages/website/docusaurus.config.mjs index f1605941..8c70af8f 100644 --- a/packages/website/docusaurus.config.mjs +++ b/packages/website/docusaurus.config.mjs @@ -50,7 +50,10 @@ export default { 'https://github.com/algolia/docsearch/edit/main/packages/website/', versions: { current: { - label: 'Latest (v4.x)', + label: 'Beta (v5.0.0-beta.x)', + }, + v4: { + label: 'Stable (v4.x)', }, v3: { label: 'Legacy (v3.x)', @@ -138,9 +141,9 @@ export default { ], }, announcementBar: { - id: 'announcement-bar', + id: 'docsearch-v5-beta', content: - 'πŸš€ Get Ask AI now! Turn your docs site search into an AI-powered assistant – faster answers, fewer tickets, better self-serve. Get Started Now', + 'DocSearch 5.0.0-beta is available. Migrate from v4 or choose a package.', }, colorMode: { defaultMode: 'light', @@ -165,8 +168,12 @@ export default { to: 'docs/v3/docsearch', }, { - label: 'DocSearch v4 - Beta', - to: 'docs/docsearch', + label: 'DocSearch v4', + to: 'docs/v4/docsearch', + }, + { + label: 'DocSearch v5 beta', + to: 'docs/packages/overview', }, ], }, diff --git a/packages/website/sidebars.js b/packages/website/sidebars.js index cc5d370b..c4fbae84 100644 --- a/packages/website/sidebars.js +++ b/packages/website/sidebars.js @@ -13,19 +13,87 @@ export default { { type: 'category', label: 'Introduction', - items: ['what-is-docsearch', 'who-can-apply'], + items: [ + 'what-is-docsearch', + 'who-can-apply', + 'migrating-from-v4', + 'v5-breaking-changes', + ], }, { type: 'category', - label: 'DocSearch v4', + label: 'Packages', items: [ - 'docsearch', - 'docusaurus-adapter', + 'packages/overview', + { + type: 'category', + label: '@docsearch/js', + items: ['packages/js/getting-started', 'packages/js/api-reference'], + }, + { + type: 'category', + label: '@docsearch/react', + items: [ + 'packages/react/getting-started', + 'packages/react/api-reference', + 'packages/react/examples', + ], + }, + { + type: 'category', + label: '@docsearch/modal', + items: ['packages/modal/overview', 'packages/modal/api'], + }, + { + type: 'category', + label: '@docsearch/sidepanel', + items: [ + 'packages/sidepanel/getting-started', + 'packages/sidepanel/advanced-use-cases', + 'packages/sidepanel/api', + ], + }, + { + type: 'category', + label: '@docsearch/sidepanel-js', + items: [ + 'packages/sidepanel-js/getting-started', + 'packages/sidepanel-js/api', + ], + }, + { + type: 'category', + label: '@docsearch/css', + items: ['packages/css/styling', 'packages/css/bundle-exports'], + }, + { + type: 'category', + label: '@docsearch/core', + items: ['packages/core/overview', 'packages/core/api'], + }, + { + type: 'category', + label: '@docsearch/docusaurus-adapter', + items: [ + 'packages/docusaurus-adapter/getting-started', + 'packages/docusaurus-adapter/configuration-reference', + 'packages/docusaurus-adapter/migrating-from-v4', + ], + }, 'composable-api', - 'styling', - 'api', - 'examples', - 'migrating-from-v3', + 'hybrid-mode', + ], + }, + { + type: 'category', + label: 'Agent Studio', + items: [ + 'agent-studio/getting-started', + 'agent-studio/dynamic-indices', + 'agent-studio/tools', + 'agent-studio/memory', + 'agent-studio/prompt-suggestions', + 'agent-studio/feedback', ], }, { @@ -33,34 +101,6 @@ export default { label: 'MCP', items: ['mcp/overview', 'mcp/installation', 'mcp/usage'], }, - { - type: 'category', - label: 'Algolia Ask AI', - items: [ - 'v4/askai', - 'v4/askai-api', - 'v4/askai-prompts', - 'v4/askai-whitelisted-domains', - 'v4/askai-models', - 'v4/askai-markdown-indexing', - 'v4/askai-errors', - { - type: 'link', - label: 'Full Documentation', - href: 'https://www.algolia.com/doc/guides/algolia-ai/askai', - }, - ], - }, - { - type: 'category', - label: 'Sidepanel', - items: [ - 'sidepanel/getting-started', - 'sidepanel/advanced-use-cases', - 'sidepanel/hybrid', - 'sidepanel/api-reference', - ], - }, { type: 'category', label: 'Algolia Crawler', diff --git a/packages/website/src/components/Home.js b/packages/website/src/components/Home.js index a8a4ea86..ee5dbb91 100644 --- a/packages/website/src/components/Home.js +++ b/packages/website/src/components/Home.js @@ -116,9 +116,9 @@ function Home() {
    + eyebrow="Interactive demo" + title="See DocSearch in action" + />
    diff --git a/packages/website/versioned_docs/version-v4/api.mdx b/packages/website/versioned_docs/version-v4/api.mdx new file mode 100644 index 00000000..ecf87ebb --- /dev/null +++ b/packages/website/versioned_docs/version-v4/api.mdx @@ -0,0 +1,935 @@ +--- +title: API Reference +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + + + + +## `container` + +> `type: string | HTMLElement` | **required** + +The container for the DocSearch search box. You can either pass a [CSS selector][5] or an [Element][6]. If there are several containers matching the selector, DocSearch picks up the first one. + +## `environment` + +> `type: typeof window` | `default: window` | **optional** + +The environment in which your application is running. + +This is useful if you’re using DocSearch in a different context than `window`. + + + + +## `appId` + +> `type: string` | **required** + +Your Algolia application ID. + +## `apiKey` + +> `type: string` | **required** + +Your Algolia Search API key. + +## `indices` + +> `type: Array` + +The list of indices and their _optional_ `searchParameters` to be used for keyword search. + +[Algolia Search Parameters][7] + +:::tip + +The ordering matters in the list, as results are ordered based on `indices` order. + +::: + +> While `indexName` is in deprecation, it is required to pass either `indices` or `indexName`. Not passing either will result in an `Error` being thrown. + + + + +```js +docsearch({ + // ... + indices: ['YOUR_ALGOLIA_INDEX'], + // ... +}); +``` + +in case you want to use custom `searchParameters` for the index + +```js +docsearch({ + // ... + indices: [ + { + name: 'YOUR_ALGOLIA_INDEX', + searchParameters: { + facetFilters: ['language:en'], + // ... + }, + }, + ], + // ... +}); +``` + + + + + +```jsx + +``` + +in case you want to use custom `searchParameters` for the index + +```jsx + +``` + + + + +## `indexName` + +> `type: string` | **deprecated** + +:::warning[Deprecation warning] + +`indexName` is currently being planned for deprecation. The new recommended property to use is `indices`. + +::: + +Your Algolia index name. + +> While `indexName` is in deprecation, it is required to pass either `indices` or `indexName`. Not passing either will result in an `Error` being thrown. + +## `placeholder` + +> `type: string` | `default: "Search docs"` | **optional** + +The placeholder of the input of the DocSearch pop-up modal. Note: If you add a placeholder, it will replace the dynamic placeholder based on `askAi`. It would be better to edit [translations](#translations) instead. + +## `askAi` + +> `type: AskAiObject` | `string` | **optional** + +Your Algolia Assistant ID. + + + + +```js +docsearch({ + // ... + askAi: 'YOUR_ALGOLIA_ASSISTANT_ID', + // ... +}); +``` + +or if you want to use different credentials for `askAi` and add search parameters + +```js +docsearch({ + // ... + askAi: { + indexName: 'ANOTHER_INDEX_NAME', + apiKey: 'ANOTHER_SEARCH_API_KEY', + appId: 'ANOTHER_APP_ID', + assistantId: 'YOUR_ALGOLIA_ASSISTANT_ID', + searchParameters: { + // Filtering parameters + facetFilters: ['language:en', 'version:latest'], + filters: 'type:content AND language:en', + + // Content control parameters + attributesToRetrieve: ['title', 'content', 'url'], + restrictSearchableAttributes: ['title', 'content'], + + // Deduplication + distinct: true, + }, + + // Enables/disables showing suggested questions on Ask AI's new conversation screen + // NOTE: Only available with version >= 4.3 + suggestedQuestions: true, + }, + // ... +}); +``` + + + + + +```jsx + +``` + +in case you want to use different credentials for `askAi` + +```jsx += 4.3 + suggestedQuestions: true, + }} +/> +``` + + + + +:::tip[Ask AI supports these essential search parameters for optimal performance:] + +- **Filtering**: `facetFilters: ['type:content']` - Filter by language, version, or content type +- **Complex filtering**: `filters: 'type:content AND language:en'` - Apply complex filtering rules +- **Content control**: `attributesToRetrieve: ['title', 'content', 'url']` - Control which attributes are retrieved +- **Search scope**: `restrictSearchableAttributes: ['title', 'content']` - Limit search to specific fields +- **Deduplication**: `distinct: true` - Remove duplicate results (`boolean | number | string`) + +These parameters provide the essential functionality for Ask AI while keeping the API simple and focused. + +::: + +### `askAi.agentStudio` + +> `type: boolean` | **optional** | **experimental** + +:::warning[Experimental] + +`askAi.agentStudio` is currently an experimental property. It is targeted to be stable in release `5.0.0`. + +::: + +If `askAi.agentStudio` is `true`, the Ask AI chat will use Algolia's [Agent Studio][12] as the chat backend instead of the Ask AI backend. Learn more on [Algolia Agent Studio Docs][13]. + +```js +docsearch({ + // ... + askAi: { + assistantId: 'YOUR_ALGOLIA_ASSISTANT_ID', + agentStudio: true, + searchParameters: { + YOUR_INDEX_NAME: { + filters: 'type:content AND language:en', + attributesToRetrieve: ['title', 'content', 'url'], + restrictSearchableAttributes: ['title', 'content'], + distinct: 'url', + }, + }, + }, +}); +``` + +::::info[Search parameter shapes] + +- Standard Ask AI (`agentStudio` omitted or `false`): `searchParameters` is a flat object and supports `facetFilters`, `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. +- Agent Studio (`agentStudio: true`): `searchParameters` must be keyed by index name and supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. + +:::: + +## `searchParameters` + +> `type: SearchParameters` | **optional** | **deprecated** + +:::warning[Deprecation warning] + +`searchParameters` is currently being planned for deprecation. The new recommended property to use is `indices`. + +::: + +The [Algolia Search Parameters][7]. + +## `transformItems` + +> `type: function` | `default: items => items` | **optional** + +Receives the items from the search response, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them. + + + + +```js +docsearch({ + // ... + transformItems(items) { + return items.map((item) => ({ + ...item, + content: item.content.toUpperCase(), + })); + }, +}); +``` + + + + + +```jsx + { + return items.map((item) => ({ + ...item, + content: item.content.toUpperCase(), + })); + }} +/> +``` + + + + +## `hitComponent` + +> `type: ({ hit, children }, { html }) => JSX.Element | string | Function` | `default: Hit` | **optional** + +The component to display each item. Supports template patterns: + +- **HTML strings with html helper** (recommended for JS CDN): `({ hit, children }, { html }) => html...` +- **JSX templates** (for React/Preact): `({ hit, children }) =>
    ...
    ` +- **Function-based templates**: `(props) => string | JSX.Element | Function` + +You get access to the `hit` object which contains all the data for the search result, and `children` which is the default rendered content. + +See the [default implementation][8]. + + + + +```js +docsearch({ + // ... + hitComponent({ hit, children }, { html }) { + // Using HTML strings with html helper + return html` + +
    πŸ”
    +
    ${children}
    +
    + `; + }, +}); +``` + +
    + + + +```jsx + { + // Using JSX templates + return ( + +
    πŸ”
    +
    {children}
    +
    + ); + }} +/> +``` + +
    +
    + +## `transformSearchClient` + +> `type: function` | `default: DocSearchTransformClient => DocSearchTransformClient` | **optional** + +Useful for transforming the [Algolia Search Client][10], for example to [debounce search queries][9] + +## `disableUserPersonalization` + +> `type: boolean` | `default: false` | **optional** + +Disable saving recent searches and favorites to the local storage. + +## `initialQuery` + +> `type: string` | **optional** + +The search input initial query. + +## `navigator` + +> `type: Navigator` | **optional** + +An implementation of [Algolia Autocomplete][1]’s Navigator API to redirect the user when opening a link. + +Learn more on the [Navigator API][11] documentation. + +## `translations` + +> `type: Partial` | `default: docSearchTranslations` | **optional** + +Allow translations of any raw text and aria-labels present in the DocSearch button or modal components. + +
    +docSearchTranslations +
    + +```ts +const translations: DocSearchTranslations = { + button: { + buttonText: 'Search', + buttonAriaLabel: 'Search', + }, + modal: { + searchBox: { + clearButtonTitle: 'Clear', + clearButtonAriaLabel: 'Clear the query', + closeButtonText: 'Close', + closeButtonAriaLabel: 'Close', + placeholderText: undefined, // fallback: 'Search docs' or 'Search docs or ask AI a question' + placeholderTextAskAi: undefined, // fallback: 'Ask another question...' + placeholderTextAskAiStreaming: 'Answering...', + // can only be one of the following + // https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/enterkeyhint#value + enterKeyHint: 'search', + enterKeyHintAskAi: 'enter', + searchInputLabel: 'Search', + backToKeywordSearchButtonText: 'Back to keyword search', + backToKeywordSearchButtonAriaLabel: 'Back to keyword search', + newConversationPlaceholder: 'Ask a question', + conversationHistoryTitle: 'My conversation history', + startNewConversationText: 'Start a new conversation', + viewConversationHistoryText: 'Conversation history' + }, + startScreen: { + recentSearchesTitle: 'Recent', + noRecentSearchesText: 'No recent searches', + saveRecentSearchButtonTitle: 'Save this search', + removeRecentSearchButtonTitle: 'Remove this search from history', + favoriteSearchesTitle: 'Favorite', + removeFavoriteSearchButtonTitle: 'Remove this search from favorites', + recentConversationsTitle: 'Recent conversations', + removeRecentConversationButtonTitle: + 'Remove this conversation from history', + }, + errorScreen: { + titleText: 'Unable to fetch results', + helpText: 'You might want to check your network connection.', + }, + noResultsScreen: { + noResultsText: 'No results found for', + suggestedQueryText: 'Try searching for', + reportMissingResultsText: 'Believe this query should return results?', + reportMissingResultsLinkText: 'Let us know.', + }, + resultsScreen: { + askAiPlaceholder: 'Ask AI: ', + noResultsAskAiPlaceholder: 'Didn't find it in the docs? Ask AI to help: ', + }, + askAiScreen: { + disclaimerText: + 'Answers are generated with AI which can make mistakes. Verify responses.', + relatedSourcesText: 'Related sources', + thinkingText: 'Thinking...', + copyButtonText: 'Copy', + copyButtonCopiedText: 'Copied!', + copyButtonTitle: 'Copy', + likeButtonTitle: 'Like', + dislikeButtonTitle: 'Dislike', + thanksForFeedbackText: 'Thanks for your feedback!', + preToolCallText: 'Searching...', + duringToolCallText: 'Searching for ', + afterToolCallText: 'Searched for', + // If provided, these override the default rendering of aggregated tool calls: + aggregatedToolCallNode: undefined, // (queries: string[], onSearchQueryClick: (query: string) => void) => React.ReactNode + aggregatedToolCallText: undefined, // (queries: string[]) => { before?: string; separator?: string; lastSeparator?: string; after?: string } + // Text to show when user has stopped streaming a message + stoppedStreamingText: 'You stopped this response', + }, + footer: { + selectText: 'Select', + submitQuestionText: 'Submit question', + selectKeyAriaLabel: 'Enter key', + navigateText: 'Navigate', + navigateUpKeyAriaLabel: 'Arrow up', + navigateDownKeyAriaLabel: 'Arrow down', + closeText: 'Close', + backToSearchText: 'Back to search', + closeKeyAriaLabel: 'Escape key', + poweredByText: 'Powered by', + }, + newConversation: { + newConversationTitle: 'How can I help you today?', + newConversationDescription: 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.' + } + }, +}; +``` + +
    +
    + +## `getMissingResultsUrl` + +> `type: ({ query: string }) => string` | **optional** + +Function to return the URL of your documentation repository. + + + + +```js +docsearch({ + // ... + getMissingResultsUrl({ query }) { + return `https://github.com/algolia/docsearch/issues/new?title=${query}`; + }, +}); +``` + + + + + +```jsx + { + return `https://github.com/algolia/docsearch/issues/new?title=${query}`; + }} +/> +``` + + + + +When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property. + +
    + No results screen with informative message +
    + +## `keyboardShortcuts` + +> `type: KeyboardShortcuts` | **optional** + +Configuration for keyboard shortcuts that trigger the search modal. + +### Default behavior: + +- `Ctrl/Cmd+K` - Opens and closes the search modal +- `/` - Opens the search modal (doesn't close) + +### Interface: + +```typescript +interface KeyboardShortcuts { + 'Ctrl/Cmd+K'?: boolean; // default: true + '/'?: boolean; // default: true +} +``` + + + + +```js +// Default - all shortcuts enabled +docsearch({ + // ... +}); + +// Disable slash shortcut +docsearch({ + // ... + keyboardShortcuts: { '/': false }, +}); + +// Disable Ctrl/Cmd+K shortcut (also hides button hint) +docsearch({ + // ... + keyboardShortcuts: { 'Ctrl/Cmd+K': false }, +}); + +// Disable all keyboard shortcuts +docsearch({ + // ... + keyboardShortcuts: { 'Ctrl/Cmd+K': false, '/': false }, +}); +``` + + + + + +```jsx +{ + /* Default - all shortcuts enabled */ +} +; + +{ + /* Disable slash shortcut */ +} +; + +{ + /* Disable Ctrl/Cmd+K shortcut (also hides button hint) */ +} +; + +{ + /* Disable all keyboard shortcuts */ +} +; +``` + + + + +:::info[Keyboard Shortcut Behavior] + +- **Ctrl/Cmd+K**: Toggle shortcut that both opens and closes the modal +- **/**: Character shortcut that only opens the modal (prevents interference with search typing) +- **Escape**: Always works to close the modal regardless of Configuration + +::: + +## `resultsFooterComponent` + +> `type: ({ state }, { html }) => JSX.Element | string | Function` | **optional** + +The component to display below the search results. Supports template patterns: + +- **HTML strings with html helper** (recommended for JS CDN): `({ state }, { html }) => html...` +- **JSX templates** (for React/Preact): `({ state }) =>
    ...
    ` +- **Function-based templates**: `(props) => string | JSX.Element | Function` + +You get access to the [current state](https://github.com/algolia/autocomplete/blob/next/packages/autocomplete-core/src/types/AutocompleteState.ts) which allows you to retrieve the number of hits returned, the query etc. + + + + +```js +docsearch({ + // ... + resultsFooterComponent({ state }, { html }) { + // Using HTML strings with html helper + return html` + + `; + }, +}); +``` + + + + + +```jsx + { + // Using JSX templates + return ( + + ); + }} +/> +``` + + + + +## `maxResultsPerGroup` + +> `type: number` | **optional** + +The maximum number of results to display per search group. Default is 5. + +[You can find a working example without JSX in this sandbox](https://codesandbox.io/s/docsearch-v3-maxresultspergroup-without-jsx-ct9m22?file=/src/index.js) + + + + +```js +docsearch({ + // ... + maxResultsPerGroup: 7, +}); +``` + + + + + +## `recentSearchesLimit` + +> `type: number` | `default: 7` | **optional** + +The maximum number of recent searches that are stored for the user. Default is 7. + + + + +```js +docsearch({ + // ... + recentSearchesLimit: 12, + // ... +}); +``` + + + + + +```jsx + +``` + + + + +## `recentSearchesWithFavoritesLimit` + +> `type: number` | `default: 4` | **optional** + +The maximum number of recent searches that are stored when the user has favorited searches. Default is 4. + + + + +```js +docsearch({ + // ... + recentSearchesWithFavoritesLimit: 5, + // ... +}); +``` + + + + + +```jsx + +``` + + + + +## `portalContainer` (React-only) + +> `type: Element | DocumentFragment` | `default: document.body` | **optional** + +The element where the DocSearch modal will be portaled. Use this when you need the overlay to render in a custom DOM nodeβ€”for example when working inside a shadow root, a specific layout container, or a modal manager. When omitted, the modal portals to `document.body`. + +:::warning + +This prop only exists in `@docsearch/react`. If you are using **`@docsearch/js`**, use the [`container`](#container) option insteadβ€”the value you pass there is both the **mount point** of the search button _and_ the portal target for the modal. + +::: + + + + +```jsx +// assume you have a dedicated modal root in your html +