diff --git a/organize/navigation.mdx b/organize/navigation.mdx
index 71ff82ecd..f7ef48cd6 100644
--- a/organize/navigation.mdx
+++ b/organize/navigation.mdx
@@ -5,6 +5,8 @@ keywords: ["navigation structure", "sidebar configuration", "page organization",
boost: 3
---
+import { NavigationBuilder } from "/snippets/navigation-builder.jsx";
+
The [navigation](/organize/settings-structure#navigation) property in `docs.json` controls the structure and information hierarchy of your documentation.
With proper navigation configuration, you can organize your content so that users can find exactly what they're looking for.
@@ -870,223 +872,9 @@ You can nest navigation elements within each other to create complex hierarchies
Each navigation element can contain one type of child element at each level of your navigation hierarchy. For example, a tab can contain anchors that contain groups, but a tab cannot contain both anchors and groups at the same level.
-
-
-```json Tabs containing anchors
-{
- "navigation": {
- "tabs": [
- {
- "tab": "Documentation",
- "anchors": [
- {
- "anchor": "Guides",
- "icon": "book-open",
- "pages": ["quickstart", "tutorial"]
- },
- {
- "anchor": "API Reference",
- "icon": "code",
- "pages": ["api/overview", "api/endpoints"]
- }
- ]
- },
- {
- "tab": "Resources",
- "groups": [
- {
- "group": "Help",
- "pages": ["support", "faq"]
- }
- ]
- }
- ]
- }
-}
-```
-
-```json Anchors containing tabs
-{
- "navigation": {
- "anchors": [
- {
- "anchor": "Documentation",
- "icon": "book-open",
- "tabs": [
- {
- "tab": "Guides",
- "pages": ["quickstart", "tutorial"]
- },
- {
- "tab": "API",
- "pages": ["api/overview", "api/endpoints"]
- }
- ]
- },
- {
- "anchor": "Community",
- "icon": "users",
- "href": "https://community.example.com"
- }
- ]
- }
-}
-```
-
-```json Products containing tabs
-{
- "navigation": {
- "products": [
- {
- "product": "Platform",
- "icon": "server",
- "tabs": [
- {
- "tab": "Documentation",
- "groups": [
- {
- "group": "Getting started",
- "pages": ["platform/quickstart"]
- }
- ]
- },
- {
- "tab": "API Reference",
- "pages": ["platform/api"]
- }
- ]
- },
- {
- "product": "Mobile SDK",
- "icon": "mobile",
- "pages": ["mobile/overview"]
- }
- ]
- }
-}
-```
-
-```json Multi-product SaaS with tabs and menu
-{
- "navigation": {
- "products": [
- {
- "product": "Platform",
- "icon": "cloud",
- "tabs": [
- {
- "tab": "Documentation",
- "menu": [
- {
- "item": "Getting Started",
- "icon": "rocket",
- "groups": [
- {
- "group": "Setup",
- "pages": ["platform/install", "platform/config"]
- },
- {
- "group": "Core Concepts",
- "pages": ["platform/concepts/auth", "platform/concepts/data"]
- }
- ]
- },
- {
- "item": "Guides",
- "icon": "book",
- "pages": ["platform/guides/deployment", "platform/guides/scaling"]
- }
- ]
- },
- {
- "tab": "API Reference",
- "groups": [
- {
- "group": "REST API",
- "pages": ["platform/api/users", "platform/api/projects"]
- },
- {
- "group": "GraphQL",
- "pages": ["platform/api/graphql/queries", "platform/api/graphql/mutations"]
- }
- ]
- }
- ]
- },
- {
- "product": "Analytics",
- "icon": "chart-bar",
- "tabs": [
- {
- "tab": "Documentation",
- "groups": [
- {
- "group": "Getting Started",
- "pages": ["analytics/quickstart", "analytics/setup"]
- }
- ]
- },
- {
- "tab": "API",
- "pages": ["analytics/api/events", "analytics/api/reports"]
- }
- ]
- }
- ]
- }
-}
-```
-
-```json Versioned docs with tabs
-{
- "navigation": {
- "versions": [
- {
- "version": "v2.0",
- "tabs": [
- {
- "tab": "Documentation",
- "groups": [
- {
- "group": "Getting Started",
- "pages": ["v2/quickstart", "v2/migration-from-v1"]
- },
- {
- "group": "Features",
- "pages": ["v2/features/auth", "v2/features/api"]
- }
- ]
- },
- {
- "tab": "API Reference",
- "pages": ["v2/api/overview", "v2/api/endpoints"]
- }
- ]
- },
- {
- "version": "v1.0",
- "tabs": [
- {
- "tab": "Documentation",
- "groups": [
- {
- "group": "Getting Started",
- "pages": ["v1/quickstart"]
- }
- ]
- },
- {
- "tab": "API Reference",
- "pages": ["v1/api/overview"]
- }
- ]
- }
- ]
- }
-}
-```
+Use this builder to assemble a hierarchy and generate the matching `docs.json` structure. Choose a root pattern, add and nest as many elements as you need at each level, rename them, then copy the result. The preview shows how each element renders and lets you click between tabs, anchors, dropdowns, and other switchers to see how visitors move through them.
-
+
## Breadcrumbs
diff --git a/snippets/navigation-builder.jsx b/snippets/navigation-builder.jsx
new file mode 100644
index 000000000..54cf630b6
--- /dev/null
+++ b/snippets/navigation-builder.jsx
@@ -0,0 +1,647 @@
+export const NavigationBuilder = () => {
+ // Mintlify evaluates snippet exports independently, so shared values must stay in this scope.
+ const DIVISIONS = {
+ languages: { singular: "language", pluralLabel: "Languages", placeholder: "en" },
+ versions: { singular: "version", pluralLabel: "Versions", placeholder: "v1" },
+ products: { singular: "product", pluralLabel: "Products", placeholder: "Platform" },
+ dropdowns: { singular: "dropdown", pluralLabel: "Dropdowns", placeholder: "Documentation" },
+ tabs: { singular: "tab", pluralLabel: "Tabs", placeholder: "Guides" },
+ anchors: { singular: "anchor", pluralLabel: "Anchors", placeholder: "API reference" },
+ menu: { singular: "item", pluralLabel: "Menu items", placeholder: "Getting started" },
+ groups: { singular: "group", pluralLabel: "Groups", placeholder: "Getting started" },
+ }
+
+ // Which child divisions are valid inside a given division, in the order buttons are shown.
+ // Mirrors the nesting rules in /organize/navigation: each level holds only one child type,
+ // and a group's own children always live in a "pages" array (which can itself nest groups).
+ const CHILD_OPTIONS = {
+ root: ["languages", "versions", "products", "dropdowns", "tabs", "anchors", "groups", "pages"],
+ languages: ["versions", "products", "dropdowns", "tabs", "anchors", "groups", "pages"],
+ versions: ["languages", "products", "dropdowns", "tabs", "anchors", "groups", "pages"],
+ products: ["languages", "versions", "dropdowns", "tabs", "anchors", "menu", "groups", "pages"],
+ dropdowns: ["languages", "versions", "products", "tabs", "anchors", "groups", "pages"],
+ tabs: ["languages", "versions", "products", "dropdowns", "anchors", "menu", "groups", "pages"],
+ anchors: ["languages", "versions", "products", "dropdowns", "tabs", "groups", "pages"],
+ menu: ["languages", "versions", "products", "dropdowns", "tabs", "anchors", "groups", "pages"],
+ groups: ["pages"],
+ }
+
+ const idRef = useRef(0)
+ const nextId = (prefix) => `${prefix}-${++idRef.current}`
+
+ const createContainer = (division) => ({
+ id: nextId(division),
+ type: "container",
+ division,
+ label: "",
+ childDivision: null,
+ children: [],
+ pages: [],
+ })
+ const createLeaf = () => ({ id: nextId("page"), type: "leaf", value: "" })
+
+ const [rootDivision, setRootDivision] = useState(null)
+ const [entries, setEntries] = useState([])
+ const [copied, setCopied] = useState(false)
+ const [previewActive, setPreviewActive] = useState({})
+ const [openDropdown, setOpenDropdown] = useState(null)
+ const [rightPanelTab, setRightPanelTab] = useState("preview")
+
+ // Divisions that render in the mock navbar, like a live site's top bar.
+ const NAVBAR_DIVISIONS = new Set(["tabs", "dropdowns", "products", "versions", "languages"])
+ // Anything else (anchors, menu) pins above the sidebar tree instead: anchors stay always
+ // visible, a menu is the active tab/product's flyout. Groups/pages become the tree itself.
+
+ const activeIndexFor = (key, length) => Math.min(previewActive[key] ?? 0, Math.max(length - 1, 0))
+ const setPreviewActiveIndex = (key, index) =>
+ setPreviewActive((prev) => ({ ...prev, [key]: index }))
+ const toggleDropdown = (key) => setOpenDropdown((prev) => (prev === key ? null : key))
+ const closeDropdown = () => setOpenDropdown(null)
+
+ useEffect(() => {
+ if (!openDropdown) return undefined
+ const closeOnPointerDown = (event) => {
+ if (
+ event.target instanceof Element &&
+ event.target.closest(`[data-preview-dropdown="${openDropdown}"]`)
+ ) {
+ return
+ }
+ setOpenDropdown(null)
+ }
+ const closeOnEscape = (event) => {
+ if (event.key === "Escape") setOpenDropdown(null)
+ }
+ document.addEventListener("pointerdown", closeOnPointerDown)
+ document.addEventListener("keydown", closeOnEscape)
+ return () => {
+ document.removeEventListener("pointerdown", closeOnPointerDown)
+ document.removeEventListener("keydown", closeOnEscape)
+ }
+ }, [openDropdown])
+
+ const mapTree = (items, id, fn) =>
+ items.map((item) => {
+ if (item.id === id) return fn(item)
+ if (item.type !== "container") return item
+ return {
+ ...item,
+ children: item.children.length ? mapTree(item.children, id, fn) : item.children,
+ pages: item.pages.length ? mapTree(item.pages, id, fn) : item.pages,
+ }
+ })
+
+ const removeTree = (items, id) =>
+ items
+ .filter((item) => item.id !== id)
+ .map((item) =>
+ item.type === "container"
+ ? { ...item, children: removeTree(item.children, id), pages: removeTree(item.pages, id) }
+ : item,
+ )
+
+ const updateLabel = (id, value) =>
+ setEntries((items) => mapTree(items, id, (item) => ({ ...item, label: value })))
+ const updatePageValue = (id, value) =>
+ setEntries((items) => mapTree(items, id, (item) => ({ ...item, value })))
+ const removeNode = (id) => setEntries((items) => removeTree(items, id))
+ const setChildDivision = (id, division) =>
+ setEntries((items) =>
+ mapTree(items, id, (item) => ({
+ ...item,
+ childDivision: division,
+ children: division !== "pages" ? [createContainer(division)] : [],
+ pages: division === "pages" ? [createLeaf()] : [],
+ })),
+ )
+ const clearChildDivision = (id) =>
+ setEntries((items) =>
+ mapTree(items, id, (item) => ({ ...item, childDivision: null, children: [], pages: [] })),
+ )
+ const addChildContainer = (id) =>
+ setEntries((items) =>
+ mapTree(items, id, (item) => ({
+ ...item,
+ children: [...item.children, createContainer(item.childDivision)],
+ })),
+ )
+ const addPageLeaf = (id) =>
+ setEntries((items) => mapTree(items, id, (item) => ({ ...item, pages: [...item.pages, createLeaf()] })))
+ const addNestedGroup = (id) =>
+ setEntries((items) =>
+ mapTree(items, id, (item) => ({ ...item, pages: [...item.pages, createContainer("groups")] })),
+ )
+
+ const chooseRootDivision = (division) => {
+ setRootDivision(division)
+ setEntries([division === "pages" ? createLeaf() : createContainer(division)])
+ }
+ const resetRoot = () => {
+ setRootDivision(null)
+ setEntries([])
+ }
+ const addRootEntry = () =>
+ setEntries((items) => [...items, rootDivision === "pages" ? createLeaf() : createContainer(rootDivision)])
+
+ const containerToJSON = (node) => {
+ const meta = DIVISIONS[node.division]
+ const json = { [meta.singular]: node.label.trim() || meta.placeholder }
+ if (node.childDivision === "pages") {
+ json.pages = node.pages.map(pageEntryToJSON)
+ } else if (node.childDivision) {
+ json[node.childDivision] = node.children.map(containerToJSON)
+ }
+ return json
+ }
+ const pageEntryToJSON = (entry) =>
+ entry.type === "leaf" ? entry.value.trim() || "page-path" : containerToJSON(entry)
+
+ const output = JSON.stringify(
+ {
+ navigation: !rootDivision
+ ? {}
+ : rootDivision === "pages"
+ ? { pages: entries.map(pageEntryToJSON) }
+ : { [rootDivision]: entries.map(containerToJSON) },
+ },
+ null,
+ 2,
+ )
+
+ const copyToClipboard = () => {
+ navigator.clipboard
+ .writeText(output)
+ .then(() => {
+ setCopied(true)
+ setTimeout(() => setCopied(false), 2000)
+ })
+ .catch((err) => {
+ console.error("Failed to copy: ", err)
+ })
+ }
+
+ const optionButtonClasses =
+ "px-2.5 py-1 text-sm rounded-lg border border-zinc-950/10 dark:border-white/10 text-zinc-950/70 dark:text-white/70 hover:bg-zinc-950/5 dark:hover:bg-white/10 transition-colors"
+ const addButtonClasses =
+ "px-2.5 py-1 text-sm rounded-lg border border-dashed border-zinc-950/20 dark:border-white/20 text-zinc-950/70 dark:text-white/70 hover:bg-zinc-950/5 dark:hover:bg-white/10 transition-colors"
+ const tagClasses =
+ "shrink-0 px-2 py-1 rounded-md font-mono text-xs bg-zinc-950/5 dark:bg-white/10 text-zinc-950/50 dark:text-white/50"
+ const inputClasses =
+ "flex-1 min-w-0 px-2 py-1 text-sm rounded-md border border-zinc-950/10 dark:border-white/10 bg-transparent"
+
+ const renderRemoveButton = (id, label) => (
+ removeNode(id)}
+ aria-label={`Remove ${label}`}
+ className="shrink-0 px-1.5 py-1 rounded-md text-zinc-950/40 dark:text-white/40 hover:text-red-500 dark:hover:text-red-400 hover:bg-red-500/10 transition-colors"
+ >
+ ×
+
+ )
+
+ const renderPageLeaf = (entry) => (
+
+ page
+ updatePageValue(entry.id, event.target.value)}
+ placeholder="quickstart"
+ aria-label="Page path"
+ className={`${inputClasses} font-mono`}
+ />
+ {renderRemoveButton(entry.id, "page")}
+
+ )
+
+ const renderContainer = (node) => {
+ const meta = DIVISIONS[node.division]
+ const childOptions = CHILD_OPTIONS[node.division] || []
+
+ return (
+
+
+ {meta.singular}
+ updateLabel(node.id, event.target.value)}
+ placeholder={meta.placeholder}
+ aria-label={`${meta.pluralLabel} label`}
+ className={inputClasses}
+ />
+ {renderRemoveButton(node.id, meta.singular)}
+
+
+ {node.childDivision ? (
+
+ {node.childDivision === "pages" ? (
+ <>
+
+ {node.pages.map((entry) =>
+ entry.type === "leaf" ? renderPageLeaf(entry) : renderContainer(entry),
+ )}
+
+
+ addPageLeaf(node.id)} className={addButtonClasses}>
+ + Add page
+
+ addNestedGroup(node.id)} className={addButtonClasses}>
+ + Nest a group
+
+
+ >
+ ) : (
+ <>
+
{node.children.map((child) => renderContainer(child))}
+
addChildContainer(node.id)}
+ className={addButtonClasses}
+ >
+ + Add another {DIVISIONS[node.childDivision].singular}
+
+ >
+ )}
+
clearChildDivision(node.id)}
+ className="text-xs text-zinc-950/40 dark:text-white/40 hover:text-zinc-950/70 dark:hover:text-white/70 transition-colors"
+ >
+ Change nesting
+
+
+ ) : (
+
+
Nest inside {meta.singular}:
+
+ {childOptions.map((option) => (
+ setChildDivision(node.id, option)}
+ className={optionButtonClasses}
+ >
+ {option === "pages" ? "Pages" : DIVISIONS[option].pluralLabel}
+
+ ))}
+
+
+ )}
+
+ )
+ }
+
+ const renderPreviewPage = (entry) => (
+
+
+ {entry.value.trim() || "page-path"}
+
+ )
+
+ const renderPreviewGroup = (node) => (
+
+
+ {node.label.trim() || DIVISIONS.groups.placeholder}
+
+ {node.childDivision === "pages" ? (
+
+ {node.pages.map((entry) => (entry.type === "leaf" ? renderPreviewPage(entry) : renderPreviewGroup(entry)))}
+
+ ) : null}
+
+ )
+
+ // Chevron icon used on real dropdown/select-style controls.
+ const renderChevron = (isOpen) => (
+
+
+
+ )
+
+ // A real tab bar: plain text links, active tab underlined, like a live site's top navigation.
+ const renderTabsRow = (nodes, key, activeIdx, meta) => (
+
+ {nodes.map((node, index) => (
+ setPreviewActiveIndex(key, index)}
+ className={`text-sm pb-2 -mb-px border-b-2 transition-colors ${
+ index === activeIdx
+ ? "border-primary text-zinc-950 dark:text-white font-medium"
+ : "border-transparent text-zinc-950/60 dark:text-white/60 hover:text-zinc-950/90 dark:hover:text-white/90"
+ }`}
+ >
+ {node.label.trim() || meta.placeholder}
+
+ ))}
+
+ )
+
+ // A real dropdown/select: a trigger button that opens a popover listing the other options.
+ const renderDropdownControl = (division, nodes, key, activeIdx, meta) => {
+ const activeNode = nodes[activeIdx]
+ const isOpen = openDropdown === key
+ const compact = division === "versions" || division === "languages"
+ return (
+
+
toggleDropdown(key)}
+ aria-haspopup="listbox"
+ aria-expanded={isOpen}
+ className={`flex items-center gap-1 rounded-md border border-zinc-950/10 dark:border-white/10 text-zinc-950/80 dark:text-white/80 hover:bg-zinc-950/5 dark:hover:bg-white/10 transition-colors ${
+ compact ? "px-2 py-1 text-xs" : "px-2.5 py-1.5 text-sm"
+ }`}
+ >
+
+ {activeNode ? activeNode.label.trim() || meta.placeholder : meta.placeholder}
+
+ {renderChevron(isOpen)}
+
+ {isOpen ? (
+
+ {nodes.map((node, index) => (
+ {
+ setPreviewActiveIndex(key, index)
+ closeDropdown()
+ }}
+ className={`block w-full text-left px-3 py-1.5 text-sm transition-colors ${
+ index === activeIdx
+ ? "text-primary dark:text-primary-light font-medium"
+ : "text-zinc-950/70 dark:text-white/70 hover:bg-zinc-950/5 dark:hover:bg-white/10"
+ }`}
+ >
+ {node.label.trim() || meta.placeholder}
+
+ ))}
+
+ ) : null}
+
+ )
+ }
+
+ const renderNavbarRow = (row) => {
+ const meta = DIVISIONS[row.division]
+ if (row.division === "tabs") return renderTabsRow(row.nodes, row.key, row.activeIdx, meta)
+ return renderDropdownControl(row.division, row.nodes, row.key, row.activeIdx, meta)
+ }
+
+ // Anchors pin above the sidebar tree as always-visible buttons (no popover, since anchors
+ // are meant to stay in view). A menu is the tab/product flyout, shown as a strip of items.
+ const renderSidebarHeaderRow = (row) => {
+ const meta = DIVISIONS[row.division]
+ if (row.division === "anchors") {
+ return (
+
+ {row.nodes.map((node, index) => (
+ setPreviewActiveIndex(row.key, index)}
+ className={`flex items-center gap-1.5 w-full px-2 py-1 text-sm rounded-md transition-colors ${
+ index === row.activeIdx
+ ? "bg-primary/10 text-primary dark:text-primary-light font-medium"
+ : "text-zinc-950/70 dark:text-white/70 hover:bg-zinc-950/5 dark:hover:bg-white/10"
+ }`}
+ >
+
+ {node.label.trim() || meta.placeholder}
+
+ ))}
+
+ )
+ }
+ return (
+
+
Menu
+
+ {row.nodes.map((node, index) => (
+ setPreviewActiveIndex(row.key, index)}
+ className={`px-2 py-1 text-xs rounded-md border transition-colors ${
+ index === row.activeIdx
+ ? "border-primary text-primary dark:text-primary-light"
+ : "border-zinc-950/15 dark:border-white/15 text-zinc-950/60 dark:text-white/60 hover:bg-zinc-950/5 dark:hover:bg-white/10"
+ }`}
+ >
+ {node.label.trim() || meta.placeholder}
+
+ ))}
+
+
+ )
+ }
+
+ // Walk down the active path, sorting each switcher level into the navbar or the sidebar
+ // header, until reaching the groups/pages tree that becomes the sidebar's main content.
+ const collectPreview = (division, nodes, key) => {
+ const empty = { navbarRows: [], sidebarHeaderRows: [], sidebarContent: null }
+ if (!division || !nodes.length) return empty
+ if (division === "pages") {
+ return { ...empty, sidebarContent: {nodes.map((entry) => renderPreviewPage(entry))}
}
+ }
+ if (division === "groups") {
+ return { ...empty, sidebarContent: {nodes.map((node) => renderPreviewGroup(node))}
}
+ }
+
+ const activeIdx = activeIndexFor(key, nodes.length)
+ const activeNode = nodes[activeIdx]
+ const row = { division, nodes, key, activeIdx }
+ const rest = activeNode
+ ? collectPreview(
+ activeNode.childDivision,
+ activeNode.childDivision === "pages" ? activeNode.pages : activeNode.children,
+ activeNode.id,
+ )
+ : empty
+
+ if (NAVBAR_DIVISIONS.has(division)) {
+ return { ...rest, navbarRows: [row, ...rest.navbarRows] }
+ }
+ return { ...rest, sidebarHeaderRows: [row, ...rest.sidebarHeaderRows] }
+ }
+
+ const preview = rootDivision
+ ? collectPreview(rootDivision, entries, "root")
+ : { navbarRows: [], sidebarHeaderRows: [], sidebarContent: null }
+
+ return (
+
+
+
+
+
Navigation builder
+
+ Add and nest as many entries as you need, then copy the generated docs.json.
+
+
+ {rootDivision && (
+
+ Reset
+
+ )}
+
+
+ {!rootDivision ? (
+
+
Choose a root pattern:
+
+ {CHILD_OPTIONS.root.map((option) => (
+ chooseRootDivision(option)}
+ className={optionButtonClasses}
+ >
+ {option === "pages" ? "Pages" : DIVISIONS[option].pluralLabel}
+
+ ))}
+
+
+ ) : (
+
+
+
+ {rootDivision}
+
+ root pattern
+
+
+
+ {entries.map((entry) => (entry.type === "leaf" ? renderPageLeaf(entry) : renderContainer(entry)))}
+
+
+
+ + Add another {rootDivision === "pages" ? "page" : DIVISIONS[rootDivision].singular}
+
+
+ )}
+
+
+
+ {/* Rounded directly (not via a clipping parent) so the dropdown popovers below aren't cut off. */}
+
+
+
+
+
+ setRightPanelTab("preview")}
+ aria-pressed={rightPanelTab === "preview"}
+ className={`px-2 py-0.5 text-xs rounded-md transition-colors ${
+ rightPanelTab === "preview"
+ ? "bg-zinc-950/10 dark:bg-white/15 text-zinc-950 dark:text-white font-medium"
+ : "text-zinc-950/50 dark:text-white/50 hover:text-zinc-950/80 dark:hover:text-white/80"
+ }`}
+ >
+ Preview
+
+ setRightPanelTab("json")}
+ aria-pressed={rightPanelTab === "json"}
+ className={`px-2 py-0.5 text-xs rounded-md transition-colors ${
+ rightPanelTab === "json"
+ ? "bg-zinc-950/10 dark:bg-white/15 text-zinc-950 dark:text-white font-medium"
+ : "text-zinc-950/50 dark:text-white/50 hover:text-zinc-950/80 dark:hover:text-white/80"
+ }`}
+ >
+ docs.json
+
+
+ {rightPanelTab === "json" && (
+
+
+
+
+
+ {copied ? "Copied" : "Copy"}
+
+ )}
+
+ {rightPanelTab === "preview" ? (
+ rootDivision ? (
+
+
+
+
+ Sitename
+
+ {preview.navbarRows.length ? (
+
+ {preview.navbarRows.map((row) => renderNavbarRow(row))}
+
+ ) : null}
+
+
+
+ {preview.sidebarHeaderRows.map((row) => renderSidebarHeaderRow(row))}
+ {preview.sidebarContent || (
+
Nothing nested here yet.
+ )}
+
+
+
+
+ ) : (
+
+ Choose a root pattern to see a preview.
+
+ )
+ ) : (
+
+ )}
+
+
+ )
+}