Home /

docs

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().

PropertyTypeDefaultDescription
entrystringrequiredURL path prefix for docs (e.g. "docs"/docs)
contentDirstringsame as entryPath to content files. SvelteKit, Astro, and Nuxt only — Next.js uses app/{entry}/
staticExportbooleanfalseSet true for full static builds; hides search and AI (see Configuration)
themeDocsThemeTheme preset from a factory (fumadocs(), darksharp(), pixelBorder(), etc.)
githubstring | GithubConfigGitHub repo config for "Edit on GitHub" links
navDocsNavSidebar header title and URL
themeToggleboolean | ThemeToggleConfigtrueLight/dark mode toggle
breadcrumbboolean | BreadcrumbConfigtrueBreadcrumb navigation
sidebarboolean | SidebarConfigtrueSidebar visibility and customization
iconsRecord<string, unknown>Icon registry for frontmatter icon fields
componentsRecord<string, unknown>Custom MDX component overrides
onCopyClick(data: CodeBlockCopyData) => voidCallback when the user clicks the copy button on a code block (runs in addition to copy)
pageActionsPageActionsConfig"Copy Markdown" and "Open in LLM" buttons
aiAIConfigRAG-powered AI chat
ordering"alphabetical" | "numeric" | OrderingItem[]"alphabetical"Sidebar page ordering strategy
metadataDocsMetadataSEO metadata
ogOGConfigOpen 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

PropertyTypeDescription
slugstringFolder name at this level (not the full path)
childrenOrderingItem[]Ordering for child pages within this folder

Pages not listed in the array appear alphabetically after the listed ones.


DocsNav

Sidebar header configuration.

PropertyTypeDefaultDescription
titlestring | ReactNode"Docs"Sidebar header title. React elements supported in Next.js
urlstring"/{entry}"URL the title links to
nav: {
  title: "My Docs",
  url: "/docs",
},

GithubConfig

GitHub repository configuration. Enables "Edit on GitHub" links in page footers.

PropertyTypeDefaultDescription
urlstringrequiredRepository URL (e.g. "https://github.com/my-org/repo")
branchstring"main"Branch name
directorystringContent 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 url and directory are 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).

PropertyTypeDescription
titlestring | undefinedCode block title (e.g. from fenced code meta), if present
contentstringRaw code content (what was copied)
urlstringCurrent page URL at the time of copy
languagestring | undefinedLanguage/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.

PropertyTypeDefaultDescription
enabledbooleantrueShow 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" },

Breadcrumb navigation above page content.

PropertyTypeDefaultDescription
enabledbooleantrueShow or hide breadcrumbs
componentComponentCustom breadcrumb component (Next.js only)
breadcrumb: true,              // show (default)
breadcrumb: false,             // hide
breadcrumb: { enabled: false },  // hide

SidebarConfig

Sidebar visibility and customization. See Sidebar for the full guide including custom sidebar components.

PropertyTypeDefaultDescription
enabledbooleantrueShow or hide the sidebar
component(props: SidebarComponentProps) => ReactNodeCustom sidebar render function. Receives { tree, collapsible, flat }. Next.js only — other frameworks use slots.
footerReactNodeContent rendered below nav items
bannerReactNodeContent rendered above nav items
collapsiblebooleantrueWhether sidebar is collapsible on desktop
flatbooleanfalseRender all items flat (Mintlify-style, no collapsible groups)

SidebarComponentProps

Props passed to a custom sidebar component:

PropertyTypeDescription
treeSidebarTreeFull page tree with all parent-child relationships
collapsiblebooleanWhether folders are collapsible
flatbooleanWhether folders are rendered flat

SidebarTree

PropertyTypeDescription
namestringRoot name (e.g. "Docs")
childrenSidebarNode[]Top-level sidebar items

SidebarNode

A union of SidebarPageNode | SidebarFolderNode.

SidebarPageNode

PropertyTypeDescription
type"page"Node type
namestringDisplay name
urlstringPage URL
iconunknownIcon from registry

SidebarFolderNode

PropertyTypeDescription
type"folder"Node type
namestringDisplay name
iconunknownIcon from registry
indexSidebarPageNodeFolder's landing page
childrenSidebarNode[]Child pages and sub-folders
collapsiblebooleanWhether this folder collapses
defaultOpenbooleanWhether 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.

PropertyTypeDescription
namestringTheme identifier (e.g. "fumadocs", "darksharp")
uiUIConfigVisual 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.

PropertyTypeDescription
colorsColorsConfigTheme color tokens
typographyTypographyConfigFont families, heading styles
radiusstringGlobal border-radius (e.g. "0px", "0.5rem")
layoutLayoutConfigContent width, sidebar width, TOC settings
codeBlockCodeBlockConfigSyntax highlighting and line numbers
sidebarSidebarStyleConfigSidebar visual style
cardCardConfigCard component styling

ColorsConfig

All color tokens. Accepts any CSS color value (hex, rgb, oklch, hsl).

TokenDescription
primaryPrimary brand color
primaryForegroundText color on primary backgrounds
backgroundPage background
foregroundDefault text color
mutedMuted background (e.g. code blocks)
mutedForegroundText on muted backgrounds
borderDefault border color
cardCard background
cardForegroundCard text color
accentAccent color
accentForegroundText on accent backgrounds
secondarySecondary color
secondaryForegroundText on secondary backgrounds
popoverPopover/dropdown background
popoverForegroundPopover text color
ringFocus ring color
colors: {
  primary: "oklch(0.72 0.19 149)",
  background: "hsl(0 0% 2%)",
  border: "#262626",
},

LayoutConfig

PropertyTypeDefaultDescription
contentWidthnumberMax width of content area in px
sidebarWidthnumberSidebar width in px
tocWidthnumberTable of contents width in px
toc.enabledbooleantrueShow table of contents
toc.depthnumber3Max heading depth for TOC
header.heightnumberHeader height in px
header.stickybooleantrueSticky header

CodeBlockConfig

PropertyTypeDefaultDescription
showLineNumbersbooleanfalseShow line numbers
showCopyButtonbooleantrueShow copy button
themestringShiki theme for light mode
darkThemestringShiki theme for dark mode

SidebarStyleConfig

PropertyTypeDefaultDescription
style"default" | "bordered" | "floating""default"Sidebar visual style
backgroundstringBackground color override
borderColorstringBorder 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.

PropertyTypeDescription
sizestringCSS font-size (e.g. "2.25rem", "clamp(1.8rem, 3vw, 2.5rem)")
weightstring | numberCSS font-weight (e.g. 700, "bold")
lineHeightstringCSS line-height (e.g. "1.2", "28px")
letterSpacingstringCSS letter-spacing (e.g. "-0.02em")

AIConfig

RAG-powered AI chat. See Ask AI for usage guide.

PropertyTypeDefaultDescription
enabledbooleanfalseEnable 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
triggerComponentComponentCustom floating button component
modelstring"gpt-4o-mini"LLM model name (OpenAI-compatible)
systemPromptstringauto-generatedCustom system prompt
baseUrlstring"https://api.openai.com/v1"OpenAI-compatible API base URL
apiKeystringprocess.env.OPENAI_API_KEYAPI key for the LLM provider
maxResultsnumber5Number of doc pages to include as RAG context
suggestedQuestionsstring[]Pre-filled questions shown when chat is empty
aiLabelstring"AI"Display name for the AI assistant
packageNamestringPackage name the AI uses in import examples
docsUrlstringBase URL the AI uses for links
loaderstring"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 }) => ReactNodeCustom loading component (overrides loader, Next.js only)

Floating styles

StyleDescription
"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.

PropertyTypeDefaultDescription
position"above-title" | "below-title""below-title"Where to render the buttons
copyMarkdownboolean | CopyMarkdownConfigfalse"Copy Markdown" button
openDocsboolean | OpenDocsConfigfalse"Open in LLM" dropdown

CopyMarkdownConfig

PropertyTypeDefaultDescription
enabledbooleanfalseShow the button

OpenDocsConfig

PropertyTypeDefaultDescription
enabledbooleanfalseShow the dropdown
providersOpenDocsProvider[]sensible defaultsLLM/tool providers

OpenDocsProvider

PropertyTypeDescription
namestringDisplay name (e.g. "ChatGPT", "Claude")
iconReactNodeIcon rendered next to the name
urlTemplatestringURL 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.

PropertyTypeDefaultDescription
titleTemplatestringPage title template. %s is replaced with the page title.
descriptionstringDefault 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.

PropertyTypeDefaultDescription
enabledbooleanfalseEnable OG image generation
type"static" | "dynamic"Static images or dynamic generation
endpointstringAPI endpoint for dynamic OG images
defaultImagestringFallback 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

  1. Start the dev server for the app that serves the OG route (e.g. cd website && pnpm dev or cd examples/next && pnpm dev).
  2. 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).
  3. 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:

PropertyTypeDescription
titlestringRequired. Page title, shown in sidebar and page heading
descriptionstringPage description, used for meta tags and search
iconstringIcon key from the icons registry. Shows in sidebar.
ordernumberSort order in the sidebar (only when ordering: "numeric"). Lower numbers first.
tagsstring[]Tags for categorization
ogImagestringShorthand for a single OG image path. Ignored if openGraph is set.
openGraphPageOpenGraphFull Open Graph object (e.g. images: [{ url, width?, height? }]). When set, replaces generated OG from the config (e.g. dynamic endpoint).
twitterPageTwitterFull Twitter card object (e.g. card, images). When set, replaces generated twitter metadata.
hiddenbooleanIf 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:

TypeExample in frontmatterUse in framework fields
stringtitle: "Hello" or title: Hellotitle, description, icon, ogImage
numberorder: 1order
booleanhidden: trueOptional (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-frontmatter and remark-mdx-frontmatter with name: "metadata". The parsed frontmatter is exposed as the metadata export from the page. The layout and generateMetadata receive it when resolving the page (e.g. via getPage(params)), and it is used for createPageMetadata, sidebar tree (title, icon, order), and description maps.
  • SvelteKit / Astro / Nuxt — The docs loader (e.g. import.meta.glob or content layer) reads each .md/.mdx file, parses frontmatter, and builds the nav tree and page data. Frontmatter is passed to the layout as page data (e.g. page.data or 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:

PropertyTypeDescription
configDocsConfigThe config object from defineDocs()
_preloadedContentRecord<string, string>Pre-loaded markdown files from import.meta.glob. Required for serverless.

Returns:

PropertyTypeDescription
load(event) => Promise<PageData>Layout load function (use in +layout.server.js)
GET(event) => ResponseSearch endpoint handler
POST(event) => Promise<Response>AI chat endpoint handler
src/lib/docs.server.ts
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:

ComponentPropsDescription
DocsLayouttree, config, title?, titleUrl?Main layout with sidebar, nav, search, AI
DocsContentdata, configPage content with TOC, breadcrumb, footer nav
DocsPageentry, tocEnabled, breadcrumbEnabled, previousPage, nextPage, editOnGithub, lastModifiedLow-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:

PropertyTypeDescription
configDocsConfigThe config object from defineDocs()
_preloadedContentRecord<string, string>Pre-loaded markdown files from import.meta.glob. Required for serverless.

Returns:

PropertyTypeDescription
load(pathname: string) => Promise<PageData>Takes a URL pathname string, returns page data
GET({ request }) => ResponseSearch endpoint handler for GET /api/docs?query=...
POST({ request }) => Promise<Response>AI chat endpoint handler with SSE streaming
src/lib/docs.server.ts
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

ComponentImportDescription
DocsLayout@farming-labs/astro-theme/src/components/DocsLayout.astroMain layout with sidebar, search, and theme toggle
DocsContent@farming-labs/astro-theme/src/components/DocsContent.astroPage content with metadata
DocsPage@farming-labs/astro-theme/src/components/DocsPage.astroPage structure (TOC, breadcrumb, nav)
ThemeToggle@farming-labs/astro-theme/src/components/ThemeToggle.astroLight/dark toggle
SearchDialog@farming-labs/astro-theme/src/components/SearchDialog.astroSearch + AI dialog

CSS Imports

Same pattern as SvelteKit:

ImportDescription
@farming-labs/astro-theme/cssDefault (fumadocs) theme
@farming-labs/astro-theme/pixel-border/cssPixel border theme
@farming-labs/astro-theme/darksharp/cssDarksharp theme

Theme Factories

FactoryImport
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:

PropertyTypeDescription
configDocsConfigThe config object from defineDocs()
useStorageFunctionNitro's useStorage utility for accessing server assets

Returns:

A Nitro event handler that responds to GET (page loading + search) and POST (AI chat) requests.

server/api/docs.ts
import { defineDocsHandler } from "@farming-labs/nuxt/server";
import config from "../../docs.config";

export default defineDocsHandler(config, useStorage);

Nuxt uses Nitro's serverAssets to load markdown files. Configure nitro.serverAssets in nuxt.config.ts to point to your docs directory.

Nuxt Components

Imported from @farming-labs/nuxt-theme:

ComponentPropsDescription
DocsLayouttree, config, triggerComponent?Main layout with sidebar, nav, search, AI
DocsContentdata, configPage content with TOC, breadcrumb, footer nav

CSS Imports

ImportDescription
@farming-labs/nuxt-theme/fumadocs/cssDefault (fumadocs) theme

Theme Factories

FactoryImport
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.

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>
  );
}
PropTypeDefaultDescription
searchSearchProviderProps{ options: { api: "/api/docs" } }Search configuration. API defaults to the unified docs handler.
themeThemeProviderPropsTheme provider options (passed to next-themes)
childrenReactNoderequiredYour app content

suppressHydrationWarning on <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.

next.config.ts
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.

app/docs/layout.tsx
import { createDocsLayout } from "@farming-labs/theme";
import config from "@/docs.config";

const { DocsLayout } = createDocsLayout(config);

export default function Layout({ children }) {
  return <DocsLayout>{children}</DocsLayout>;
}

On this page

No Headings