Utility function for merging Tailwind CSS classes.
import { cn } from 'fumadocs-ui/utils/cn';
Signature
function cn(...inputs: ClassValue[]): string
This is a re-export of twMerge from tailwind-merge for convenient class name merging.
Usage
import { cn } from 'fumadocs-ui/utils/cn';
function Button({ className, variant }) {
return (
<button
className={cn(
'px-4 py-2 rounded',
variant === 'primary' && 'bg-blue-500 text-white',
variant === 'secondary' && 'bg-gray-200 text-black',
className
)}
>
Click me
</button>
);
}
Hook for implementing copy-to-clipboard functionality with visual feedback.
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
Signature
function useCopyButton(
onCopy: () => void | Promise<void>
): [checked: boolean, onClick: MouseEventHandler]
Parameters
onCopy
() => void | Promise<void>
required
Function to execute when copy is triggered (typically writing to clipboard)
Returns
Returns a tuple:
checked (boolean) - True for 1.5s after successful copy
onClick (MouseEventHandler) - Click handler for copy button
Usage
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
import { Check, Copy } from 'lucide-react';
function CopyCodeButton({ code }: { code: string }) {
const [copied, onClick] = useCopyButton(() => {
return navigator.clipboard.writeText(code);
});
return (
<button onClick={onClick}>
{copied ? <Check /> : <Copy />}
{copied ? 'Copied!' : 'Copy'}
</button>
);
}
mergeRefs
Merge multiple React refs into a single callback ref.
import { mergeRefs } from 'fumadocs-ui/utils/merge-refs';
Signature
function mergeRefs<T>(
...refs: (React.Ref<T> | undefined)[]
): React.RefCallback<T>
Usage
import { mergeRefs } from 'fumadocs-ui/utils/merge-refs';
import { useRef, forwardRef } from 'react';
const Component = forwardRef<HTMLDivElement>((props, forwardedRef) => {
const localRef = useRef<HTMLDivElement>(null);
return (
<div
ref={mergeRefs(localRef, forwardedRef)}
{...props}
/>
);
});
isActive
Check if a URL/path is active based on current pathname.
import { isActive } from 'fumadocs-ui/utils/urls';
Signature
function isActive(
href: string,
pathname: string,
nested?: boolean
): boolean
Parameters
If true, also matches nested paths (default: false)
Usage
import { isActive } from 'fumadocs-ui/utils/urls';
import { usePathname } from 'next/navigation';
function NavLink({ href, children }) {
const pathname = usePathname();
const active = isActive(href, pathname, true);
return (
<a
href={href}
className={active ? 'font-bold' : ''}
>
{children}
</a>
);
}
normalize
Normalize URLs by removing trailing slashes.
import { normalize } from 'fumadocs-ui/utils/urls';
Signature
function normalize(urlOrPath: string): string
Usage
import { normalize } from 'fumadocs-ui/utils/urls';
normalize('/docs/'); // '/docs'
normalize('/docs'); // '/docs'
normalize('/'); // '/'
Get a flattened list of all page items in the current tree for footer navigation.
import { useFooterItems } from 'fumadocs-ui/utils/use-footer-items';
Signature
function useFooterItems(): PageTree.Item[]
Returns
Array of page tree items (pages only, excluding folders and external links)
Usage
import { useFooterItems } from 'fumadocs-ui/utils/use-footer-items';
import { usePathname } from 'next/navigation';
function PageNavigation() {
const items = useFooterItems();
const pathname = usePathname();
const currentIndex = items.findIndex(item => item.url === pathname);
const previous = items[currentIndex - 1];
const next = items[currentIndex + 1];
return (
<nav>
{previous && (
<a href={previous.url}>← {previous.name}</a>
)}
{next && (
<a href={next.url}>{next.name} →</a>
)}
</nav>
);
}
LinkItem
Component for rendering navigation links with active state.
import { LinkItem } from 'fumadocs-ui/utils/link-item';
Props
Extends ComponentProps<'a'> (excluding href)
Link configuration object
LinkItemType
Union type supporting multiple link types:
MainItemType
active
'url' | 'nested-url' | 'none'
Active state matching (default: 'url')
Where to display link (default: 'all')
IconItemType
Aria-label for accessibility
Use secondary styling (default: false)
Dropdown menu with sub-items
items
(MainItemType | CustomItemType)[]
required
Menu items
CustomItemType
Usage
import { LinkItem } from 'fumadocs-ui/utils/link-item';
import { GithubIcon } from 'lucide-react';
const links = [
{
type: 'main' as const,
url: '/docs',
text: 'Documentation',
icon: <BookIcon />
},
{
type: 'icon' as const,
url: 'https://github.com/user/repo',
text: 'GitHub',
icon: <GithubIcon />,
label: 'GitHub Repository',
external: true
}
];
function Navigation() {
return (
<nav>
{links.map((item, i) => (
<LinkItem key={i} item={item} />
))}
</nav>
);
}
useLinkItemActive
Determine if a link item is active.
import { useLinkItemActive } from 'fumadocs-ui/utils/link-item';
Signature
function useLinkItemActive(link: LinkItemType): boolean
Usage
import { useLinkItemActive } from 'fumadocs-ui/utils/link-item';
function CustomNavLink({ item }) {
const active = useLinkItemActive(item);
return (
<a
href={item.url}
data-active={active}
className="data-[active=true]:font-bold"
>
{item.text}
</a>
);
}
resolveLinkItems
Resolve link items with shortcuts (e.g., auto-adding GitHub icon).
import { resolveLinkItems } from 'fumadocs-ui/layouts/shared';
Signature
function resolveLinkItems({
links,
githubUrl
}: {
links?: LinkItemType[];
githubUrl?: string;
}): LinkItemType[]
Usage
import { resolveLinkItems } from 'fumadocs-ui/layouts/shared';
const links = resolveLinkItems({
links: [
{ type: 'main', url: '/docs', text: 'Docs' }
],
githubUrl: 'https://github.com/user/repo'
});
// Returns: [...original links, GitHub icon link]
useLinkItems
Hook to categorize links for different layout areas.
import { useLinkItems } from 'fumadocs-ui/layouts/shared';
Signature
function useLinkItems({
links,
githubUrl
}: {
links?: LinkItemType[];
githubUrl?: string;
}): {
navItems: LinkItemType[];
menuItems: LinkItemType[];
all: LinkItemType[];
}
Returns
Links for navbar (items with on: 'nav' or on: 'all')
Links for sidebar/menu (items with on: 'menu' or on: 'all')
Usage
import { useLinkItems } from 'fumadocs-ui/layouts/shared';
function Layout({ links, githubUrl }) {
const { navItems, menuItems } = useLinkItems({ links, githubUrl });
return (
<>
<nav>
{navItems.map((item, i) => (
<NavItem key={i} item={item} />
))}
</nav>
<aside>
{menuItems.map((item, i) => (
<MenuItem key={i} item={item} />
))}
</aside>
</>
);
}