Skip to main content
Login
Sign up

Tree

The built-in tree tag — a nested file/folder explorer with collapsible folders, indentation guides, and per-file source you can open in a modal. Usage, options, and live examples.

A built-in tag that renders a nested file/folder explorer — in the spirit of Fern’s <Files> and Mintlify’s <Tree>: collapsible folders with indentation guide lines and language-aware icons, full keyboard navigation, and defaultOpen, href, comment, and highlighted options. It goes one step further: give a {% file %} a body of source code and the file becomes clickable, opening that code centered in a modal as a standard fenced code block (so the site’s syntax highlighting styles it). A file with an empty body is a plain, non-clickable leaf.

Usage

Wrap the structure in {% tree %} … {% endTree %}, nest {% folder name="…" %} … {% endFolder %} and {% file name="…" %} … {% endFile %} inside it, and put a file’s source between its tags:

{% tree label="Project files" %}
{% folder name="src" defaultOpen %}
{% file name="app.py" %}
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {"status": "ok"}
{% endFile %}
{% folder name="utils" %}
{% file name="text.py" %}
def slugify(value: str) -> str:
    return value.strip().lower().replace(" ", "-")
{% endFile %}
{% endFolder %}
{% endFolder %}
{% file name="package.json" %}
{
  "name": "demo",
  "scripts": { "build": "vark build" }
}
{% endFile %}
{% file name="README.md" comment="start here" %}{% endFile %}
{% endTree %}

renders, live:

src
app.py
package.json
README.md# start here

Click a file with a body — app.py, text.py, package.json — to open its source in a modal (with a copy button). README.md has no body, so it’s a plain leaf with a trailing comment. Folders collapse on click; the icon tracks the file extension. The whole tree is keyboard-navigable: focus it and use the arrow keys (↑ ↓ to move, → ← to expand/collapse, Enter to open a file), Home/End, etc.

A href turns a name into a link (a bodyless file with href is a plain link); a comment adds a trailing note in muted monospace (auto-prefixed with #); and highlighted tints a row to draw the eye:

{% tree %}
{% folder name="docs" defaultOpen comment="published to the site" %}
{% file name="index.md" href="/" %}{% endFile %}
{% file name="config.yaml" highlighted %}
title: My Site
theme:
  accent: indigo
{% endFile %}
{% endFolder %}
{% endTree %}
docs# published to the site
config.yaml

Options

Tag Attribute Effect
{% tree %} label="…" Accessible name for the tree (sets aria-label); use it when a page has more than one.
{% folder %} name="…" Folder label (required).
defaultOpen Start expanded instead of collapsed.
openable=false Static folder — always open, no chevron, no toggle.
href="…" Link the folder name (shown underlined).
comment="…" Trailing muted-monospace note, auto-prefixed with #.
highlighted Tint the row with the accent color.
{% file %} name="…" File name (required); sets the icon and the code language.
(body) Source code → opens in a modal on click. An empty body is a plain leaf.
lang="…" Override the language guessed from the extension (e.g. lang="bash").
href="…" Link a bodyless file (ignored when the file has a code body — that opens the modal).
comment="…", highlighted As for folders.

The file body is captured verbatim and shown as a fenced code block — the template engine does not execute inside it, so ordinary source code (even code that looks like template syntax) is safe as-is. A balanced {% file %} … {% endFile %} pair — e.g. when documenting the tree’s own syntax — is fine too: the close-tag scanner depth-counts, so it pairs them. The only case that needs a raw block is a lone, unbalanced end-tag (a {% endFile %}, {% endFolder %}, or {% endTree %} with no matching opener), which would otherwise close the block early — the engine runs before Markdown.

Last modified

Was this page helpful?