# Analytics
URL: /docs/customization/analytics
Description: Track product and usage events from docs, search, AI, feedback, agent, and MCP routes

# Analytics

Use `analytics` when you want to understand how people and agents use your docs. It emits
product-level usage events: page views, search activity, Ask AI requests, feedback, page actions,
machine-readable markdown reads, agent feedback routes, and MCP requests.

Analytics is intentionally separate from [Observability](/docs/customization/observability).
Analytics answers "what did users or agents do?" Observability answers "what happened inside this
agent run?"

## Quick Start

```ts title="docs.config.ts"
export default defineDocs({
  analytics: true,
});
```

`analytics: true` logs usage events to the console with the `[@farming-labs/docs:analytics]`
prefix.

## Send Events To Your Own Sink

```ts title="docs.config.ts"
export default defineDocs({
  analytics: {
    async onEvent(event) {
      await fetch("https://analytics.example.com/events", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(event),
      });
    },
  },
});
```

The callback receives a normalized `DocsAnalyticsEvent`:

```ts
interface DocsAnalyticsEvent {
  type: string;
  timestamp: string;
  source: "client" | "server" | "mcp";
  url?: string;
  path?: string;
  referrer?: string;
  locale?: string;
  input?: {
    query?: string;
    question?: string;
    feedbackComment?: string;
    content?: string;
  };
  metadata?: Record<string, unknown>;
  properties?: Record<string, unknown>;
}
```

## Event Types

Analytics events describe product usage: what a person or agent did, which surface they used, and
whether the action completed.

### Client Events

| Event                            | Meaning                                                                 |
| -------------------------------- | ----------------------------------------------------------------------- |
| `page_view`                      | A docs page was viewed in the browser.                                  |
| `search_open`                    | The search UI was opened.                                               |
| `search_close`                   | The search UI was closed.                                               |
| `search_query`                   | A search query was submitted or changed enough to run search.           |
| `search_result_click`            | A search result was selected.                                           |
| `search_error`                   | Client-side search failed.                                              |
| `ai_open`                        | The Ask AI UI was opened.                                               |
| `ai_close`                       | The Ask AI UI was closed.                                               |
| `ai_question`                    | A user submitted a question to Ask AI from the client UI.                |
| `ai_response`                    | The Ask AI UI received a successful response.                            |
| `ai_feedback`                    | A user rated a completed Ask AI answer with the response feedback buttons. |
| `ai_error`                       | The Ask AI UI encountered an error.                                     |
| `ai_clear`                       | The Ask AI conversation was cleared.                                    |
| `page_action_copy_markdown`      | The Copy Markdown page action was used.                                 |
| `page_action_open_docs_menu`     | The Open in LLM/Open docs page-action menu was opened.                  |
| `page_action_open_docs`          | A destination in the Open in LLM/Open docs menu was selected.           |
| `code_block_copy`                | A code block copy button was clicked.                                   |
| `feedback_select`                | A feedback rating or option was selected.                               |
| `feedback_submit`                | Feedback was submitted successfully.                                    |
| `feedback_error`                 | Feedback submission failed.                                             |

### Server And Agent-Surface Events

| Event                           | Meaning                                                                 |
| ------------------------------- | ----------------------------------------------------------------------- |
| `api_search`                    | The docs API handled a search request.                                  |
| `api_ai_request`                | The docs API accepted an Ask AI request.                                |
| `api_ai_response`               | The docs API returned a successful Ask AI response.                     |
| `api_ai_error`                  | The docs API rejected or failed an Ask AI request.                      |
| `agent_read`                    | A page was read through a machine-readable docs surface.                |
| `markdown_request`              | A markdown route or API markdown request was served.                    |
| `llms_request`                  | `/llms.txt` or `/llms-full.txt` was requested.                          |
| `skill_request`                 | An Agent Skills file or skill index was requested.                      |
| `agent_spec_request`            | The agent-facing docs spec endpoint was requested.                      |
| `agent_feedback_schema`         | The agent feedback schema endpoint was requested.                       |
| `agent_feedback_submit`         | Agent feedback was submitted successfully.                              |
| `agent_feedback_error`          | Agent feedback submission failed.                                       |
| `mcp_request`                   | The MCP endpoint received a request.                                    |
| `mcp_tool`                      | An MCP tool call was handled, such as `search_docs` or `read_page`.     |

`agent_read` includes `properties.delivery` so you can see how the page was read: `md_route`,
`accept_header`, `api_format`, or `mcp_tool`.

## Input Privacy

By default, analytics events include safe metadata such as paths, counts, durations, status, result
counts, model IDs, content lengths, and whether a comment exists.

<Callout type="warning" title="Inputs are excluded by default">
  Search queries, AI questions, feedback comments, and copied content are not included unless you
  explicitly set `includeInputs: true`.
</Callout>

Enable raw input capture only when you have user consent and a retention policy:

```ts title="docs.config.ts"
export default defineDocs({
  analytics: {
    includeInputs: true,
    onEvent(event) {
      console.info(event);
    },
  },
});
```

## Options

| Option          | Type                                      | Default                      |
| --------------- | ----------------------------------------- | ---------------------------- |
| `enabled`       | `boolean`                                 | `true` when object is passed |
| `console`       | `boolean \| "log" \| "info" \| "debug"` | `true` for `analytics: true` |
| `includeInputs` | `boolean`                                 | `false`                      |
| `onEvent`       | `(event) => void \| Promise<void>`        | `undefined`                  |

Configure both streams when you want usage analytics and runtime traces:

```ts title="docs.config.ts"
export default defineDocs({
  analytics: {
    onEvent: sendUsageEvent,
  },
  observability: {
    console: "debug",
    onEvent: sendTraceEvent,
  },
});
```