API Reference
Complete reference for every option in docs.config.ts. All types are exported from @farming-labs/docs.
defineDocs(config)
The entry point for configuring your docs. Returns a typed config object.
import { defineDocs } from "@farming-labs/docs";
export default defineDocs({
entry: "docs",
// ...all options below
});DocsConfig
Top-level configuration object passed to defineDocs().
| Property | Type | Default | Description |
|---|---|---|---|
entry | string | required | URL path prefix for docs (e.g. "docs" → /docs) |
contentDir | string | same as entry | Path to content files. SvelteKit, Astro, and Nuxt only — Next.js uses app/{entry}/ |
staticExport | boolean | false | Set true for full static builds; hides search and AI (see Configuration) |
theme | DocsTheme | — | Theme preset from a factory (fumadocs(), darksharp(), pixelBorder(), etc.) |
github | string | GithubConfig | — | GitHub repo config for "Edit on GitHub" links |
nav | DocsNav | — | Sidebar header title and URL |
themeToggle | boolean | ThemeToggleConfig | true | Light/dark mode toggle |
breadcrumb | boolean | BreadcrumbConfig | true | Breadcrumb navigation |
sidebar | boolean | SidebarConfig | true | Sidebar visibility and customization |
icons | Record<string, unknown> | — | Icon registry for frontmatter icon fields |
components | Record<string, unknown> | — | Custom MDX component overrides |
onCopyClick | (data: CodeBlockCopyData) => void | — | Callback when the user clicks the copy button on a code block (runs in addition to copy) |
pageActions | PageActionsConfig | — | "Copy Markdown" and "Open in LLM" buttons |
ai | AIConfig | — | RAG-powered AI chat |
ordering | "alphabetical" | "numeric" | OrderingItem[] | "alphabetical" | Sidebar page ordering strategy |
metadata | DocsMetadata | — | SEO metadata |
og | OGConfig | — | Open Graph image config |
Ordering
Controls how pages are sorted in the sidebar. Three strategies are available:
"alphabetical" (default)
Pages are sorted alphabetically by folder name. No extra configuration needed.
ordering: "alphabetical","numeric"
Pages are sorted by the order field in frontmatter. Lower numbers appear first. Pages without order are sorted alphabetically after ordered pages.
ordering: "numeric",Then in your page frontmatter:
---
title: "Installation"
order: 1
---Slug-based (OrderingItem[])
Pass an array of { slug, children? } objects for explicit control over page order, including nested pages.
ordering: [
{ slug: "installation" },
{ slug: "cli" },
{ slug: "configuration" },
{
slug: "themes",
children: [
{ slug: "default" },
{ slug: "darksharp" },
{ slug: "pixel-border" },
{ slug: "creating-themes" },
],
},
{
slug: "customization",
children: [
{ slug: "colors" },
{ slug: "typography" },
{ slug: "sidebar" },
{ slug: "components" },
{ slug: "ai-chat" },
{ slug: "page-actions" },
],
},
{ slug: "reference" },
],OrderingItem
| Property | Type | Description |
|---|---|---|
slug | string | Folder name at this level (not the full path) |
children | OrderingItem[] | Ordering for child pages within this folder |
Pages not listed in the array appear alphabetically after the listed ones.
DocsNav
Sidebar header configuration.
| Property | Type | Default | Description |
|---|---|---|---|
title | string | ReactNode | "Docs" | Sidebar header title. React elements supported in Next.js |
url | string | "/{entry}" | URL the title links to |
nav: {
title: "My Docs",
url: "/docs",
},GithubConfig
GitHub repository configuration. Enables "Edit on GitHub" links in page footers.
| Property | Type | Default | Description |
|---|---|---|---|
url | string | required | Repository URL (e.g. "https://github.com/my-org/repo") |
branch | string | "main" | Branch name |
directory | string | — | Content subdirectory for monorepos |
// Simple
github: "https://github.com/my-org/my-docs",
// Monorepo
github: {
url: "https://github.com/my-org/monorepo",
branch: "main",
directory: "apps/docs/docs",
},The "Edit on GitHub" link only appears when both
urlanddirectoryare provided.
onCopyClick and CodeBlockCopyData
Optional callback on DocsConfig. Fired when the user clicks the copy button on a code block — in addition to copying to the clipboard. Use it for analytics, logging, or custom behavior. See Code block copy callback for setup (Next.js vs SvelteKit/Astro/Nuxt).
CodeBlockCopyData
Argument passed to onCopyClick(data: CodeBlockCopyData).
| Property | Type | Description |
|---|---|---|
title | string | undefined | Code block title (e.g. from fenced code meta), if present |
content | string | Raw code content (what was copied) |
url | string | Current page URL at the time of copy |
language | string | undefined | Language/syntax hint (e.g. "tsx", "bash"), if present |
import type { CodeBlockCopyData } from "@farming-labs/docs";
import { defineDocs } from "@farming-labs/docs";
export default defineDocs({
entry: "docs",
onCopyClick(data: CodeBlockCopyData) {
// data.title, data.content, data.url, data.language
console.log("Copied:", data.language, data.title ?? "(no title)");
},
});ThemeToggleConfig
Light/dark mode toggle in the sidebar.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Show or hide the toggle |
default | "light" | "dark" | "system" | "system" | Forced theme when enabled: false |
mode | "light-dark" | "light-dark-system" | "light-dark" | Toggle behavior |
// Show toggle (default)
themeToggle: true,
// Hide toggle, follow system preference
themeToggle: false,
// Hide toggle, force dark mode
themeToggle: { enabled: false, default: "dark" },
// Show toggle with system option
themeToggle: { mode: "light-dark-system" },BreadcrumbConfig
Breadcrumb navigation above page content.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Show or hide breadcrumbs |
component | Component | — | Custom breadcrumb component (Next.js only) |
breadcrumb: true, // show (default)
breadcrumb: false, // hide
breadcrumb: { enabled: false }, // hideSidebarConfig
Sidebar visibility and customization. See Sidebar for the full guide including custom sidebar components.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Show or hide the sidebar |
component | (props: SidebarComponentProps) => ReactNode | — | Custom sidebar render function. Receives { tree, collapsible, flat }. Next.js only — other frameworks use slots. |
footer | ReactNode | — | Content rendered below nav items |
banner | ReactNode | — | Content rendered above nav items |
collapsible | boolean | true | Whether sidebar is collapsible on desktop |
flat | boolean | false | Render all items flat (Mintlify-style, no collapsible groups) |
SidebarComponentProps
Props passed to a custom sidebar component:
| Property | Type | Description |
|---|---|---|
tree | SidebarTree | Full page tree with all parent-child relationships |
collapsible | boolean | Whether folders are collapsible |
flat | boolean | Whether folders are rendered flat |
SidebarTree
| Property | Type | Description |
|---|---|---|
name | string | Root name (e.g. "Docs") |
children | SidebarNode[] | Top-level sidebar items |
SidebarNode
A union of SidebarPageNode | SidebarFolderNode.
SidebarPageNode
| Property | Type | Description |
|---|---|---|
type | "page" | Node type |
name | string | Display name |
url | string | Page URL |
icon | unknown | Icon from registry |
SidebarFolderNode
| Property | Type | Description |
|---|---|---|
type | "folder" | Node type |
name | string | Display name |
icon | unknown | Icon from registry |
index | SidebarPageNode | Folder's landing page |
children | SidebarNode[] | Child pages and sub-folders |
collapsible | boolean | Whether this folder collapses |
defaultOpen | boolean | Whether it starts open |
sidebar: true, // show (default)
sidebar: false, // hide
sidebar: { collapsible: false }, // non-collapsible
sidebar: { flat: true }, // Mintlify-style flat
sidebar: { // custom component
component: ({ tree }) => <MySidebar tree={tree} />,
},DocsTheme
Theme configuration returned by theme factories.
| Property | Type | Description |
|---|---|---|
name | string | Theme identifier (e.g. "fumadocs", "darksharp") |
ui | UIConfig | Visual configuration — colors, typography, layout |
Created via theme factories:
import { fumadocs } from "@farming-labs/theme";
import { darksharp } from "@farming-labs/theme/darksharp";
import { pixelBorder } from "@farming-labs/theme/pixel-border";
import { colorful } from "@farming-labs/theme/colorful";
theme: fumadocs({ ui: { /* overrides */ } }),import { fumadocs, darksharp, pixelBorder } from "@farming-labs/svelte-theme";
import { colorful } from "@farming-labs/svelte-theme/colorful";
theme: fumadocs({ ui: { /* overrides */ } }),import { fumadocs } from "@farming-labs/astro-theme";
import { pixelBorder } from "@farming-labs/astro-theme/pixel-border";
import { darksharp } from "@farming-labs/astro-theme/darksharp";
import { colorful } from "@farming-labs/astro-theme/colorful";
theme: fumadocs({ ui: { /* overrides */ } }),import { fumadocs } from "@farming-labs/nuxt-theme/fumadocs";
import { colorful } from "@farming-labs/nuxt-theme/colorful";
theme: fumadocs({ ui: { /* overrides */ } }),UIConfig
Fine-grained visual configuration passed to theme factories.
| Property | Type | Description |
|---|---|---|
colors | ColorsConfig | Theme color tokens |
typography | TypographyConfig | Font families, heading styles |
radius | string | Global border-radius (e.g. "0px", "0.5rem") |
layout | LayoutConfig | Content width, sidebar width, TOC settings |
codeBlock | CodeBlockConfig | Syntax highlighting and line numbers |
sidebar | SidebarStyleConfig | Sidebar visual style |
card | CardConfig | Card component styling |
ColorsConfig
All color tokens. Accepts any CSS color value (hex, rgb, oklch, hsl).
| Token | Description |
|---|---|
primary | Primary brand color |
primaryForeground | Text color on primary backgrounds |
background | Page background |
foreground | Default text color |
muted | Muted background (e.g. code blocks) |
mutedForeground | Text on muted backgrounds |
border | Default border color |
card | Card background |
cardForeground | Card text color |
accent | Accent color |
accentForeground | Text on accent backgrounds |
secondary | Secondary color |
secondaryForeground | Text on secondary backgrounds |
popover | Popover/dropdown background |
popoverForeground | Popover text color |
ring | Focus ring color |
colors: {
primary: "oklch(0.72 0.19 149)",
background: "hsl(0 0% 2%)",
border: "#262626",
},LayoutConfig
| Property | Type | Default | Description |
|---|---|---|---|
contentWidth | number | — | Max width of content area in px |
sidebarWidth | number | — | Sidebar width in px |
tocWidth | number | — | Table of contents width in px |
toc.enabled | boolean | true | Show table of contents |
toc.depth | number | 3 | Max heading depth for TOC |
header.height | number | — | Header height in px |
header.sticky | boolean | true | Sticky header |
CodeBlockConfig
| Property | Type | Default | Description |
|---|---|---|---|
showLineNumbers | boolean | false | Show line numbers |
showCopyButton | boolean | true | Show copy button |
theme | string | — | Shiki theme for light mode |
darkTheme | string | — | Shiki theme for dark mode |
SidebarStyleConfig
| Property | Type | Default | Description |
|---|---|---|---|
style | "default" | "bordered" | "floating" | "default" | Sidebar visual style |
background | string | — | Background color override |
borderColor | string | — | Border color override |
TypographyConfig
typography: {
font: {
style: {
sans: "Inter, sans-serif",
mono: "JetBrains Mono, monospace",
},
h1: { size: "2.25rem", weight: 700, letterSpacing: "-0.02em" },
h2: { size: "1.75rem", weight: 600 },
h3: { size: "1.25rem", weight: 600 },
body: { size: "1rem", lineHeight: "1.75" },
small: { size: "0.875rem" },
},
},FontStyle
Used for each heading level and body text.
| Property | Type | Description |
|---|---|---|
size | string | CSS font-size (e.g. "2.25rem", "clamp(1.8rem, 3vw, 2.5rem)") |
weight | string | number | CSS font-weight (e.g. 700, "bold") |
lineHeight | string | CSS line-height (e.g. "1.2", "28px") |
letterSpacing | string | CSS letter-spacing (e.g. "-0.02em") |
AIConfig
RAG-powered AI chat. See Ask AI for usage guide.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable AI chat |
mode | "search" | "floating" | "search" | UI mode: integrated in search or floating widget |
position | "bottom-right" | "bottom-left" | "bottom-center" | "bottom-right" | Floating button position (only when mode: "floating") |
floatingStyle | "panel" | "modal" | "popover" | "full-modal" | "panel" | Floating chat visual style |
triggerComponent | Component | — | Custom floating button component |
model | string | "gpt-4o-mini" | LLM model name (OpenAI-compatible) |
systemPrompt | string | auto-generated | Custom system prompt |
baseUrl | string | "https://api.openai.com/v1" | OpenAI-compatible API base URL |
apiKey | string | process.env.OPENAI_API_KEY | API key for the LLM provider |
maxResults | number | 5 | Number of doc pages to include as RAG context |
suggestedQuestions | string[] | — | Pre-filled questions shown when chat is empty |
aiLabel | string | "AI" | Display name for the AI assistant |
packageName | string | — | Package name the AI uses in import examples |
docsUrl | string | — | Base URL the AI uses for links |
loader | string | "shimmer-dots" | Loading indicator variant ("shimmer-dots", "circular", "dots", "typing", "wave", "bars", "pulse", "pulse-dot", "terminal", "text-blink", "text-shimmer", "loading-dots") |
loadingComponent | (props: { name: string }) => ReactNode | — | Custom loading component (overrides loader, Next.js only) |
Floating styles
| Style | Description |
|---|---|
"panel" | Tall panel sliding up from the button. No backdrop. |
"modal" | Centered modal with backdrop overlay, like Cmd+K search. |
"popover" | Compact popover near the button. |
"full-modal" | Full-screen immersive overlay with pills for suggested questions. |
PageActionsConfig
Action buttons shown on each docs page. See Page Actions for usage guide.
| Property | Type | Default | Description |
|---|---|---|---|
position | "above-title" | "below-title" | "below-title" | Where to render the buttons |
copyMarkdown | boolean | CopyMarkdownConfig | false | "Copy Markdown" button |
openDocs | boolean | OpenDocsConfig | false | "Open in LLM" dropdown |
CopyMarkdownConfig
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Show the button |
OpenDocsConfig
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Show the dropdown |
providers | OpenDocsProvider[] | sensible defaults | LLM/tool providers |
OpenDocsProvider
| Property | Type | Description |
|---|---|---|
name | string | Display name (e.g. "ChatGPT", "Claude") |
icon | ReactNode | Icon rendered next to the name |
urlTemplate | string | URL template. {url} is replaced with the page URL, {mdxUrl} with the MDX URL. |
pageActions: {
copyMarkdown: { enabled: true },
openDocs: {
enabled: true,
providers: [
{ name: "ChatGPT", urlTemplate: "https://chatgpt.com/?q={url}" },
{ name: "Claude", urlTemplate: "https://claude.ai/new?q=Read+this:+{url}" },
],
},
},DocsMetadata
SEO metadata configuration.
| Property | Type | Default | Description |
|---|---|---|---|
titleTemplate | string | — | Page title template. %s is replaced with the page title. |
description | string | — | Default meta description |
twitterCard | "summary" | "summary_large_image" | — | Twitter card type |
metadata: {
titleTemplate: "%s – My Docs",
description: "Documentation for my project",
},OGConfig
Open Graph image configuration. When endpoint is set, each docs page gets a dynamic OG image: the framework passes the page’s title and description (from frontmatter) to the endpoint, and the layout injects the resulting image URL into og:image and twitter:image meta tags. For a full guide (how dynamic OG works, what context is passed, and how the docs website implements it), see OG Images.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable OG image generation |
type | "static" | "dynamic" | — | Static images or dynamic generation |
endpoint | string | — | API endpoint for dynamic OG images |
defaultImage | string | — | Fallback OG image URL |
Example (Next.js): In docs.config.tsx, set og.endpoint to your OG route path. Then implement app/api/og/route.tsx (or route.ts) that accepts title and description query params and returns a 1200×630 image (e.g. using ImageResponse from next/og).
og: {
enabled: true,
type: "dynamic",
endpoint: "/api/og",
},Testing your OG image
- Start the dev server for the app that serves the OG route (e.g.
cd website && pnpm devorcd examples/next && pnpm dev). - Open the OG URL in the browser, e.g.
http://localhost:3000/api/og?title=Test&description=My+description
(use your app’s port if different). - After changing the OG route code, refresh the page. If the image doesn’t update, do a hard refresh (e.g. Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows) or open the URL in a private/incognito window. You can also add a cache-busting query param (e.g.
&_=1,&_=2) to force a new request.
Page Frontmatter
Each docs page (.mdx / .md) supports these frontmatter fields:
| Property | Type | Description |
|---|---|---|
title | string | Required. Page title, shown in sidebar and page heading |
description | string | Page description, used for meta tags and search |
icon | string | Icon key from the icons registry. Shows in sidebar. |
order | number | Sort order in the sidebar (only when ordering: "numeric"). Lower numbers first. |
tags | string[] | Tags for categorization |
ogImage | string | Shorthand for a single OG image path. Ignored if openGraph is set. |
openGraph | PageOpenGraph | Full Open Graph object (e.g. images: [{ url, width?, height? }]). When set, replaces generated OG from the config (e.g. dynamic endpoint). |
twitter | PageTwitter | Full Twitter card object (e.g. card, images). When set, replaces generated twitter metadata. |
hidden | boolean | If true, hide the page from the sidebar (page remains reachable by URL). Optional; behavior may vary by adapter. |
Static OG example — use openGraph and twitter in frontmatter to serve a static image instead of the dynamic OG endpoint:
---
title: "Title of Docs"
description: "Title of the docs goes here"
icon: "harddrive"
openGraph:
images:
- url: "/og/path-to-image/image.png"
width: 1200
height: 630
twitter:
card: "summary_large_image"
images:
- "/og/path-to-image/image.png"
---Minimal example (shorthand ogImage or generated OG):
---
title: "Getting Started"
description: "Set up your docs in 5 minutes"
icon: "rocket"
order: 1
---Data types
Frontmatter is YAML between the --- fences. Supported value types:
| Type | Example in frontmatter | Use in framework fields |
|---|---|---|
string | title: "Hello" or title: Hello | title, description, icon, ogImage |
number | order: 1 | order |
boolean | hidden: true | Optional (e.g. hide from sidebar) |
string[] | tags: [a, b] or tags: ["a", "b"] | tags |
You can use other YAML types (e.g. nested objects) for custom keys; only the fields in the table above are used by the framework for sidebar, SEO, and OG.
How frontmatter is passed
- Next.js — The MDX pipeline uses
remark-frontmatterandremark-mdx-frontmatterwithname: "metadata". The parsed frontmatter is exposed as themetadataexport from the page. The layout andgenerateMetadatareceive it when resolving the page (e.g. viagetPage(params)), and it is used forcreatePageMetadata, sidebar tree (title, icon, order), and description maps. - SvelteKit / Astro / Nuxt — The docs loader (e.g.
import.meta.globor content layer) reads each.md/.mdxfile, parses frontmatter, and builds the nav tree and page data. Frontmatter is passed to the layout as page data (e.g.page.dataor the props your content component receives). The same fields (title,description,icon,order,tags,ogImage) are used for sidebar, meta tags, and search.
So in all frameworks, the same frontmatter fields drive titles, descriptions, icons, ordering, and OG; only the mechanism (MDX metadata vs. content loader page.data) differs.
createTheme(options)
Create a custom theme from scratch. See Creating Themes.
import { createTheme } from "@farming-labs/docs";
export const myTheme = createTheme({
name: "my-theme",
ui: {
colors: { primary: "#ff4d8d", background: "#0a0a0a" },
radius: "0px",
sidebar: { style: "bordered" },
},
});extendTheme(base, overrides)
Extend an existing theme with overrides.
import { extendTheme } from "@farming-labs/docs";
import { fumadocs } from "@farming-labs/theme";
export const myTheme = extendTheme(fumadocs(), {
ui: {
colors: { primary: "oklch(0.72 0.19 149)" },
},
});SvelteKit Server API
createDocsServer(config)
Creates all server-side functions for a SvelteKit docs site.
import { createDocsServer } from "@farming-labs/svelte/server";Parameters:
| Property | Type | Description |
|---|---|---|
config | DocsConfig | The config object from defineDocs() |
_preloadedContent | Record<string, string> | Pre-loaded markdown files from import.meta.glob. Required for serverless. |
Returns:
| Property | Type | Description |
|---|---|---|
load | (event) => Promise<PageData> | Layout load function (use in +layout.server.js) |
GET | (event) => Response | Search endpoint handler |
POST | (event) => Promise<Response> | AI chat endpoint handler |
import { createDocsServer } from "@farming-labs/svelte/server";
import config from "./docs.config";
const contentFiles = import.meta.glob("/docs/**/*.{md,mdx,svx}", {
query: "?raw",
import: "default",
eager: true,
}) as Record<string, string>;
export const { load, GET, POST } = createDocsServer({
...config,
_preloadedContent: contentFiles,
});SvelteKit Components
Imported from @farming-labs/svelte-theme:
| Component | Props | Description |
|---|---|---|
DocsLayout | tree, config, title?, titleUrl? | Main layout with sidebar, nav, search, AI |
DocsContent | data, config | Page content with TOC, breadcrumb, footer nav |
DocsPage | entry, tocEnabled, breadcrumbEnabled, previousPage, nextPage, editOnGithub, lastModified | Low-level page wrapper (used by DocsContent) |
Astro Server API
createDocsServer(config)
Same as SvelteKit — returns { load, GET, POST }.
import { createDocsServer } from "@farming-labs/astro/server";Parameters:
| Property | Type | Description |
|---|---|---|
config | DocsConfig | The config object from defineDocs() |
_preloadedContent | Record<string, string> | Pre-loaded markdown files from import.meta.glob. Required for serverless. |
Returns:
| Property | Type | Description |
|---|---|---|
load | (pathname: string) => Promise<PageData> | Takes a URL pathname string, returns page data |
GET | ({ request }) => Response | Search endpoint handler for GET /api/docs?query=... |
POST | ({ request }) => Promise<Response> | AI chat endpoint handler with SSE streaming |
import { createDocsServer } from "@farming-labs/astro/server";
import config from "./docs.config";
const contentFiles = import.meta.glob("/docs/**/*.{md,mdx}", {
query: "?raw",
import: "default",
eager: true,
}) as Record<string, string>;
export const { load, GET, POST } = createDocsServer({
...config,
_preloadedContent: contentFiles,
});Astro Components
| Component | Import | Description |
|---|---|---|
DocsLayout | @farming-labs/astro-theme/src/components/DocsLayout.astro | Main layout with sidebar, search, and theme toggle |
DocsContent | @farming-labs/astro-theme/src/components/DocsContent.astro | Page content with metadata |
DocsPage | @farming-labs/astro-theme/src/components/DocsPage.astro | Page structure (TOC, breadcrumb, nav) |
ThemeToggle | @farming-labs/astro-theme/src/components/ThemeToggle.astro | Light/dark toggle |
SearchDialog | @farming-labs/astro-theme/src/components/SearchDialog.astro | Search + AI dialog |
CSS Imports
Same pattern as SvelteKit:
| Import | Description |
|---|---|
@farming-labs/astro-theme/css | Default (fumadocs) theme |
@farming-labs/astro-theme/pixel-border/css | Pixel border theme |
@farming-labs/astro-theme/darksharp/css | Darksharp theme |
Theme Factories
| Factory | Import |
|---|---|
fumadocs() | @farming-labs/astro-theme |
pixelBorder() | @farming-labs/astro-theme/pixel-border |
darksharp() | @farming-labs/astro-theme/darksharp |
Nuxt Server API
defineDocsHandler(config, useStorage)
Creates a single Nitro event handler that serves docs loading, search, and AI chat for Nuxt.
import { defineDocsHandler } from "@farming-labs/nuxt/server";Parameters:
| Property | Type | Description |
|---|---|---|
config | DocsConfig | The config object from defineDocs() |
useStorage | Function | Nitro's useStorage utility for accessing server assets |
Returns:
A Nitro event handler that responds to GET (page loading + search) and POST (AI chat) requests.
import { defineDocsHandler } from "@farming-labs/nuxt/server";
import config from "../../docs.config";
export default defineDocsHandler(config, useStorage);Nuxt uses Nitro's
serverAssetsto load markdown files. Configurenitro.serverAssetsinnuxt.config.tsto point to your docs directory.
Nuxt Components
Imported from @farming-labs/nuxt-theme:
| Component | Props | Description |
|---|---|---|
DocsLayout | tree, config, triggerComponent? | Main layout with sidebar, nav, search, AI |
DocsContent | data, config | Page content with TOC, breadcrumb, footer nav |
CSS Imports
| Import | Description |
|---|---|
@farming-labs/nuxt-theme/fumadocs/css | Default (fumadocs) theme |
Theme Factories
| Factory | Import |
|---|---|
fumadocs() | @farming-labs/nuxt-theme/fumadocs |
Next.js API
RootProvider
Client-side provider that wraps your entire app. Enables search, theme switching (light/dark), and AI chat. Must be placed in your root app/layout.tsx.
import { RootProvider } from "@farming-labs/theme";
import "./global.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
search | SearchProviderProps | { options: { api: "/api/docs" } } | Search configuration. API defaults to the unified docs handler. |
theme | ThemeProviderProps | — | Theme provider options (passed to next-themes) |
children | ReactNode | required | Your app content |
suppressHydrationWarningon<html>prevents React warnings caused by the theme class being injected before hydration.
withDocs(nextConfig)
Wraps your Next.js config with docs framework support. Handles MDX, routing, search index generation, and auto-generates mdx-components.tsx and app/docs/layout.tsx if missing.
import { withDocs } from "@farming-labs/next/config";
export default withDocs({});createDocsLayout(config)
Creates the docs layout component from your config. Auto-generated by withDocs() — you typically don't need to create this manually.
import { createDocsLayout } from "@farming-labs/theme";
import config from "@/docs.config";
const { DocsLayout } = createDocsLayout(config);
export default function Layout({ children }) {
return <DocsLayout>{children}</DocsLayout>;
}