@farming-labs/nuxt 0.0.37 → 0.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-reference.d.ts +3 -0
- package/dist/api-reference.d.ts.map +1 -0
- package/dist/api-reference.js +21 -0
- package/dist/api-reference.js.map +1 -0
- package/dist/docs/src/api-reference.d.ts +27 -0
- package/dist/docs/src/api-reference.d.ts.map +1 -0
- package/dist/docs/src/api-reference.js +594 -0
- package/dist/docs/src/api-reference.js.map +1 -0
- package/dist/docs/src/create-theme.d.ts +74 -0
- package/dist/docs/src/create-theme.d.ts.map +1 -0
- package/dist/docs/src/create-theme.js +86 -0
- package/dist/docs/src/create-theme.js.map +1 -0
- package/dist/docs/src/define-docs.d.ts +6 -0
- package/dist/docs/src/define-docs.d.ts.map +1 -0
- package/dist/docs/src/define-docs.js +27 -0
- package/dist/docs/src/define-docs.js.map +1 -0
- package/dist/docs/src/i18n.d.ts +15 -0
- package/dist/docs/src/i18n.d.ts.map +1 -0
- package/dist/docs/src/i18n.js +48 -0
- package/dist/docs/src/i18n.js.map +1 -0
- package/dist/docs/src/index.d.ts +16 -0
- package/dist/docs/src/index.d.ts.map +1 -0
- package/dist/docs/src/index.js +14 -0
- package/dist/docs/src/index.js.map +1 -0
- package/dist/docs/src/metadata.d.ts +24 -0
- package/dist/docs/src/metadata.d.ts.map +1 -0
- package/dist/docs/src/metadata.js +90 -0
- package/dist/docs/src/metadata.js.map +1 -0
- package/dist/docs/src/server.d.ts +3 -0
- package/dist/docs/src/server.d.ts.map +1 -0
- package/dist/docs/src/server.js +2 -0
- package/dist/docs/src/server.js.map +1 -0
- package/dist/docs/src/types.d.ts +1344 -0
- package/dist/docs/src/types.d.ts.map +1 -0
- package/dist/docs/src/types.js +6 -0
- package/dist/docs/src/types.js.map +1 -0
- package/dist/docs/src/utils.d.ts +6 -0
- package/dist/docs/src/utils.d.ts.map +1 -0
- package/dist/docs/src/utils.js +32 -0
- package/dist/docs/src/utils.js.map +1 -0
- package/dist/nuxt/src/api-reference.d.ts +3 -0
- package/dist/nuxt/src/api-reference.d.ts.map +1 -0
- package/dist/nuxt/src/api-reference.js +20 -0
- package/dist/nuxt/src/api-reference.js.map +1 -0
- package/dist/nuxt/src/content.d.ts +54 -0
- package/dist/nuxt/src/content.d.ts.map +1 -0
- package/dist/nuxt/src/content.js +202 -0
- package/dist/nuxt/src/content.js.map +1 -0
- package/dist/nuxt/src/index.d.ts +11 -0
- package/dist/nuxt/src/index.d.ts.map +1 -0
- package/dist/nuxt/src/index.js +11 -0
- package/dist/nuxt/src/index.js.map +1 -0
- package/dist/nuxt/src/markdown.d.ts +18 -0
- package/dist/nuxt/src/markdown.d.ts.map +1 -0
- package/dist/nuxt/src/markdown.js +277 -0
- package/dist/nuxt/src/markdown.js.map +1 -0
- package/dist/nuxt/src/server.d.ts +87 -0
- package/dist/nuxt/src/server.d.ts.map +1 -0
- package/dist/nuxt/src/server.js +726 -0
- package/dist/nuxt/src/server.js.map +1 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -2
- package/dist/server.js.map +1 -1
- package/package.json +9 -2
|
@@ -0,0 +1,1344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme / UI configuration types for the docs framework.
|
|
3
|
+
* Inspired by Fumadocs: https://github.com/fuma-nama/fumadocs
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Fine-grained UI configuration for docs themes.
|
|
7
|
+
*
|
|
8
|
+
* Theme authors define defaults for these values in their `createTheme` call.
|
|
9
|
+
* End users can override any value when calling the theme factory.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const myTheme = createTheme({
|
|
14
|
+
* name: "my-theme",
|
|
15
|
+
* ui: {
|
|
16
|
+
* colors: { primary: "#6366f1", background: "#0a0a0a" },
|
|
17
|
+
* radius: "0px",
|
|
18
|
+
* codeBlock: { showLineNumbers: true, theme: "github-dark" },
|
|
19
|
+
* sidebar: { width: 280, style: "bordered" },
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Font style configuration for a single text element (heading, body, etc.).
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* h1: { size: "2.25rem", weight: 700, lineHeight: "1.2", letterSpacing: "-0.02em" }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export interface FontStyle {
|
|
33
|
+
/** CSS `font-size` value (e.g. "2.25rem", "36px", "clamp(1.8rem, 3vw, 2.5rem)") */
|
|
34
|
+
size?: string;
|
|
35
|
+
/** CSS `font-weight` value (e.g. 700, "bold", "600") */
|
|
36
|
+
weight?: string | number;
|
|
37
|
+
/** CSS `line-height` value (e.g. "1.2", "1.5", "28px") */
|
|
38
|
+
lineHeight?: string;
|
|
39
|
+
/** CSS `letter-spacing` value (e.g. "-0.02em", "0.05em") */
|
|
40
|
+
letterSpacing?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Typography configuration for the docs.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* typography: {
|
|
48
|
+
* font: {
|
|
49
|
+
* style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" },
|
|
50
|
+
* h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" },
|
|
51
|
+
* h2: { size: "1.75rem", weight: 600 },
|
|
52
|
+
* body: { size: "1rem", lineHeight: "1.75" },
|
|
53
|
+
* },
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export interface TypographyConfig {
|
|
58
|
+
/**
|
|
59
|
+
* Font configuration.
|
|
60
|
+
*/
|
|
61
|
+
font?: {
|
|
62
|
+
/**
|
|
63
|
+
* Font family definitions.
|
|
64
|
+
*/
|
|
65
|
+
style?: {
|
|
66
|
+
/** Sans-serif font family — used for body text, headings, and UI elements. */
|
|
67
|
+
sans?: string;
|
|
68
|
+
/** Monospace font family — used for code blocks, inline code, and terminal output. */
|
|
69
|
+
mono?: string;
|
|
70
|
+
};
|
|
71
|
+
/** Heading 1 (`<h1>`) style overrides */
|
|
72
|
+
h1?: FontStyle;
|
|
73
|
+
/** Heading 2 (`<h2>`) style overrides */
|
|
74
|
+
h2?: FontStyle;
|
|
75
|
+
/** Heading 3 (`<h3>`) style overrides */
|
|
76
|
+
h3?: FontStyle;
|
|
77
|
+
/** Heading 4 (`<h4>`) style overrides */
|
|
78
|
+
h4?: FontStyle;
|
|
79
|
+
/** Body text style */
|
|
80
|
+
body?: FontStyle;
|
|
81
|
+
/** Small text style (captions, meta text) */
|
|
82
|
+
small?: FontStyle;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export interface UIConfig {
|
|
86
|
+
/**
|
|
87
|
+
* Theme color tokens.
|
|
88
|
+
*
|
|
89
|
+
* These are mapped to `--color-fd-*` CSS variables at runtime.
|
|
90
|
+
* Accepts any valid CSS color value (hex, rgb, oklch, hsl, etc.).
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* colors: {
|
|
95
|
+
* primary: "oklch(0.72 0.19 149)", // green primary
|
|
96
|
+
* primaryForeground: "#ffffff", // white text on primary
|
|
97
|
+
* accent: "hsl(220 80% 60%)", // blue accent
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
colors?: {
|
|
102
|
+
primary?: string;
|
|
103
|
+
primaryForeground?: string;
|
|
104
|
+
background?: string;
|
|
105
|
+
foreground?: string;
|
|
106
|
+
muted?: string;
|
|
107
|
+
mutedForeground?: string;
|
|
108
|
+
border?: string;
|
|
109
|
+
card?: string;
|
|
110
|
+
cardForeground?: string;
|
|
111
|
+
accent?: string;
|
|
112
|
+
accentForeground?: string;
|
|
113
|
+
secondary?: string;
|
|
114
|
+
secondaryForeground?: string;
|
|
115
|
+
popover?: string;
|
|
116
|
+
popoverForeground?: string;
|
|
117
|
+
ring?: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Typography settings — font families, heading sizes, weights, etc.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* typography: {
|
|
125
|
+
* font: {
|
|
126
|
+
* style: { sans: "Inter, sans-serif", mono: "JetBrains Mono, monospace" },
|
|
127
|
+
* h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" },
|
|
128
|
+
* body: { size: "1rem", lineHeight: "1.75" },
|
|
129
|
+
* },
|
|
130
|
+
* }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
typography?: TypographyConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Global border-radius. Maps to CSS `--radius`.
|
|
136
|
+
* Use "0px" for sharp corners, "0.5rem" for rounded, etc.
|
|
137
|
+
*/
|
|
138
|
+
radius?: string;
|
|
139
|
+
/** Layout dimensions */
|
|
140
|
+
layout?: {
|
|
141
|
+
contentWidth?: number;
|
|
142
|
+
sidebarWidth?: number;
|
|
143
|
+
tocWidth?: number;
|
|
144
|
+
toc?: {
|
|
145
|
+
enabled?: boolean;
|
|
146
|
+
depth?: number;
|
|
147
|
+
/**
|
|
148
|
+
* Visual style of the TOC indicator.
|
|
149
|
+
* - `"default"` — highlight active link text color only
|
|
150
|
+
* - `"directional"` — animated thumb bar that tracks active headings (fumadocs style)
|
|
151
|
+
* @default "default"
|
|
152
|
+
*/
|
|
153
|
+
style?: "default" | "directional";
|
|
154
|
+
};
|
|
155
|
+
header?: {
|
|
156
|
+
height?: number;
|
|
157
|
+
sticky?: boolean;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
/** Code block rendering config */
|
|
161
|
+
codeBlock?: {
|
|
162
|
+
/** Show line numbers in code blocks @default false */
|
|
163
|
+
showLineNumbers?: boolean;
|
|
164
|
+
/** Show copy button @default true */
|
|
165
|
+
showCopyButton?: boolean;
|
|
166
|
+
/** Shiki theme name for syntax highlighting */
|
|
167
|
+
theme?: string;
|
|
168
|
+
/** Dark mode shiki theme (for dual-theme setups) */
|
|
169
|
+
darkTheme?: string;
|
|
170
|
+
};
|
|
171
|
+
/** Sidebar styling hints (consumed by theme CSS) */
|
|
172
|
+
sidebar?: {
|
|
173
|
+
/**
|
|
174
|
+
* Visual style of the sidebar.
|
|
175
|
+
* - "default" — standard fumadocs sidebar
|
|
176
|
+
* - "bordered" — visible bordered sections (like better-auth)
|
|
177
|
+
* - "floating" — floating card sidebar
|
|
178
|
+
*/
|
|
179
|
+
style?: "default" | "bordered" | "floating";
|
|
180
|
+
/** Background color override */
|
|
181
|
+
background?: string;
|
|
182
|
+
/** Border color override */
|
|
183
|
+
borderColor?: string;
|
|
184
|
+
};
|
|
185
|
+
/** Card styling */
|
|
186
|
+
card?: {
|
|
187
|
+
/** Whether cards have visible borders @default true */
|
|
188
|
+
bordered?: boolean;
|
|
189
|
+
/** Card background color override */
|
|
190
|
+
background?: string;
|
|
191
|
+
};
|
|
192
|
+
/** Default props/variants for MDX components (Callout, CodeBlock, Tabs, etc.) */
|
|
193
|
+
components?: {
|
|
194
|
+
[key: string]: Record<string, unknown> | ((defaults: unknown) => unknown);
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* A docs theme configuration.
|
|
199
|
+
*
|
|
200
|
+
* Theme authors create these with `createTheme()`. The `name` identifies the
|
|
201
|
+
* theme (useful for CSS scoping, debugging, analytics). The `ui` object holds
|
|
202
|
+
* all visual configuration.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* import { createTheme } from "@farming-labs/docs";
|
|
207
|
+
*
|
|
208
|
+
* export const myTheme = createTheme({
|
|
209
|
+
* name: "my-theme",
|
|
210
|
+
* ui: {
|
|
211
|
+
* colors: { primary: "#ff4d8d" },
|
|
212
|
+
* radius: "0px",
|
|
213
|
+
* },
|
|
214
|
+
* });
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
export interface DocsTheme {
|
|
218
|
+
/** Unique name for this theme (used for CSS scoping and debugging) */
|
|
219
|
+
name?: string;
|
|
220
|
+
/** UI configuration — colors, typography, layout, components */
|
|
221
|
+
ui?: UIConfig;
|
|
222
|
+
/**
|
|
223
|
+
* @internal
|
|
224
|
+
* User-provided color overrides tracked by `createTheme`.
|
|
225
|
+
* Only these colors are emitted as inline CSS variables at runtime.
|
|
226
|
+
* Preset defaults stay in the theme's CSS file.
|
|
227
|
+
*/
|
|
228
|
+
_userColorOverrides?: Record<string, string>;
|
|
229
|
+
}
|
|
230
|
+
export interface DocsMetadata {
|
|
231
|
+
titleTemplate?: string;
|
|
232
|
+
description?: string;
|
|
233
|
+
twitterCard?: "summary" | "summary_large_image";
|
|
234
|
+
}
|
|
235
|
+
export interface OGConfig {
|
|
236
|
+
enabled?: boolean;
|
|
237
|
+
type?: "static" | "dynamic";
|
|
238
|
+
endpoint?: string;
|
|
239
|
+
defaultImage?: string;
|
|
240
|
+
}
|
|
241
|
+
/** Single image entry for Open Graph (frontmatter or Next metadata). */
|
|
242
|
+
export interface OpenGraphImage {
|
|
243
|
+
url: string;
|
|
244
|
+
width?: number;
|
|
245
|
+
height?: number;
|
|
246
|
+
}
|
|
247
|
+
/** Open Graph block in page frontmatter. When present, used as-is for metadata (replaces generated OG). */
|
|
248
|
+
export interface PageOpenGraph {
|
|
249
|
+
images?: OpenGraphImage[];
|
|
250
|
+
title?: string;
|
|
251
|
+
description?: string;
|
|
252
|
+
}
|
|
253
|
+
/** Twitter card block in page frontmatter. When present, used as-is for metadata (replaces generated twitter). */
|
|
254
|
+
export interface PageTwitter {
|
|
255
|
+
card?: "summary" | "summary_large_image";
|
|
256
|
+
images?: string[];
|
|
257
|
+
title?: string;
|
|
258
|
+
description?: string;
|
|
259
|
+
}
|
|
260
|
+
export interface PageFrontmatter {
|
|
261
|
+
title: string;
|
|
262
|
+
description?: string;
|
|
263
|
+
tags?: string[];
|
|
264
|
+
icon?: string;
|
|
265
|
+
/** Path to custom OG image for this page (shorthand). Ignored if `openGraph` is set. */
|
|
266
|
+
ogImage?: string;
|
|
267
|
+
/** Full Open Graph object. When set, replaces any generated OG from config (e.g. dynamic endpoint). */
|
|
268
|
+
openGraph?: PageOpenGraph;
|
|
269
|
+
/** Full Twitter card object. When set, replaces any generated twitter from config. */
|
|
270
|
+
twitter?: PageTwitter;
|
|
271
|
+
/** Sort order in the sidebar. Lower numbers appear first. Pages without `order` are sorted alphabetically after ordered pages. */
|
|
272
|
+
order?: number;
|
|
273
|
+
}
|
|
274
|
+
export interface DocsNav {
|
|
275
|
+
/**
|
|
276
|
+
* Sidebar title — a plain string or a React element (e.g. a div with an icon).
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```tsx
|
|
280
|
+
* // Simple string
|
|
281
|
+
* nav: { title: "My Docs" }
|
|
282
|
+
*
|
|
283
|
+
* // React element with icon
|
|
284
|
+
* nav: {
|
|
285
|
+
* title: <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
|
286
|
+
* <Rocket size={18} /> Example Docs
|
|
287
|
+
* </div>
|
|
288
|
+
* }
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
title?: unknown;
|
|
292
|
+
/** URL the title links to. Defaults to `/{entry}`. */
|
|
293
|
+
url?: string;
|
|
294
|
+
}
|
|
295
|
+
export interface ThemeToggleConfig {
|
|
296
|
+
/**
|
|
297
|
+
* Whether to show the light/dark theme toggle in the sidebar.
|
|
298
|
+
* @default true
|
|
299
|
+
*/
|
|
300
|
+
enabled?: boolean;
|
|
301
|
+
/**
|
|
302
|
+
* The default / forced theme when the toggle is hidden.
|
|
303
|
+
* Only applies when `enabled` is `false`.
|
|
304
|
+
* @default "system"
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* // Hide toggle, force dark mode
|
|
309
|
+
* themeToggle: { enabled: false, default: "dark" }
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
default?: "light" | "dark" | "system";
|
|
313
|
+
/**
|
|
314
|
+
* Toggle mode — show only light/dark, or include a system option.
|
|
315
|
+
* @default "light-dark"
|
|
316
|
+
*/
|
|
317
|
+
mode?: "light-dark" | "light-dark-system";
|
|
318
|
+
}
|
|
319
|
+
export interface BreadcrumbConfig {
|
|
320
|
+
/**
|
|
321
|
+
* Whether to show the breadcrumb navigation above page content.
|
|
322
|
+
* @default true
|
|
323
|
+
*/
|
|
324
|
+
enabled?: boolean;
|
|
325
|
+
/**
|
|
326
|
+
* Custom breadcrumb component. Receives the default breadcrumb as children
|
|
327
|
+
* so you can wrap/modify it.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```tsx
|
|
331
|
+
* breadcrumb: {
|
|
332
|
+
* component: ({ items }) => <MyBreadcrumb items={items} />,
|
|
333
|
+
* }
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
component?: unknown;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* A leaf page in the sidebar tree.
|
|
340
|
+
*/
|
|
341
|
+
export interface SidebarPageNode {
|
|
342
|
+
type: "page";
|
|
343
|
+
name: string;
|
|
344
|
+
url: string;
|
|
345
|
+
icon?: unknown;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* A folder (group) in the sidebar tree. May contain child pages
|
|
349
|
+
* and nested folders, forming a recursive hierarchy.
|
|
350
|
+
*/
|
|
351
|
+
export interface SidebarFolderNode {
|
|
352
|
+
type: "folder";
|
|
353
|
+
name: string;
|
|
354
|
+
icon?: unknown;
|
|
355
|
+
/** Index page for this folder (the folder's own landing page). */
|
|
356
|
+
index?: SidebarPageNode;
|
|
357
|
+
/** Child pages and sub-folders. */
|
|
358
|
+
children: SidebarNode[];
|
|
359
|
+
/** Whether this folder section is collapsible. */
|
|
360
|
+
collapsible?: boolean;
|
|
361
|
+
/** Whether this folder starts open. */
|
|
362
|
+
defaultOpen?: boolean;
|
|
363
|
+
}
|
|
364
|
+
/** A node in the sidebar tree — either a page or a folder. */
|
|
365
|
+
export type SidebarNode = SidebarPageNode | SidebarFolderNode;
|
|
366
|
+
/** The full sidebar tree passed to custom sidebar components. */
|
|
367
|
+
export interface SidebarTree {
|
|
368
|
+
name: string;
|
|
369
|
+
children: SidebarNode[];
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Props passed to a custom sidebar component.
|
|
373
|
+
*
|
|
374
|
+
* Contains all the information needed to build a fully custom sidebar:
|
|
375
|
+
* the complete page tree with parent-child relationships, and the
|
|
376
|
+
* current sidebar configuration.
|
|
377
|
+
*/
|
|
378
|
+
export interface SidebarComponentProps {
|
|
379
|
+
/** Full page tree with all parent-child-folder relationships. */
|
|
380
|
+
tree: SidebarTree;
|
|
381
|
+
/** Whether folders are collapsible. */
|
|
382
|
+
collapsible: boolean;
|
|
383
|
+
/** Whether folders are rendered flat (Mintlify-style). */
|
|
384
|
+
flat: boolean;
|
|
385
|
+
}
|
|
386
|
+
export interface SidebarConfig {
|
|
387
|
+
/**
|
|
388
|
+
* Whether to show the sidebar.
|
|
389
|
+
* @default true
|
|
390
|
+
*/
|
|
391
|
+
enabled?: boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Custom sidebar component to replace the default navigation.
|
|
394
|
+
*
|
|
395
|
+
* **Next.js** — Pass a render function that receives `SidebarComponentProps`:
|
|
396
|
+
* ```tsx
|
|
397
|
+
* sidebar: {
|
|
398
|
+
* component: ({ tree, collapsible, flat }) => (
|
|
399
|
+
* <MySidebar tree={tree} />
|
|
400
|
+
* ),
|
|
401
|
+
* }
|
|
402
|
+
* ```
|
|
403
|
+
*
|
|
404
|
+
* **Astro** — Use the `sidebar` named slot on `<DocsLayout>`:
|
|
405
|
+
* ```astro
|
|
406
|
+
* <DocsLayout tree={tree} config={config}>
|
|
407
|
+
* <MySidebar slot="sidebar" tree={tree} />
|
|
408
|
+
* <slot />
|
|
409
|
+
* </DocsLayout>
|
|
410
|
+
* ```
|
|
411
|
+
*
|
|
412
|
+
* **SvelteKit** — Use the `sidebar` snippet on `<DocsLayout>`:
|
|
413
|
+
* ```svelte
|
|
414
|
+
* <DocsLayout {tree} {config}>
|
|
415
|
+
* {#snippet sidebar({ tree, isActive })}
|
|
416
|
+
* <MySidebarNav {tree} {isActive} />
|
|
417
|
+
* {/snippet}
|
|
418
|
+
* {@render children()}
|
|
419
|
+
* </DocsLayout>
|
|
420
|
+
* ```
|
|
421
|
+
*
|
|
422
|
+
* **Nuxt / Vue** — Use the `#sidebar` scoped slot on `<DocsLayout>`:
|
|
423
|
+
* ```vue
|
|
424
|
+
* <DocsLayout :tree="tree" :config="config">
|
|
425
|
+
* <template #sidebar="{ tree, isActive }">
|
|
426
|
+
* <MySidebarNav :tree="tree" :is-active="isActive" />
|
|
427
|
+
* </template>
|
|
428
|
+
* <DocsContent />
|
|
429
|
+
* </DocsLayout>
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
component?: (props: SidebarComponentProps) => unknown;
|
|
433
|
+
/**
|
|
434
|
+
* Sidebar footer content (rendered below navigation items).
|
|
435
|
+
*/
|
|
436
|
+
footer?: unknown;
|
|
437
|
+
/**
|
|
438
|
+
* Sidebar banner content (rendered above navigation items).
|
|
439
|
+
*/
|
|
440
|
+
banner?: unknown;
|
|
441
|
+
/**
|
|
442
|
+
* Whether the sidebar is collapsible on desktop.
|
|
443
|
+
* @default true
|
|
444
|
+
*/
|
|
445
|
+
collapsible?: boolean;
|
|
446
|
+
/**
|
|
447
|
+
* When true, all folder children are rendered flat in the sidebar
|
|
448
|
+
* (no collapsible sections). Folder index pages appear as category
|
|
449
|
+
* headings with all children listed directly below them.
|
|
450
|
+
*
|
|
451
|
+
* This creates a Mintlify-style sidebar where all navigation items
|
|
452
|
+
* are always visible.
|
|
453
|
+
*
|
|
454
|
+
* @default false
|
|
455
|
+
*/
|
|
456
|
+
flat?: boolean;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* A single "Open in …" provider shown in the Open dropdown.
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```ts
|
|
463
|
+
* { name: "Claude", icon: <ClaudeIcon />, urlTemplate: "https://claude.ai?url={url}" }
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
export interface OpenDocsProvider {
|
|
467
|
+
/** Display name (e.g. "ChatGPT", "Claude", "Cursor") */
|
|
468
|
+
name: string;
|
|
469
|
+
/** Icon element rendered next to the name */
|
|
470
|
+
icon?: unknown;
|
|
471
|
+
/**
|
|
472
|
+
* URL template. Placeholders:
|
|
473
|
+
* - `{url}` — current page URL (encoded).
|
|
474
|
+
* - `{mdxUrl}` — page URL with `.mdx` suffix (encoded).
|
|
475
|
+
* - `{githubUrl}` — GitHub edit URL for the current page (same as "Edit on GitHub"). Requires `github` in config.
|
|
476
|
+
*
|
|
477
|
+
* @example "https://claude.ai/new?q=Read+this+doc:+{url}"
|
|
478
|
+
* @example "{githubUrl}" — open current page file on GitHub (edit view)
|
|
479
|
+
*/
|
|
480
|
+
urlTemplate: string;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Configuration for the "Open in …" dropdown that lets users
|
|
484
|
+
* send the current page to an LLM or external tool.
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```ts
|
|
488
|
+
* openDocs: {
|
|
489
|
+
* enabled: true,
|
|
490
|
+
* providers: [
|
|
491
|
+
* { name: "ChatGPT", icon: <ChatGPTIcon />, urlTemplate: "https://chatgpt.com/?q={url}" },
|
|
492
|
+
* { name: "Claude", icon: <ClaudeIcon />, urlTemplate: "https://claude.ai/new?q={url}" },
|
|
493
|
+
* ],
|
|
494
|
+
* }
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
export interface OpenDocsConfig {
|
|
498
|
+
/** Whether to show the "Open" dropdown. @default false */
|
|
499
|
+
enabled?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* List of LLM / tool providers to show in the dropdown.
|
|
502
|
+
* If not provided, a sensible default list is used.
|
|
503
|
+
*/
|
|
504
|
+
providers?: OpenDocsProvider[];
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Configuration for the "Copy Markdown" button that copies
|
|
508
|
+
* the current page's content as Markdown to the clipboard.
|
|
509
|
+
*/
|
|
510
|
+
export interface CopyMarkdownConfig {
|
|
511
|
+
/** Whether to show the "Copy Markdown" button. @default false */
|
|
512
|
+
enabled?: boolean;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Page-level action buttons shown above the page content
|
|
516
|
+
* (e.g. "Copy Markdown", "Open in …" dropdown).
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* pageActions: {
|
|
521
|
+
* copyMarkdown: { enabled: true },
|
|
522
|
+
* openDocs: {
|
|
523
|
+
* enabled: true,
|
|
524
|
+
* providers: [
|
|
525
|
+
* { name: "Claude", urlTemplate: "https://claude.ai/new?q={url}" },
|
|
526
|
+
* ],
|
|
527
|
+
* },
|
|
528
|
+
* }
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
export interface PageActionsConfig {
|
|
532
|
+
/** "Copy Markdown" button */
|
|
533
|
+
copyMarkdown?: boolean | CopyMarkdownConfig;
|
|
534
|
+
/** "Open in …" dropdown with LLM / tool providers */
|
|
535
|
+
openDocs?: boolean | OpenDocsConfig;
|
|
536
|
+
/**
|
|
537
|
+
* Where to render the page action buttons relative to the page title.
|
|
538
|
+
*
|
|
539
|
+
* - `"below-title"` — render below the first `<h1>` heading (default)
|
|
540
|
+
* - `"above-title"` — render above the page title / content
|
|
541
|
+
*
|
|
542
|
+
* @default "below-title"
|
|
543
|
+
*/
|
|
544
|
+
position?: "above-title" | "below-title";
|
|
545
|
+
/**
|
|
546
|
+
* Horizontal alignment of page action buttons.
|
|
547
|
+
*
|
|
548
|
+
* - `"left"` — align to the left (default)
|
|
549
|
+
* - `"right"` — align to the right
|
|
550
|
+
*
|
|
551
|
+
* @default "left"
|
|
552
|
+
*/
|
|
553
|
+
alignment?: "left" | "right";
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Configuration for the "Last updated" date display.
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* lastUpdated: { position: "below-title" }
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
/**
|
|
564
|
+
* Configuration for auto-generated `/llms.txt` and `/llms-full.txt` routes.
|
|
565
|
+
*
|
|
566
|
+
* @see https://llmstxt.org
|
|
567
|
+
*/
|
|
568
|
+
export interface LlmsTxtConfig {
|
|
569
|
+
/**
|
|
570
|
+
* Whether to enable llms.txt generation.
|
|
571
|
+
* @default true
|
|
572
|
+
*/
|
|
573
|
+
enabled?: boolean;
|
|
574
|
+
/**
|
|
575
|
+
* Base URL for your docs site (used to build absolute links in llms.txt).
|
|
576
|
+
* @example "https://docs.example.com"
|
|
577
|
+
*/
|
|
578
|
+
baseUrl?: string;
|
|
579
|
+
/**
|
|
580
|
+
* Site title shown at the top of llms.txt.
|
|
581
|
+
* Falls back to `nav.title` if not set.
|
|
582
|
+
*/
|
|
583
|
+
siteTitle?: string;
|
|
584
|
+
/**
|
|
585
|
+
* Site description shown below the title.
|
|
586
|
+
*/
|
|
587
|
+
siteDescription?: string;
|
|
588
|
+
}
|
|
589
|
+
export interface LastUpdatedConfig {
|
|
590
|
+
/**
|
|
591
|
+
* Whether to show the "Last updated" date.
|
|
592
|
+
* @default true
|
|
593
|
+
*/
|
|
594
|
+
enabled?: boolean;
|
|
595
|
+
/**
|
|
596
|
+
* Where to render the "Last updated" date.
|
|
597
|
+
*
|
|
598
|
+
* - `"footer"` — next to the "Edit on GitHub" link at the bottom (default)
|
|
599
|
+
* - `"below-title"` — below the page title/description, above the content
|
|
600
|
+
*
|
|
601
|
+
* @default "footer"
|
|
602
|
+
*/
|
|
603
|
+
position?: "footer" | "below-title";
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* GitHub repository configuration for "Edit on GitHub" links
|
|
607
|
+
* and source file references.
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```ts
|
|
611
|
+
* // Simple repo (not a monorepo)
|
|
612
|
+
* github: {
|
|
613
|
+
* url: "https://github.com/Kinfe123/my-docs",
|
|
614
|
+
* }
|
|
615
|
+
*
|
|
616
|
+
* // Monorepo — docs site lives in "website/" subdirectory
|
|
617
|
+
* github: {
|
|
618
|
+
* url: "https://github.com/farming-labs/docs",
|
|
619
|
+
* directory: "website",
|
|
620
|
+
* branch: "main",
|
|
621
|
+
* }
|
|
622
|
+
* ```
|
|
623
|
+
*
|
|
624
|
+
* Or as a simple string (branch defaults to "main", no directory prefix):
|
|
625
|
+
* ```ts
|
|
626
|
+
* github: "https://github.com/Kinfe123/my-docs"
|
|
627
|
+
* ```
|
|
628
|
+
*/
|
|
629
|
+
export interface GithubConfig {
|
|
630
|
+
/** Repository URL (e.g. "https://github.com/farming-labs/docs") */
|
|
631
|
+
url: string;
|
|
632
|
+
/** Branch name. @default "main" */
|
|
633
|
+
branch?: string;
|
|
634
|
+
/**
|
|
635
|
+
* Subdirectory inside the repo where the docs site lives.
|
|
636
|
+
* Use this for monorepos where the docs app is not at the repo root.
|
|
637
|
+
*
|
|
638
|
+
* @example "website" → links point to `website/app/docs/…/page.mdx`
|
|
639
|
+
*/
|
|
640
|
+
directory?: string;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Configuration for "Ask AI" — a RAG-powered chat that lets users
|
|
644
|
+
* ask questions about the documentation content.
|
|
645
|
+
*
|
|
646
|
+
* The AI handler searches relevant doc pages, builds context, and
|
|
647
|
+
* streams a response from an LLM (OpenAI-compatible API).
|
|
648
|
+
*
|
|
649
|
+
* The API key is **never** stored in the config. It is read from the
|
|
650
|
+
* `OPENAI_API_KEY` environment variable at runtime on the server.
|
|
651
|
+
*
|
|
652
|
+
* @example
|
|
653
|
+
* ```ts
|
|
654
|
+
* ai: {
|
|
655
|
+
* enabled: true,
|
|
656
|
+
* model: "gpt-4o-mini",
|
|
657
|
+
* systemPrompt: "You are a helpful assistant for our developer docs.",
|
|
658
|
+
* }
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
export interface AIConfig {
|
|
662
|
+
/**
|
|
663
|
+
* Whether to enable "Ask AI" functionality.
|
|
664
|
+
* When enabled, the unified `/api/docs` route handler will accept
|
|
665
|
+
* POST requests for AI chat.
|
|
666
|
+
* @default false
|
|
667
|
+
*/
|
|
668
|
+
enabled?: boolean;
|
|
669
|
+
/**
|
|
670
|
+
* How the AI chat UI is presented.
|
|
671
|
+
*
|
|
672
|
+
* - `"search"` — AI tab integrated into the Cmd+K search dialog (default)
|
|
673
|
+
* - `"floating"` — A floating chat widget (bubble button + slide-out panel)
|
|
674
|
+
*
|
|
675
|
+
* @default "search"
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* ```ts
|
|
679
|
+
* // Floating chat bubble in the bottom-right corner
|
|
680
|
+
* ai: {
|
|
681
|
+
* enabled: true,
|
|
682
|
+
* mode: "floating",
|
|
683
|
+
* position: "bottom-right",
|
|
684
|
+
* }
|
|
685
|
+
* ```
|
|
686
|
+
*/
|
|
687
|
+
mode?: "search" | "floating" | "sidebar-icon";
|
|
688
|
+
/**
|
|
689
|
+
* Position of the floating chat button on screen.
|
|
690
|
+
* Only used when `mode` is `"floating"`.
|
|
691
|
+
*
|
|
692
|
+
* - `"bottom-right"` — bottom-right corner (default)
|
|
693
|
+
* - `"bottom-left"` — bottom-left corner
|
|
694
|
+
* - `"bottom-center"` — bottom center
|
|
695
|
+
*
|
|
696
|
+
* @default "bottom-right"
|
|
697
|
+
*/
|
|
698
|
+
position?: "bottom-right" | "bottom-left" | "bottom-center";
|
|
699
|
+
/**
|
|
700
|
+
* Visual style of the floating chat when opened.
|
|
701
|
+
* Only used when `mode` is `"floating"`.
|
|
702
|
+
*
|
|
703
|
+
* - `"panel"` — A tall panel that slides up from the button position (default).
|
|
704
|
+
* Stays anchored near the floating button. No backdrop overlay.
|
|
705
|
+
*
|
|
706
|
+
* - `"modal"` — A centered modal dialog with a backdrop overlay,
|
|
707
|
+
* similar to the Cmd+K search dialog. Feels more focused and immersive.
|
|
708
|
+
*
|
|
709
|
+
* - `"popover"` — A compact popover near the button. Smaller than the
|
|
710
|
+
* panel, suitable for quick questions without taking much screen space.
|
|
711
|
+
*
|
|
712
|
+
* - `"full-modal"` — A full-screen immersive overlay (inspired by better-auth).
|
|
713
|
+
* Messages scroll in the center, input is pinned at the bottom.
|
|
714
|
+
* Suggested questions appear as horizontal pills. Best for
|
|
715
|
+
* documentation-heavy sites that want a premium AI experience.
|
|
716
|
+
*
|
|
717
|
+
* @default "panel"
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* ai: {
|
|
722
|
+
* enabled: true,
|
|
723
|
+
* mode: "floating",
|
|
724
|
+
* position: "bottom-right",
|
|
725
|
+
* floatingStyle: "full-modal",
|
|
726
|
+
* }
|
|
727
|
+
* ```
|
|
728
|
+
*/
|
|
729
|
+
floatingStyle?: "panel" | "modal" | "popover" | "full-modal";
|
|
730
|
+
/**
|
|
731
|
+
* Custom trigger component for the floating chat button (Next.js only).
|
|
732
|
+
* Only used when `mode` is `"floating"`.
|
|
733
|
+
*
|
|
734
|
+
* The click handler is attached automatically by the wrapper.
|
|
735
|
+
*
|
|
736
|
+
* - **Next.js**: Pass a JSX element via this config option.
|
|
737
|
+
* - **SvelteKit**: Use the `aiTrigger` snippet on `<DocsLayout>`.
|
|
738
|
+
* - **Nuxt / Vue**: Use the `ai-trigger` slot on `<DocsLayout>`.
|
|
739
|
+
* - **Astro**: Use `<MyTrigger slot="ai-trigger" />` on `<DocsLayout>`.
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```tsx
|
|
743
|
+
* // Next.js — pass JSX directly in config
|
|
744
|
+
* triggerComponent: <button className="my-chat-btn">Ask AI</button>,
|
|
745
|
+
* ```
|
|
746
|
+
*
|
|
747
|
+
* ```svelte
|
|
748
|
+
* <!-- SvelteKit — use snippet in layout -->
|
|
749
|
+
* <DocsLayout {tree} {config}>
|
|
750
|
+
* {#snippet aiTrigger()}<AskAITrigger />{/snippet}
|
|
751
|
+
* {@render children()}
|
|
752
|
+
* </DocsLayout>
|
|
753
|
+
* ```
|
|
754
|
+
*
|
|
755
|
+
* ```vue
|
|
756
|
+
* <!-- Nuxt / Vue — use named slot in layout -->
|
|
757
|
+
* <DocsLayout :tree="tree" :config="config">
|
|
758
|
+
* <template #ai-trigger><AskAITrigger /></template>
|
|
759
|
+
* <DocsContent />
|
|
760
|
+
* </DocsLayout>
|
|
761
|
+
* ```
|
|
762
|
+
*
|
|
763
|
+
* ```astro
|
|
764
|
+
* <!-- Astro — use named slot in layout -->
|
|
765
|
+
* <DocsLayout tree={tree} config={config}>
|
|
766
|
+
* <AskAITrigger slot="ai-trigger" />
|
|
767
|
+
* <DocsContent />
|
|
768
|
+
* </DocsLayout>
|
|
769
|
+
* ```
|
|
770
|
+
*/
|
|
771
|
+
triggerComponent?: unknown;
|
|
772
|
+
/**
|
|
773
|
+
* The LLM model configuration.
|
|
774
|
+
*
|
|
775
|
+
* **Simple** — pass a plain string for a single model:
|
|
776
|
+
* ```ts
|
|
777
|
+
* model: "gpt-4o-mini"
|
|
778
|
+
* ```
|
|
779
|
+
*
|
|
780
|
+
* **Advanced** — pass an object with multiple selectable models and an
|
|
781
|
+
* optional `provider` key that references a named provider in `providers`:
|
|
782
|
+
* ```ts
|
|
783
|
+
* model: {
|
|
784
|
+
* models: [
|
|
785
|
+
* { id: "gpt-4o-mini", label: "GPT-4o mini (fast)", provider: "openai" },
|
|
786
|
+
* { id: "llama-3.3-70b-versatile", label: "Llama 3.3 70B", provider: "groq" },
|
|
787
|
+
* ],
|
|
788
|
+
* defaultModel: "gpt-4o-mini",
|
|
789
|
+
* }
|
|
790
|
+
* ```
|
|
791
|
+
*
|
|
792
|
+
* When an object is provided, a model selector dropdown appears in the
|
|
793
|
+
* AI chat interface.
|
|
794
|
+
*
|
|
795
|
+
* @default "gpt-4o-mini"
|
|
796
|
+
*/
|
|
797
|
+
model?: string | {
|
|
798
|
+
models: {
|
|
799
|
+
id: string;
|
|
800
|
+
label: string;
|
|
801
|
+
provider?: string;
|
|
802
|
+
}[];
|
|
803
|
+
defaultModel?: string;
|
|
804
|
+
};
|
|
805
|
+
/**
|
|
806
|
+
* Named provider configurations for multi-provider setups.
|
|
807
|
+
*
|
|
808
|
+
* Each key is a provider name referenced by `model.models[].provider`.
|
|
809
|
+
* Each value contains a `baseUrl` and optional `apiKey`.
|
|
810
|
+
*
|
|
811
|
+
* @example
|
|
812
|
+
* ```ts
|
|
813
|
+
* providers: {
|
|
814
|
+
* openai: {
|
|
815
|
+
* baseUrl: "https://api.openai.com/v1",
|
|
816
|
+
* apiKey: process.env.OPENAI_API_KEY,
|
|
817
|
+
* },
|
|
818
|
+
* groq: {
|
|
819
|
+
* baseUrl: "https://api.groq.com/openai/v1",
|
|
820
|
+
* apiKey: process.env.GROQ_API_KEY,
|
|
821
|
+
* },
|
|
822
|
+
* }
|
|
823
|
+
* ```
|
|
824
|
+
*/
|
|
825
|
+
providers?: Record<string, {
|
|
826
|
+
baseUrl: string;
|
|
827
|
+
apiKey?: string;
|
|
828
|
+
}>;
|
|
829
|
+
/**
|
|
830
|
+
* Custom system prompt prepended to the AI conversation.
|
|
831
|
+
* The documentation context is automatically appended after this prompt.
|
|
832
|
+
*
|
|
833
|
+
* @default "You are a helpful documentation assistant. Answer questions
|
|
834
|
+
* based on the provided documentation context. Be concise and accurate.
|
|
835
|
+
* If the answer is not in the context, say so honestly."
|
|
836
|
+
*/
|
|
837
|
+
systemPrompt?: string;
|
|
838
|
+
/**
|
|
839
|
+
* Default base URL for an OpenAI-compatible API endpoint.
|
|
840
|
+
* Used when no per-model `provider` is configured.
|
|
841
|
+
* @default "https://api.openai.com/v1"
|
|
842
|
+
*/
|
|
843
|
+
baseUrl?: string;
|
|
844
|
+
/**
|
|
845
|
+
* Default API key for the LLM provider.
|
|
846
|
+
* Used when no per-model `provider` is configured.
|
|
847
|
+
* Falls back to `process.env.OPENAI_API_KEY` if not set.
|
|
848
|
+
*
|
|
849
|
+
* @default process.env.OPENAI_API_KEY
|
|
850
|
+
*
|
|
851
|
+
* @example
|
|
852
|
+
* ```ts
|
|
853
|
+
* // Default — reads OPENAI_API_KEY automatically
|
|
854
|
+
* ai: { enabled: true }
|
|
855
|
+
*
|
|
856
|
+
* // Custom provider key
|
|
857
|
+
* ai: {
|
|
858
|
+
* enabled: true,
|
|
859
|
+
* apiKey: process.env.GROQ_API_KEY,
|
|
860
|
+
* }
|
|
861
|
+
* ```
|
|
862
|
+
*/
|
|
863
|
+
apiKey?: string;
|
|
864
|
+
/**
|
|
865
|
+
* Maximum number of search results to include as context for the AI.
|
|
866
|
+
* More results = more context but higher token usage.
|
|
867
|
+
* @default 5
|
|
868
|
+
*/
|
|
869
|
+
maxResults?: number;
|
|
870
|
+
/**
|
|
871
|
+
* Pre-filled suggested questions shown in the AI chat when empty.
|
|
872
|
+
* When a user clicks one, it fills the input and submits automatically.
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```ts
|
|
876
|
+
* ai: {
|
|
877
|
+
* enabled: true,
|
|
878
|
+
* suggestedQuestions: [
|
|
879
|
+
* "How do I install this?",
|
|
880
|
+
* "What themes are available?",
|
|
881
|
+
* "How do I create a custom component?",
|
|
882
|
+
* ],
|
|
883
|
+
* }
|
|
884
|
+
* ```
|
|
885
|
+
*/
|
|
886
|
+
suggestedQuestions?: string[];
|
|
887
|
+
/**
|
|
888
|
+
* Display name for the AI assistant in the chat UI.
|
|
889
|
+
* Shown as the message label, header title, and passed to the loading component.
|
|
890
|
+
*
|
|
891
|
+
* @default "AI"
|
|
892
|
+
*
|
|
893
|
+
* @example
|
|
894
|
+
* ```ts
|
|
895
|
+
* ai: {
|
|
896
|
+
* enabled: true,
|
|
897
|
+
* aiLabel: "DocsBot",
|
|
898
|
+
* }
|
|
899
|
+
* ```
|
|
900
|
+
*/
|
|
901
|
+
aiLabel?: string;
|
|
902
|
+
/**
|
|
903
|
+
* The npm package name used in import examples.
|
|
904
|
+
* The AI will use this in code snippets instead of generic placeholders.
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* ```ts
|
|
908
|
+
* ai: {
|
|
909
|
+
* enabled: true,
|
|
910
|
+
* packageName: "@farming-labs/docs",
|
|
911
|
+
* }
|
|
912
|
+
* ```
|
|
913
|
+
*/
|
|
914
|
+
packageName?: string;
|
|
915
|
+
/**
|
|
916
|
+
* The public URL of the documentation site.
|
|
917
|
+
* The AI will use this for links instead of relative paths.
|
|
918
|
+
*
|
|
919
|
+
* @example
|
|
920
|
+
* ```ts
|
|
921
|
+
* ai: {
|
|
922
|
+
* enabled: true,
|
|
923
|
+
* docsUrl: "https://docs.farming-labs.dev",
|
|
924
|
+
* }
|
|
925
|
+
* ```
|
|
926
|
+
*/
|
|
927
|
+
docsUrl?: string;
|
|
928
|
+
/**
|
|
929
|
+
* Loading indicator variant shown while the AI generates a response.
|
|
930
|
+
*
|
|
931
|
+
* - `"shimmer-dots"` — shimmer text + typing dots (default)
|
|
932
|
+
* - `"circular"` — spinning ring
|
|
933
|
+
* - `"dots"` — bouncing dots
|
|
934
|
+
* - `"typing"` — typing dots
|
|
935
|
+
* - `"wave"` — wave bars
|
|
936
|
+
* - `"bars"` — thick wave bars
|
|
937
|
+
* - `"pulse"` — pulsing ring
|
|
938
|
+
* - `"pulse-dot"` — pulsing dot
|
|
939
|
+
* - `"terminal"` — blinking terminal cursor
|
|
940
|
+
* - `"text-blink"` — blinking text
|
|
941
|
+
* - `"text-shimmer"` — shimmer text only
|
|
942
|
+
* - `"loading-dots"` — "Thinking..." with animated dots
|
|
943
|
+
*
|
|
944
|
+
* @default "shimmer-dots"
|
|
945
|
+
*
|
|
946
|
+
* @example
|
|
947
|
+
* ```ts
|
|
948
|
+
* ai: {
|
|
949
|
+
* enabled: true,
|
|
950
|
+
* loader: "wave",
|
|
951
|
+
* }
|
|
952
|
+
* ```
|
|
953
|
+
*/
|
|
954
|
+
loader?: "shimmer-dots" | "circular" | "dots" | "typing" | "wave" | "bars" | "pulse" | "pulse-dot" | "terminal" | "text-blink" | "text-shimmer" | "loading-dots";
|
|
955
|
+
/**
|
|
956
|
+
* Custom loading indicator that overrides the built-in `loader` variant.
|
|
957
|
+
* Receives `{ name }` (the `aiLabel` value) and returns a React element.
|
|
958
|
+
*
|
|
959
|
+
* Only works in Next.js. For other frameworks, use the `loader` option.
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```tsx
|
|
963
|
+
* ai: {
|
|
964
|
+
* enabled: true,
|
|
965
|
+
* aiLabel: "Sage",
|
|
966
|
+
* loadingComponent: ({ name }) => (
|
|
967
|
+
* <div className="flex items-center gap-2 text-sm text-zinc-400">
|
|
968
|
+
* <span className="animate-pulse">🤔</span>
|
|
969
|
+
* <span>{name} is thinking...</span>
|
|
970
|
+
* </div>
|
|
971
|
+
* ),
|
|
972
|
+
* }
|
|
973
|
+
* ```
|
|
974
|
+
*/
|
|
975
|
+
loadingComponent?: (props: {
|
|
976
|
+
name: string;
|
|
977
|
+
}) => unknown;
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* A single item in the slug-based sidebar ordering.
|
|
981
|
+
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```ts
|
|
984
|
+
* ordering: [
|
|
985
|
+
* { slug: "installation" },
|
|
986
|
+
* { slug: "cli" },
|
|
987
|
+
* { slug: "themes", children: [
|
|
988
|
+
* { slug: "default" },
|
|
989
|
+
* { slug: "darksharp" },
|
|
990
|
+
* { slug: "pixel-border" },
|
|
991
|
+
* { slug: "creating-themes" },
|
|
992
|
+
* ]},
|
|
993
|
+
* { slug: "reference" },
|
|
994
|
+
* ]
|
|
995
|
+
* ```
|
|
996
|
+
*/
|
|
997
|
+
export interface OrderingItem {
|
|
998
|
+
/** Folder name (not the full path, just the directory name at this level) */
|
|
999
|
+
slug: string;
|
|
1000
|
+
/** Ordering for child pages within this folder */
|
|
1001
|
+
children?: OrderingItem[];
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Data passed to the `onCopyClick` callback when the user clicks the copy button
|
|
1005
|
+
* on a code block in the docs.
|
|
1006
|
+
*/
|
|
1007
|
+
export interface CodeBlockCopyData {
|
|
1008
|
+
/** Title of the code block (e.g. from the fenced code block meta string), if present */
|
|
1009
|
+
title?: string;
|
|
1010
|
+
/** Raw code content (the text that was copied to the clipboard) */
|
|
1011
|
+
content: string;
|
|
1012
|
+
/** Current page URL at the time of copy */
|
|
1013
|
+
url: string;
|
|
1014
|
+
/** Language / syntax hint (e.g. "tsx", "bash"), if present */
|
|
1015
|
+
language?: string;
|
|
1016
|
+
}
|
|
1017
|
+
export interface DocsI18nConfig {
|
|
1018
|
+
/** Supported locale identifiers (e.g. ["en", "fr"]). */
|
|
1019
|
+
locales: string[];
|
|
1020
|
+
/** Default locale when `?lang=` is missing or invalid. Defaults to first locale. */
|
|
1021
|
+
defaultLocale?: string;
|
|
1022
|
+
}
|
|
1023
|
+
export interface ApiReferenceConfig {
|
|
1024
|
+
/**
|
|
1025
|
+
* Whether to enable generated API reference pages.
|
|
1026
|
+
* The initial implementation is wired for Next.js route handlers.
|
|
1027
|
+
* @default false
|
|
1028
|
+
*/
|
|
1029
|
+
enabled?: boolean;
|
|
1030
|
+
/**
|
|
1031
|
+
* URL path where the generated API reference lives.
|
|
1032
|
+
* Example: `"api-reference"` → `/api-reference`
|
|
1033
|
+
* @default "api-reference"
|
|
1034
|
+
*/
|
|
1035
|
+
path?: string;
|
|
1036
|
+
/**
|
|
1037
|
+
* Filesystem route root to scan for API handlers.
|
|
1038
|
+
*
|
|
1039
|
+
* For Next.js this defaults to the App Router convention:
|
|
1040
|
+
* `app/api` or `src/app/api`.
|
|
1041
|
+
*
|
|
1042
|
+
* You can override it with a project-relative path like `"app/v1"` or
|
|
1043
|
+
* `"src/app/internal-api"`. If you pass a bare segment like `"api"` or
|
|
1044
|
+
* `"v1"`, it will be resolved inside the detected app directory.
|
|
1045
|
+
*/
|
|
1046
|
+
routeRoot?: string;
|
|
1047
|
+
/**
|
|
1048
|
+
* Route entries to exclude from the generated API reference.
|
|
1049
|
+
*
|
|
1050
|
+
* Accepts either URL-style paths like `"/api/hello"` or route-root-relative
|
|
1051
|
+
* entries like `"hello"` / `"hello/route.ts"`.
|
|
1052
|
+
*/
|
|
1053
|
+
exclude?: string[];
|
|
1054
|
+
}
|
|
1055
|
+
export interface DocsConfig {
|
|
1056
|
+
/** Entry folder for docs (e.g. "docs" → /docs) */
|
|
1057
|
+
entry: string;
|
|
1058
|
+
/** Path to the content directory. Defaults to `entry` value. */
|
|
1059
|
+
contentDir?: string;
|
|
1060
|
+
/**
|
|
1061
|
+
* Internationalization (i18n) configuration.
|
|
1062
|
+
* When set, docs content is expected under `${contentDir}/{locale}` and
|
|
1063
|
+
* the active locale is selected by `?lang=<locale>` in the URL.
|
|
1064
|
+
*/
|
|
1065
|
+
i18n?: DocsI18nConfig;
|
|
1066
|
+
/**
|
|
1067
|
+
* Set to `true` when building for full static export (e.g. Cloudflare Pages).
|
|
1068
|
+
* When using `output: 'export'` in Next.js, the `/api/docs` route is not generated.
|
|
1069
|
+
* Set `ai.enabled: false` and optionally rely on client-side search or leave search disabled.
|
|
1070
|
+
*/
|
|
1071
|
+
staticExport?: boolean;
|
|
1072
|
+
/** Theme configuration - single source of truth for UI */
|
|
1073
|
+
theme?: DocsTheme;
|
|
1074
|
+
/**
|
|
1075
|
+
* GitHub repository URL or config. Enables "Edit on GitHub" links
|
|
1076
|
+
* on each docs page footer, pointing to the source `.mdx` file.
|
|
1077
|
+
*
|
|
1078
|
+
* @example
|
|
1079
|
+
* ```ts
|
|
1080
|
+
* // Simple — branch defaults to "main"
|
|
1081
|
+
* github: "https://github.com/Kinfe123/my-docs"
|
|
1082
|
+
*
|
|
1083
|
+
* // Monorepo — docs site lives in "website/" subdirectory
|
|
1084
|
+
* github: {
|
|
1085
|
+
* url: "https://github.com/farming-labs/docs",
|
|
1086
|
+
* directory: "website",
|
|
1087
|
+
* }
|
|
1088
|
+
*
|
|
1089
|
+
* // Custom branch
|
|
1090
|
+
* github: {
|
|
1091
|
+
* url: "https://github.com/Kinfe123/my-docs",
|
|
1092
|
+
* branch: "develop",
|
|
1093
|
+
* }
|
|
1094
|
+
* ```
|
|
1095
|
+
*/
|
|
1096
|
+
github?: string | GithubConfig;
|
|
1097
|
+
/**
|
|
1098
|
+
* Sidebar navigation header.
|
|
1099
|
+
* Customise the title shown at the top of the sidebar.
|
|
1100
|
+
*/
|
|
1101
|
+
nav?: DocsNav;
|
|
1102
|
+
/**
|
|
1103
|
+
* Theme toggle (light/dark mode switcher) in the sidebar.
|
|
1104
|
+
*
|
|
1105
|
+
* - `true` or `undefined` → toggle is shown (default)
|
|
1106
|
+
* - `false` → toggle is hidden, defaults to system theme
|
|
1107
|
+
* - `{ enabled: false, default: "dark" }` → toggle hidden, force dark
|
|
1108
|
+
*
|
|
1109
|
+
* @example
|
|
1110
|
+
* ```ts
|
|
1111
|
+
* // Hide toggle, force dark mode
|
|
1112
|
+
* themeToggle: { enabled: false, default: "dark" }
|
|
1113
|
+
*
|
|
1114
|
+
* // Show toggle with system option
|
|
1115
|
+
* themeToggle: { mode: "light-dark-system" }
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
1118
|
+
themeToggle?: boolean | ThemeToggleConfig;
|
|
1119
|
+
/**
|
|
1120
|
+
* Breadcrumb navigation above page content.
|
|
1121
|
+
*
|
|
1122
|
+
* - `true` or `undefined` → breadcrumb is shown (default)
|
|
1123
|
+
* - `false` → breadcrumb is hidden
|
|
1124
|
+
* - `{ enabled: false }` → breadcrumb is hidden
|
|
1125
|
+
* - `{ component: MyBreadcrumb }` → custom breadcrumb component
|
|
1126
|
+
*/
|
|
1127
|
+
breadcrumb?: boolean | BreadcrumbConfig;
|
|
1128
|
+
/**
|
|
1129
|
+
* Sidebar customisation.
|
|
1130
|
+
*
|
|
1131
|
+
* - `true` or `undefined` → default sidebar
|
|
1132
|
+
* - `false` → sidebar is hidden
|
|
1133
|
+
* - `{ component: MySidebar }` → custom sidebar component
|
|
1134
|
+
* - `{ footer: <MyFooter />, banner: <MyBanner /> }` → add footer/banner
|
|
1135
|
+
*/
|
|
1136
|
+
sidebar?: boolean | SidebarConfig;
|
|
1137
|
+
/**
|
|
1138
|
+
* Custom MDX component overrides.
|
|
1139
|
+
*
|
|
1140
|
+
* Pass your own React components to replace defaults (e.g. Callout, CodeBlock).
|
|
1141
|
+
* Components must match the expected props interface.
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* import { MyCallout } from "./components/my-callout";
|
|
1146
|
+
*
|
|
1147
|
+
* export default defineDocs({
|
|
1148
|
+
* entry: "docs",
|
|
1149
|
+
* theme: fumadocs(),
|
|
1150
|
+
* components: {
|
|
1151
|
+
* Callout: MyCallout,
|
|
1152
|
+
* },
|
|
1153
|
+
* });
|
|
1154
|
+
* ```
|
|
1155
|
+
*/
|
|
1156
|
+
components?: Record<string, unknown>;
|
|
1157
|
+
/**
|
|
1158
|
+
* Callback fired when the user clicks the copy button on a code block.
|
|
1159
|
+
* Called in addition to the default copy-to-clipboard behavior.
|
|
1160
|
+
* Use it for analytics, logging, or custom behavior.
|
|
1161
|
+
*
|
|
1162
|
+
* @example
|
|
1163
|
+
* ```ts
|
|
1164
|
+
* export default defineDocs({
|
|
1165
|
+
* entry: "docs",
|
|
1166
|
+
* theme: fumadocs(),
|
|
1167
|
+
* onCopyClick(data) {
|
|
1168
|
+
* console.log("Code copied", data.title, data.language, data.url);
|
|
1169
|
+
* analytics.track("code_block_copy", { title: data.title, url: data.url });
|
|
1170
|
+
* },
|
|
1171
|
+
* });
|
|
1172
|
+
* ```
|
|
1173
|
+
*/
|
|
1174
|
+
onCopyClick?: (data: CodeBlockCopyData) => void;
|
|
1175
|
+
/**
|
|
1176
|
+
* Icon registry for sidebar items.
|
|
1177
|
+
*
|
|
1178
|
+
* Map string labels to React elements. Reference them in page frontmatter
|
|
1179
|
+
* with `icon: "label"` and the matching icon renders in the sidebar.
|
|
1180
|
+
*
|
|
1181
|
+
* @example
|
|
1182
|
+
* ```tsx
|
|
1183
|
+
* import { Book, Terminal, Rocket } from "lucide-react";
|
|
1184
|
+
*
|
|
1185
|
+
* export default defineDocs({
|
|
1186
|
+
* entry: "docs",
|
|
1187
|
+
* theme: fumadocs(),
|
|
1188
|
+
* icons: {
|
|
1189
|
+
* book: <Book />,
|
|
1190
|
+
* terminal: <Terminal />,
|
|
1191
|
+
* rocket: <Rocket />,
|
|
1192
|
+
* },
|
|
1193
|
+
* });
|
|
1194
|
+
* ```
|
|
1195
|
+
*
|
|
1196
|
+
* Then in `page.mdx` frontmatter:
|
|
1197
|
+
* ```yaml
|
|
1198
|
+
* ---
|
|
1199
|
+
* title: "CLI Reference"
|
|
1200
|
+
* icon: "terminal"
|
|
1201
|
+
* ---
|
|
1202
|
+
* ```
|
|
1203
|
+
*/
|
|
1204
|
+
icons?: Record<string, unknown>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Page action buttons shown above the content area.
|
|
1207
|
+
* Includes "Copy Markdown" and "Open in …" (LLM dropdown).
|
|
1208
|
+
*
|
|
1209
|
+
* @example
|
|
1210
|
+
* ```ts
|
|
1211
|
+
* pageActions: {
|
|
1212
|
+
* copyMarkdown: { enabled: true },
|
|
1213
|
+
* openDocs: {
|
|
1214
|
+
* enabled: true,
|
|
1215
|
+
* providers: [
|
|
1216
|
+
* { name: "ChatGPT", urlTemplate: "https://chatgpt.com/?q={url}" },
|
|
1217
|
+
* { name: "Claude", urlTemplate: "https://claude.ai/new?q={url}" },
|
|
1218
|
+
* ],
|
|
1219
|
+
* },
|
|
1220
|
+
* }
|
|
1221
|
+
* ```
|
|
1222
|
+
*/
|
|
1223
|
+
pageActions?: PageActionsConfig;
|
|
1224
|
+
/**
|
|
1225
|
+
* Configuration for the "Last updated" date display.
|
|
1226
|
+
*
|
|
1227
|
+
* - `true` or `undefined` → shown in footer next to "Edit on GitHub" (default)
|
|
1228
|
+
* - `false` → hidden
|
|
1229
|
+
* - `{ position: "below-title" }` → shown below the page title
|
|
1230
|
+
* - `{ position: "footer" }` → shown next to "Edit on GitHub" (default)
|
|
1231
|
+
*
|
|
1232
|
+
* @example
|
|
1233
|
+
* ```ts
|
|
1234
|
+
* // Show below title (Mintlify style)
|
|
1235
|
+
* lastUpdated: { position: "below-title" }
|
|
1236
|
+
*
|
|
1237
|
+
* // Hide entirely
|
|
1238
|
+
* lastUpdated: false
|
|
1239
|
+
* ```
|
|
1240
|
+
*/
|
|
1241
|
+
lastUpdated?: boolean | LastUpdatedConfig;
|
|
1242
|
+
/**
|
|
1243
|
+
* AI-powered "Ask AI" chat for documentation.
|
|
1244
|
+
*
|
|
1245
|
+
* When enabled, the unified API route handler (`/api/docs`) accepts
|
|
1246
|
+
* POST requests for AI chat. The handler uses RAG (Retrieval-Augmented
|
|
1247
|
+
* Generation) — it searches relevant docs, builds context, and streams
|
|
1248
|
+
* a response from an LLM.
|
|
1249
|
+
*
|
|
1250
|
+
* The API key defaults to `process.env.OPENAI_API_KEY`. For other providers,
|
|
1251
|
+
* pass the key via `apiKey: process.env.YOUR_KEY`.
|
|
1252
|
+
*
|
|
1253
|
+
* @example
|
|
1254
|
+
* ```ts
|
|
1255
|
+
* // Enable with defaults (gpt-4o-mini, OPENAI_API_KEY)
|
|
1256
|
+
* ai: { enabled: true }
|
|
1257
|
+
*
|
|
1258
|
+
* // Custom model + system prompt
|
|
1259
|
+
* ai: {
|
|
1260
|
+
* enabled: true,
|
|
1261
|
+
* model: "gpt-4o",
|
|
1262
|
+
* systemPrompt: "You are an expert on our SDK. Be concise.",
|
|
1263
|
+
* }
|
|
1264
|
+
*
|
|
1265
|
+
* // Use a different provider (e.g. Groq)
|
|
1266
|
+
* ai: {
|
|
1267
|
+
* enabled: true,
|
|
1268
|
+
* baseUrl: "https://api.groq.com/openai/v1",
|
|
1269
|
+
* apiKey: process.env.GROQ_API_KEY,
|
|
1270
|
+
* model: "llama-3.1-70b-versatile",
|
|
1271
|
+
* }
|
|
1272
|
+
* ```
|
|
1273
|
+
*/
|
|
1274
|
+
ai?: AIConfig;
|
|
1275
|
+
/**
|
|
1276
|
+
* Sidebar ordering strategy.
|
|
1277
|
+
*
|
|
1278
|
+
* - `"alphabetical"` — sort pages alphabetically by folder name (default)
|
|
1279
|
+
* - `"numeric"` — sort by frontmatter `order` field (lower first, unset pages last)
|
|
1280
|
+
* - `OrderingItem[]` — explicit slug-based ordering with nested children
|
|
1281
|
+
*
|
|
1282
|
+
* @default "alphabetical"
|
|
1283
|
+
*
|
|
1284
|
+
* @example
|
|
1285
|
+
* ```ts
|
|
1286
|
+
* // Alphabetical (default)
|
|
1287
|
+
* ordering: "alphabetical",
|
|
1288
|
+
*
|
|
1289
|
+
* // Use frontmatter `order: 1`, `order: 2`, etc.
|
|
1290
|
+
* ordering: "numeric",
|
|
1291
|
+
*
|
|
1292
|
+
* // Explicit slug-based ordering
|
|
1293
|
+
* ordering: [
|
|
1294
|
+
* { slug: "installation" },
|
|
1295
|
+
* { slug: "cli" },
|
|
1296
|
+
* { slug: "configuration" },
|
|
1297
|
+
* { slug: "themes", children: [
|
|
1298
|
+
* { slug: "default" },
|
|
1299
|
+
* { slug: "darksharp" },
|
|
1300
|
+
* { slug: "pixel-border" },
|
|
1301
|
+
* { slug: "creating-themes" },
|
|
1302
|
+
* ]},
|
|
1303
|
+
* { slug: "customization" },
|
|
1304
|
+
* { slug: "reference" },
|
|
1305
|
+
* ]
|
|
1306
|
+
* ```
|
|
1307
|
+
*/
|
|
1308
|
+
ordering?: "alphabetical" | "numeric" | OrderingItem[];
|
|
1309
|
+
/**
|
|
1310
|
+
* Auto-generate `/llms.txt` and `/llms-full.txt` routes for LLM-friendly
|
|
1311
|
+
* documentation. These files let AI tools quickly understand your docs.
|
|
1312
|
+
*
|
|
1313
|
+
* @example
|
|
1314
|
+
* ```ts
|
|
1315
|
+
* llmsTxt: {
|
|
1316
|
+
* enabled: true,
|
|
1317
|
+
* baseUrl: "https://docs.example.com",
|
|
1318
|
+
* }
|
|
1319
|
+
* ```
|
|
1320
|
+
*
|
|
1321
|
+
* @see https://llmstxt.org
|
|
1322
|
+
*/
|
|
1323
|
+
llmsTxt?: boolean | LlmsTxtConfig;
|
|
1324
|
+
/**
|
|
1325
|
+
* Generated API reference pages from framework route conventions.
|
|
1326
|
+
*
|
|
1327
|
+
* The first implementation targets Next.js route handlers under `app/api/<segments>/route.ts`.
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* ```ts
|
|
1331
|
+
* apiReference: {
|
|
1332
|
+
* enabled: true,
|
|
1333
|
+
* path: "api-reference",
|
|
1334
|
+
* routeRoot: "api",
|
|
1335
|
+
* }
|
|
1336
|
+
* ```
|
|
1337
|
+
*/
|
|
1338
|
+
apiReference?: boolean | ApiReferenceConfig;
|
|
1339
|
+
/** SEO metadata - separate from theme */
|
|
1340
|
+
metadata?: DocsMetadata;
|
|
1341
|
+
/** Open Graph image handling */
|
|
1342
|
+
og?: OGConfig;
|
|
1343
|
+
}
|
|
1344
|
+
//# sourceMappingURL=types.d.ts.map
|