Components
Pass custom React components that become available in all MDX files — no imports needed.
How It Works
When you register components in docs.config.tsx, they're merged into the MDX component map via getMDXComponents(). The merge order is:
- Built-in components — headings, code blocks, callouts,
Tab,Tabs, etc. - Your components — from
docs.config.tsx(overrides built-ins if names match)
This means you can both add new components and override existing ones.
Creating a Custom Component
1. Create the component
interface InfoCardProps {
title: string;
children: React.ReactNode;
variant?: "default" | "tip" | "warning";
}
export function InfoCard({
title,
children,
variant = "default",
}: InfoCardProps) {
const colors = {
default: "border-white/10 bg-white/[0.02]",
tip: "border-emerald-500/20 bg-emerald-500/[0.04]",
warning: "border-amber-500/20 bg-amber-500/[0.04]",
};
return (
<div className={`border p-4 my-4 ${colors[variant]}`}>
<p className="text-sm font-medium mb-1">{title}</p>
<div className="text-sm text-fd-muted-foreground">{children}</div>
</div>
);
}2. Register in config
import { defineDocs } from "@farming-labs/docs";
import { pixelBorder } from "@farming-labs/fumadocs/pixel-border";
import { InfoCard } from "./components/info-card";
export default defineDocs({
// ...theme, nav, etc.
components: {
InfoCard,
},
});3. Use in any MDX file
No import needed — just use it directly:
# Getting Started
<InfoCard title="Quick Tip" variant="tip">
You can use custom components anywhere without importing them.
</InfoCard>Overriding Built-in Components
You can replace any built-in MDX component by registering one with the same name. Your component will take precedence.
Available built-in components
The following components are available by default (from fumadocs-ui):
h1,h2,h3,h4,h5,h6— heading elementsp,a,ul,ol,li— text and list elementstable,thead,tbody,tr,th,td— table elementspre,code— code blocks and inline codeimg— imagesblockquote— blockquoteshr— horizontal rulesTab,Tabs— tabbed contentCallout— callout/admonition boxes
Example: Override the a tag
import Link from "next/link";
export function CustomLink({
href,
children,
...props
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
const isExternal = href?.startsWith("http");
if (isExternal) {
return (
<a href={href} target="_blank" rel="noopener noreferrer" {...props}>
{children} ↗
</a>
);
}
return (
<Link href={href || "#"} {...props}>
{children}
</Link>
);
}components: {
a: CustomLink,
},Now every link in your MDX files will use CustomLink — external links open in a new tab with an arrow indicator.
Example: Override blockquote
export function CustomBlockquote({
children,
}: {
children: React.ReactNode;
}) {
return (
<blockquote className="border-l-2 border-white/20 pl-4 my-4 text-fd-muted-foreground italic">
{children}
</blockquote>
);
}components: {
blockquote: CustomBlockquote,
},Example: Override pre (code blocks)
export function CustomPre({
children,
...props
}: React.HTMLAttributes<HTMLPreElement>) {
return (
<div className="relative group my-4">
<pre
className="border border-white/10 bg-black p-4 overflow-x-auto"
{...props}
>
{children}
</pre>
</div>
);
}components: {
pre: CustomPre,
},Multiple Components
Register as many components as you need:
import { InfoCard } from "./components/info-card";
import { CustomLink } from "./components/custom-link";
import { VideoEmbed } from "./components/video-embed";
import { ApiReference } from "./components/api-reference";
export default defineDocs({
// ...
components: {
// Custom components
InfoCard,
VideoEmbed,
ApiReference,
// Built-in overrides
a: CustomLink,
},
});Then use them all across your MDX without imports:
# API Overview
<InfoCard title="Authentication Required" variant="warning">
All endpoints require a valid API key.
</InfoCard>
<ApiReference endpoint="/api/users" method="GET" />
<VideoEmbed url="https://youtube.com/watch?v=..." />Component Props
Components receive their props as defined in your implementation. The only requirement is that they must be valid React components (function or class).
For built-in overrides, your component should accept the same props as the original element (e.g., React.AnchorHTMLAttributes for a, React.HTMLAttributes<HTMLPreElement> for pre).
For custom components, define whatever props interface you need.