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. Analytics answers "what did users or agents do?" Observability answers "what happened inside this agent run?"
Quick Start
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
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:
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.
Inputs are excluded by default
Search queries, AI questions, feedback comments, and copied content are not included unless you
explicitly set includeInputs: true.
Enable raw input capture only when you have user consent and a retention policy:
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:
export default defineDocs({
analytics: {
onEvent: sendUsageEvent,
},
observability: {
console: "debug",
onEvent: sendTraceEvent,
},
});How is this guide?