Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/standalone-dialog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'ondocs': minor
'starlight-ondocs': minor
---

The Astro, Starlight and VitePress plugins no longer need React. Their dialog now comes prebuilt with its own React, Radix and cmdk, from the new `ondocs/embed/standalone`, so a site installs `ondocs`, `ai` and `@ai-sdk/openai` and nothing else. Before, a Vue or Astro site without React had to install `react`, `react-dom`, `@radix-ui/react-dialog` and `cmdk`, or its build failed. `ondocs init` no longer lists them for these sites, and `starlight-ondocs` no longer asks for them as peers, so npm no longer installs them with it. The dialog still loads only the first time it is wanted, in a chunk of its own: 92.6 KB gzipped on the Starlight example (93.6 KB before) and 95.6 KB on the VitePress one (96.8 KB before). A site that installed the four packages only for the dialog can remove them. On an Astro site with React islands, the dialog no longer shares their React.

`ondocs/embed/standalone` has the same `mountAskDialog` and `openAskDialog` as `ondocs/embed`, for an app with a bundler and no React. On such a site, import `openAskDialog` from it: `ondocs/embed` renders the dialog with the site's React, so the build fails without React installed. `launcherScript` from `ondocs/integration` now mounts the launcher with it.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Each answers from an endpoint you deploy as one function next to the site, rate-

**Live demos:** [Starlight](https://ondocs-starlight.vercel.app), [Docusaurus](https://ondocs-docusaurus.vercel.app), [VitePress](https://ondocs-vitepress.vercel.app).

**Starlight.** `npm i ondocs ai @ai-sdk/openai react react-dom @radix-ui/react-dialog cmdk`, then:
**Starlight.** `npm i ondocs ai @ai-sdk/openai`, then:

```js
// astro.config.mjs
Expand Down
31 changes: 16 additions & 15 deletions examples/docusaurus/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ description: "The package's imports, the core functions for building and searchi

The package has one CLI and these imports. Each is tree-shakeable, and only `ondocs/node`, `ondocs/integration`, the framework plugins and the CLI touch Node.js built-ins, so the rest runs on edge runtimes, in workers and in browsers.

| Import | For |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `ondocs` | Loaders, chunking, `buildIndex`, `checkIndex`, `loadIndex`, `retrieve`, `buildLlmsFiles`, `mcpInstallLinks` |
| `ondocs/node` | `loadDirectory`, `readIndexFile`, `writeIndexFile`, and the config module's types |
| `ondocs/integration` | The build helpers the plugins are made of, for [writing an integration](./writing-an-integration.md) |
| `ondocs/server` | `createAskHandler`, `createMcpHandler`, `remoteIndex`, the rate limiters, the budget and answer cache stores |
| `ondocs/react` | `AskDialog`, `AskButton`, `useAsk`, `AskAnswer`, `McpInstall` and `loadAskDialog`; needs `@radix-ui/react-dialog` and `cmdk` |
| `ondocs/embed` | `mountAskDialog`: the dialog and its button without writing React; `openAskDialog`, to open any page's dialog |
| `ondocs/docusaurus` | The [Docusaurus plugin](./docusaurus.md) |
| `ondocs/astro` | The [Astro integration](./astro.md) |
| `ondocs/starlight` | The [Starlight plugin](./astro.md) |
| `ondocs/vitepress` | The [VitePress plugin](./vitepress.md): `withOndocs` |
| `ondocs/astro/McpInstall.astro` | The "Add to Cursor / VS Code / Claude" block for an Astro or Starlight page |
| `ondocs/mock` | `mockEmbeddingModel` and `mockLanguageModel`, for tests and offline demos |
| `ondocs` (bin) | [`ondocs index`, `init`, `dev` and `eval`](./cli.md) |
| Import | For |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ondocs` | Loaders, chunking, `buildIndex`, `checkIndex`, `loadIndex`, `retrieve`, `buildLlmsFiles`, `mcpInstallLinks` |
| `ondocs/node` | `loadDirectory`, `readIndexFile`, `writeIndexFile`, and the config module's types |
| `ondocs/integration` | The build helpers the plugins are made of, for [writing an integration](./writing-an-integration.md) |
| `ondocs/server` | `createAskHandler`, `createMcpHandler`, `remoteIndex`, the rate limiters, the budget and answer cache stores |
| `ondocs/react` | `AskDialog`, `AskButton`, `useAsk`, `AskAnswer`, `McpInstall` and `loadAskDialog`; needs `@radix-ui/react-dialog` and `cmdk` |
| `ondocs/embed` | `mountAskDialog`: the dialog and its button without writing React; `openAskDialog`, to open any page's dialog. Needs the site's React, `@radix-ui/react-dialog` and `cmdk` |
| `ondocs/embed/standalone` | The same `mountAskDialog` and `openAskDialog`, with React, Radix and cmdk built into the dialog's chunk, for a site without React. The Astro, Starlight and VitePress plugins use it |
| `ondocs/docusaurus` | The [Docusaurus plugin](./docusaurus.md) |
| `ondocs/astro` | The [Astro integration](./astro.md) |
| `ondocs/starlight` | The [Starlight plugin](./astro.md) |
| `ondocs/vitepress` | The [VitePress plugin](./vitepress.md): `withOndocs` |
| `ondocs/astro/McpInstall.astro` | The "Add to Cursor / VS Code / Claude" block for an Astro or Starlight page |
| `ondocs/mock` | `mockEmbeddingModel` and `mockLanguageModel`, for tests and offline demos |
| `ondocs` (bin) | [`ondocs index`, `init`, `dev` and `eval`](./cli.md) |

The handlers are documented in [The ask endpoint](./ask-endpoint.md) and [MCP server](./mcp.md), and the React components in [The ask dialog](./ask-dialog.md).

Expand Down
2 changes: 1 addition & 1 deletion examples/docusaurus/docs/ask-dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Any element with a `data-ondocs-open` attribute opens the dialog the page has: t
</form>
```

From code, `openAskDialog(question?)` from `ondocs/embed` does the same in any framework, and so does `window.Ondocs.open(question?)` on a page with the script tag. A pointer over the element, or focus on it, loads the dialog's code, as on the launcher. The plugins' `navbar` option puts such a button in the navbar for you: see [Docusaurus](./docusaurus.md#ask-ai-in-the-docusaurus-navbar), [Starlight](./astro.md#ask-ai-in-the-starlight-header) and [VitePress](./vitepress.md#ask-ai-in-the-vitepress-nav-bar). For its look on a button of your own, import `ondocs/embed/button.css` and give the button the `ondocs-button` class, with its label in a `<span class="ondocs-button-label">`.
From code, `openAskDialog(question?)` from `ondocs/embed` does the same in a React app, and so does `window.Ondocs.open(question?)` on a page with the script tag. On a site without React, such as Astro, Starlight or VitePress, import `openAskDialog(question?)` from `ondocs/embed/standalone` instead, or use `data-ondocs-open`, which needs no import: `ondocs/embed` renders the dialog with the site's own React, so the site's build fails where React is not installed. A pointer over the element, or focus on it, loads the dialog's code, as on the launcher. The plugins' `navbar` option puts such a button in the navbar for you: see [Docusaurus](./docusaurus.md#ask-ai-in-the-docusaurus-navbar), [Starlight](./astro.md#ask-ai-in-the-starlight-header) and [VitePress](./vitepress.md#ask-ai-in-the-vitepress-nav-bar). For its look on a button of your own, import `ondocs/embed/button.css` and give the button the `ondocs-button` class, with its label in a `<span class="ondocs-button-label">`.

In React, with a controlled `open`, the `question` prop does the same: set both to open the dialog on a question.

Expand Down
10 changes: 7 additions & 3 deletions examples/docusaurus/docs/astro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ Live demo: [these docs as a Starlight site](https://ondocs-starlight.vercel.app)

## Install for Astro

The dialog is a React component, so install React and its two dependencies along with the AI SDK:
Install ondocs and the AI SDK. The dialog comes with its own React, so your site needs none:

```sh
npm i ondocs ai @ai-sdk/openai react react-dom @radix-ui/react-dialog cmdk
npm i ondocs ai @ai-sdk/openai
```

With ondocs 0.11.0 or earlier, the dialog renders with the site's React: also install `react`, `react-dom`, `@radix-ui/react-dialog` and `cmdk`.

## Add it to Starlight

To add ondocs to Starlight, put the plugin in Starlight's `plugins` array in `astro.config.mjs`:
Expand Down Expand Up @@ -55,7 +57,9 @@ The Astro integration reads each page's `<main>`. Choose another part with `cont

## The dialog in Astro

Both add a floating "Ask AI" button and open the dialog with ⌘I or Ctrl+I, so ⌘K stays with Starlight's search. In Starlight the button sits in the corner of the table of contents column, in Starlight's colors, and the dialog follows its light or dark theme. On other Astro sites the dialog follows `data-theme` on `<html>`, or the system setting. Vite bundles the dialog with your pages, so it shares React with your own islands. With `<ClientRouter />`, the dialog stays across navigations and citations navigate through the router.
Both add a floating "Ask AI" button and open the dialog with ⌘I or Ctrl+I, so ⌘K stays with Starlight's search. In Starlight the button sits in the corner of the table of contents column, in Starlight's colors, and the dialog follows its light or dark theme. On other Astro sites the dialog follows `data-theme` on `<html>`, or the system setting. With `<ClientRouter />`, the dialog stays across navigations and citations navigate through the router.

The dialog comes prebuilt with its own React, Radix and cmdk, from `ondocs/embed/standalone`, also on a site with React islands of its own. Vite splits it off into a chunk that loads the first time it is wanted: 92.6 KB of JavaScript, gzipped, on the Starlight example. Before then, a page carries only the button and the shortcut, and the dialog's stylesheet, 3.5 KB gzipped, which the plugin adds to the site's CSS. Measured on an Apple M1 Max with `node scripts/js-weight.mjs starlight`, in headless Chrome, and `gzip -9` of `ondocs/react/styles.css`.

Pick another key with `dialog: { shortcut: 'j' }`, turn the shortcut off with `shortcut: false`, or hide the button with `launcher: false`. `dialog: { links: 'sources' }` keeps only the answer's links to its source pages.

Expand Down
2 changes: 1 addition & 1 deletion examples/docusaurus/docs/benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Each page carries only the dialog's button and shortcut; the dialog loads the fi
| Site | The site on its own | With ondocs | When the dialog opens |
| -------------------------- | ------------------: | ----------: | --------------------: |
| Docusaurus 3.10 | 173.8 KB | 177.7 KB | +26.6 KB |
| Starlight 0.42 | 33.7 KB | 36.1 KB | +92.7 KB |
| Starlight 0.42 | 33.7 KB | 36.1 KB | +92.6 KB |
| Script tag on a plain page | 0 | 3.2 KB | +97.1 KB |

Starlight's dialog brings its own React, as the script tag's does; Docusaurus's shares the site's. Before the dialog loaded on demand, these pages carried 192.7 KB, 121.2 KB and 91.2 KB. CI measures the example sites the same way, with `node scripts/js-weight.mjs --check`, and fails a change that goes over each site's budget, or that stops a shortcut pressed while the dialog loads from opening it with focus in its input, or focus from coming back when it closes. The handler adds no client code at all.
Expand Down
4 changes: 3 additions & 1 deletion examples/docusaurus/docs/script-tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@ From a script, `window.Ondocs.open(question?)` opens it. With `data-manual`, the

## With a bundler

In an app with a bundler, `mountAskDialog(options)` from `ondocs/embed` does the same with your own copy of React. Install `react`, `react-dom`, `@radix-ui/react-dialog` and `cmdk`, and import `ondocs/react/styles.css` and `ondocs/embed/launcher.css` with it.
In an app with a bundler, `mountAskDialog(options)` from `ondocs/embed/standalone` does the same, with React, Radix and cmdk built into the dialog's chunk, which your bundler splits off to load on first use. Install nothing else, and import `ondocs/react/styles.css` and `ondocs/embed/launcher.css` with it. The Astro, Starlight and VitePress plugins mount it this way.

`mountAskDialog(options)` from `ondocs/embed` is the same, rendered with your own copy of React instead, for an app that already loads React: install `react`, `react-dom`, `@radix-ui/react-dialog` and `cmdk` with it.
8 changes: 5 additions & 3 deletions examples/docusaurus/docs/vitepress.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ Live demo: [these docs as a VitePress site](https://ondocs-vitepress.vercel.app)

## Install for VitePress

The dialog is a React component, so install React and its two dependencies along with the AI SDK. They load with the dialog, the first time a visitor opens it, and never on the rest of your Vue pages:
Install ondocs and the AI SDK. The dialog comes with its own React, which loads with it the first time a visitor opens it, and never on the rest of your Vue pages:

```sh
npm i ondocs ai @ai-sdk/openai react react-dom @radix-ui/react-dialog cmdk
npm i ondocs ai @ai-sdk/openai
```

With ondocs 0.11.0 or earlier, the dialog renders with the site's React: also install `react`, `react-dom`, `@radix-ui/react-dialog` and `cmdk`.

## Add it to .vitepress/config.mts

To add ondocs to VitePress, wrap the config in `withOndocs`:
Expand Down Expand Up @@ -47,7 +49,7 @@ The plugin reads each page's Markdown as the default theme renders it, the `.vp-

## The dialog in VitePress

The plugin adds a floating "Ask AI" button and opens the dialog with ⌘I or Ctrl+I, so ⌘K stays with VitePress's search. The button takes the default theme's colors, and the button and the dialog follow VitePress's light and dark modes, as its appearance switch sets them. A page loads only the button, about 3 KB of JavaScript, and the dialog loads the first time it is wanted. The plugin adds the button through VitePress's own client entry, so there is no theme file to write. With `mpa: true`, VitePress ships no client entry, and pages get no button: add the [script tag](./script-tag.md) to `head` instead.
The plugin adds a floating "Ask AI" button and opens the dialog with ⌘I or Ctrl+I, so ⌘K stays with VitePress's search. The button takes the default theme's colors, and the button and the dialog follow VitePress's light and dark modes, as its appearance switch sets them. A page loads only the button, about 3 KB of JavaScript, and the dialog's stylesheet, 3.5 KB gzipped, which the plugin adds to the site's CSS. The dialog comes prebuilt with its own React, Radix and cmdk, from `ondocs/embed/standalone`, and loads the first time it is wanted: 95.6 KB of JavaScript, gzipped, on the VitePress example. Measured on an Apple M1 Max with `node scripts/js-weight.mjs vitepress`, in headless Chrome, and `gzip -9` of `ondocs/react/styles.css`. The plugin adds the button through VitePress's own client entry, so there is no theme file to write. With `mpa: true`, VitePress ships no client entry, and pages get no button: add the [script tag](./script-tag.md) to `head` instead.

Pick another key with `dialog: { shortcut: 'j' }`, turn the shortcut off with `shortcut: false`, or hide the button with `launcher: false`. `dialog: { links: 'sources' }` keeps only the answer's links to its source pages.

Expand Down
Loading
Loading