Skip to main content

Overview

The Page Tree API provides types and utilities for working with hierarchical navigation structures in Fumadocs. Page trees represent the sidebar navigation of your documentation.

Types

Root

The root of a page tree.
interface Root {
  $id?: string;
  name: ReactNode;
  children: Node[];
  fallback?: Root;
}
$id
string
Unique identifier for the root node
name
ReactNode
Display name of the root
children
Node[]
Child nodes of the root
fallback
Root
Alternative page tree that won’t be displayed unless explicitly opened

Node

A node in the page tree can be an Item, Separator, or Folder.
type Node = Item | Separator | Folder;

Item

Represents a page in the navigation.
interface Item {
  $id?: string;
  $ref?: { file: string };
  type: 'page';
  name: ReactNode;
  url: string;
  external?: boolean;
  description?: ReactNode;
  icon?: ReactNode;
}
type
'page'
Node type discriminator
name
ReactNode
Display name of the page
url
string
Page URL
external
boolean
Whether the link should be treated as external (uses HTML <a> tag)
description
ReactNode
Page description
icon
ReactNode
Icon element for the page

Folder

Represents a collapsible folder in the navigation.
interface Folder {
  $id?: string;
  $ref?: { metaFile?: string };
  type: 'folder';
  name: ReactNode;
  description?: ReactNode;
  root?: boolean;
  defaultOpen?: boolean;
  collapsible?: boolean;
  index?: Item;
  icon?: ReactNode;
  children: Node[];
}
type
'folder'
Node type discriminator
name
ReactNode
Display name of the folder
root
boolean
Whether this folder is a root folder (affects navigation behavior)
defaultOpen
boolean
Whether the folder should be open by default
collapsible
boolean
Whether the folder can be collapsed
index
Item
Index page for the folder
children
Node[]
Child nodes within the folder

Separator

A visual separator in the navigation.
interface Separator {
  $id?: string;
  type: 'separator';
  name?: ReactNode;
  icon?: ReactNode;
}
type
'separator'
Node type discriminator
name
ReactNode
Optional label for the separator

Utility Functions

flattenTree()

Flatten a page tree into an array of page nodes.
function flattenTree(nodes: Node[]): Item[];
nodes
Node[]
required
Array of page tree nodes to flatten
items
Item[]
Flattened array of page items
Example:
import { flattenTree } from 'fumadocs-core/page-tree';

const pages = flattenTree(tree.children);
// Returns all pages in order, including folder index pages

findNeighbour()

Get the previous and next pages for navigation.
function findNeighbour(
  tree: Root,
  url: string,
  options?: {
    separateRoot?: boolean;
  }
): {
  previous?: Item;
  next?: Item;
};
tree
Root
required
The page tree to search
url
string
required
URL of the current page
options.separateRoot
boolean
default:"true"
Whether to treat root folders as separate navigation groups
result
object
Object containing:
  • previous: Previous page in navigation order
  • next: Next page in navigation order
Example:
import { findNeighbour } from 'fumadocs-core/page-tree';

const { previous, next } = findNeighbour(
  pageTree,
  '/docs/getting-started'
);

// Use for previous/next page buttons

findPath()

Find the path to a node that matches a condition.
function findPath(
  nodes: Node[],
  matcher: (node: Node) => boolean,
  options?: {
    includeSeparator?: boolean;
  }
): Node[] | null;
nodes
Node[]
required
Array of nodes to search
matcher
(node: Node) => boolean
required
Function to match the target node
options.includeSeparator
boolean
default:"true"
Whether to include separators in the path
path
Node[] | null
Array of nodes from root to target, or null if not found
Example:
import { findPath } from 'fumadocs-core/page-tree';

const path = findPath(
  tree.children,
  (node) => node.type === 'page' && node.url === '/docs/api'
);

// Returns: [parentFolder, page]

findParent()

Find the parent of a page by URL.
function findParent(
  from: Root | Folder,
  url: string
): Root | Folder | undefined;
from
Root | Folder
required
Starting point for the search
url
string
required
URL of the page to find the parent of
parent
Root | Folder | undefined
The parent node, or undefined if not found
Example:
import { findParent } from 'fumadocs-core/page-tree';

const parent = findParent(tree, '/docs/api/reference');

findSiblings()

Get sibling nodes that share the same parent.
function findSiblings(
  treeOrTrees: Root | Record<string, Root>,
  url: string
): Node[];
treeOrTrees
Root | Record<string, Root>
required
Page tree or trees (for i18n)
url
string
required
URL of the reference page
siblings
Node[]
Array of sibling nodes (excluding the target page)
Example:
import { findSiblings } from 'fumadocs-core/page-tree';

const siblings = findSiblings(tree, '/docs/api/source');
// Returns other pages/folders in the same parent folder

getPageTreePeers()

Get sibling pages (excludes folders and separators).
function getPageTreePeers(
  treeOrTrees: Root | Record<string, Root>,
  url: string
): Item[];
treeOrTrees
Root | Record<string, Root>
required
Page tree or trees (for i18n)
url
string
required
URL of the reference page
peers
Item[]
Array of sibling page items only
Example:
import { getPageTreePeers } from 'fumadocs-core/page-tree';

const peers = getPageTreePeers(tree, '/docs/api/source');
// Returns only page items, not folders or separators

getPageTreeRoots()

Get all root folders from a page tree.
function getPageTreeRoots(
  pageTree: Root | Folder
): (Root | Folder)[];
pageTree
Root | Folder
required
Page tree to extract roots from
roots
(Root | Folder)[]
Array of root-level folders
Example:
import { getPageTreeRoots } from 'fumadocs-core/page-tree';

const roots = getPageTreeRoots(tree);
// Returns all folders marked with root: true

visit()

Perform a depth-first traversal of the page tree.
function visit<Root extends Node | Root>(
  root: Root,
  visitor: <T extends Node | Root>(
    node: T,
    parent?: Root | Folder
  ) => 'skip' | 'break' | T | void
): Root;
root
Node | Root
required
Starting node for traversal
visitor
function
required
Callback function for each node. Can return:
  • 'skip': Skip children of current node
  • 'break': Stop traversal
  • Modified node: Replace current node
  • void: Continue traversal
result
Root
The transformed tree
Example:
import { visit } from 'fumadocs-core/page-tree';

// Add a class name to all folders
const modifiedTree = visit(tree, (node) => {
  if (node.type === 'folder') {
    return {
      ...node,
      className: 'custom-folder'
    };
  }
});

// Count all pages
let pageCount = 0;
visit(tree, (node) => {
  if (node.type === 'page') pageCount++;
});

Build docs developers (and LLMs) love