Documentation
Configuration
DataLeaf keeps configuration deliberately small. Unset optional parameters fall back to simple defaults.
Content sections
#DataLeaf uses Hugo’s mainSections for the home page, archives, and adjacent-article navigation:
mainSections = ["blog", "notes"]This is a root configuration setting, not a theme parameter. If omitted, Hugo chooses the top-level section with the most pages. The example site explicitly selects posts; your site can use any section names. Home and taxonomy introductions come from their _index.md content. Empty collections remain usable, and undated pages omit date metadata in the interface.
Front page
#The home page is an editorial front page built from your content; it needs no extra configuration:
- Introduction — the home page’s
titlefromcontent/_index.mdas the page heading, with the sitedescriptionand the home page’s own content beside it on wide screens. Give the home page a title that states what the site is about rather than repeating the site title, which the masthead already shows. - Latest writing — the newest page of your main sections is featured: its listing summary as the dek, an excerpt of the article when it has a
description, its date, reading time, and tags. The next entries sit beside it on wide screens, each with a date, title, and summary. - Topics — the most used terms of the
tagstaxonomy, or of the site’s first taxonomy when there are no tags, linked to their pages. The band is titled with the taxonomy page’s title and omitted when there are no published term pages.
The page size follows pagination: the first page features one entry and lists the rest; later pages list entries only. On small screens the front page is a single column.
Theme parameters
#Description
#[params]
description = "Technical notes and long-form articles."Used on the front page as the introduction’s lede. Default: empty.
Theme selector
#[params]
themeToggle = trueWhen enabled, DataLeaf shows a System / Light / Dark selector. Default: false.
Without JavaScript, the theme still follows the operating system’s preferred color scheme.
Fonts
#[params.fonts]
bundled = falseDataLeaf bundles Source Serif 4, IBM Plex Sans, IBM Plex Mono, and STIX Two Math and serves them from your site; no font service is contacted. With bundled = false, no font files or @font-face rules are published and the theme uses installed fonts. Default: true. See Design tokens for the fallback stacks and for using other fonts.
Author
#[params.author]
name = "Ada Lovelace"
url = "https://example.com/about/"name is optional and controls the article byline and HTML author metadata. url is optional; when supplied, the byline becomes a link.
Custom CSS
#[params]
customCSS = ["css/custom.css"]Paths without a leading slash are resolved relative to the configured base URL, including its subpath. Put the corresponding file under your site’s static/ directory, for example static/css/custom.css.
Default: no additional stylesheets.
Mathematics
#The default engine is Hugo’s build-time renderer:
[params.math]
engine = "hugo"To use a client-side renderer instead, choose another engine name and provide the assets:
[params.math]
engine = "external"
stylesheet = "https://cdn.example.com/math.css"
script = "https://cdn.example.com/math.js"DataLeaf only loads these assets on pages that actually contain passthrough math. You must provide and initialize the renderer yourself. Prefer self-hosted assets such as js/math.js; external services receive visitor requests. DataLeaf does not load third-party assets by default.
Menus
#The header is a publication masthead. The site title links to the home page. Below it, one bar holds the primary navigation and, smaller and quieter, the site tools.
DataLeaf reads the primary navigation from Hugo’s main menu. Keep it to a few reader destinations; the site title already links home:
[[menus.main]]
name = "Writing"
pageRef = "/posts"
weight = 10
[[menus.main]]
name = "Topics"
pageRef = "/tags"
weight = 20
[[menus.main]]
name = "Archive"
pageRef = "/archives"
weight = 30The theme adds the site tools itself, so they do not belong in menus.main:
- Search links to the page with
layout: "search"when static search is enabled; - languages link to each translation of the current page on multilingual sites;
- the theme selector appears when
themeToggleis enabled.
Use Hugo’s parent and identifier settings for nested menu entries. Only the current item receives aria-current="page"; its ancestors share the active styling and receive aria-current="true". Active items are underlined as well as tinted, so the state does not depend on color. Omitting menus.main removes the primary navigation; the site tools remain. Prefer pageRef for content links so Hugo resolves language prefixes and configured permalinks.
Taxonomies
#The standard setup is:
[taxonomies]
tag = "tags"
category = "categories"DataLeaf supplies taxonomy index and term layouts and links post tags from articles and list entries. A taxonomy page is an alphabetical index of its terms, by their displayed titles, set in columns with the number of pages for each. A term page lists its pages like a section, under a kicker that links back to the taxonomy.
Custom taxonomy names use the same index and term layouts. Hugo’s disableKinds = ["taxonomy", "term"] disables taxonomy pages and their article links; there is no mandatory tags or categories menu.
Archive page
#The archive lists the pages of your mainSections by year. Create it as content/archives/_index.md, or under any other path, with the archives layout:
---
title: "Archive"
layout: "archives"
---Add it to menus.main to link it from the header.
Contents page
#A documentation or reference section can list its pages as numbered contents on one page instead of paginated, dated entries. Select the contents layout in the section’s _index.md:
---
title: "Documentation"
layout: "contents"
---Pages follow the section’s order: by weight, then date and title. Each entry shows its summary and reading time; a subsection shows how many entries it holds.
Pagination
#[pagination]
pagerSize = 10The home page and list pages use Hugo’s paginator. On the home page, the first entry of the first page is featured. Pages with the contents layout are not paginated.
Syntax highlighting
#DataLeaf’s fenced-code render hook uses class-based Chroma output so syntax colors work in both color schemes without extra site configuration. For other Hugo highlighting functions and the built-in highlight shortcode, also configure:
[markup]
[markup.highlight]
noClasses = falseOther highlighting options, such as line numbers, remain configurable through Hugo.
See Technical content for code, math, statements, tables, and figures.
Static search
#Search is optional and fully static.
Enable it with:
[params.search]
enabled = true
minQueryLength = 2
maxResults = 20
[outputFormats.SearchIndex]
mediaType = "application/json"
baseName = "search-index"
isPlainText = true
notAlternative = true
[outputs]
home = ["HTML", "SearchIndex"]Then add a search page:
---
title: "Search"
layout: "search"
searchExclude: true
---The header links to it as a site tool, so it does not need a menu entry.
Both the parameter and output configuration above are required. With this configuration, DataLeaf generates a search-index.json home output containing each page’s title, URL, plain-text excerpt, tags, categories, translated section title, and date. Instead of the full article text, the index stores the page’s distinct words. This keeps long pages compact, because vocabulary grows far more slowly than text. The search page fetches the index using Hugo’s generated relative permalink, so it works under root domains and subpath deployments such as GitLab Pages.
How matching works
#- Matching ignores case and accents: “tecnica”, “Técnica”, and “TÉCNICA” find the same pages.
- Every word in the query must match. Words may match whole or by their beginning, so “hug” finds “Hugo”. A fragment of three or more characters may also match inside a word, so “script” finds “JavaScript”.
- Ranking favors matches in the title, then tags, categories, the excerpt, and finally the body. Exact words outrank prefixes, and prefixes outrank matches inside words. Ties are ordered by title, then URL.
maxResultslimits how many results are shown. The status message still reports the total and says when the list is truncated. Invalid limits fall back to the defaults.- Queries shorter than
minQueryLength, or containing no letters or digits, show the minimum-length hint instead of results. - Results update as you type. Enter or the Search button searches immediately without reloading the page. The query is kept in the address as
?q=, so a search can be shared, reloaded, or restored with the back button. - Index entries are rendered as text. Entries without a title or with a non-HTTP(S) URL are ignored, and a missing or malformed index shows a “temporarily unavailable” message.
Set searchExclude: true in page front matter to omit an individual page from the index.
Only pages with a published HTML output are indexed. JSON-only pages and pages with build.render: never are excluded. Reordering page outputs does not change search targets. The index follows the current language, and its URL is obtained from Hugo’s SearchIndex output, including a customized baseName or path. Include RSS in outputs.home as well if you want a home feed. Configured alternative outputs receive discovery links in the HTML head; SearchIndex is excluded by notAlternative.
The search implementation uses vanilla JavaScript and loads only on pages with layout = "search". With enabled = false, no search script or input is shown and a configured index is empty. Remove SearchIndex from outputs.home to omit the JSON file entirely. Search needs JavaScript; a localized browse link remains available without it.
Article table of contents and heading links
#Long pages can expose Hugo’s generated table of contents.
Global configuration:
[params.article]
toc = true
headingAnchors = true
copyHeadingLinks = true
[markup.tableOfContents]
startLevel = 2
endLevel = 4
ordered = falsetoc controls the article table of contents. On wide screens it sits in the article’s side rail and stays in view while reading; on smaller screens it follows the article header, before the text. An individual page can override it in front matter:
---
toc: false
---When headingAnchors is enabled, Markdown headings from level 2 onward show a permalink based on Hugo’s own stable heading anchor. These links work as ordinary fragment links without JavaScript. The permalink is rendered beside the heading rather than inside it, so the heading’s accessible name is only its text, and the link is labeled “Permalink to …”.
When copyHeadingLinks is also enabled and the browser supports the Clipboard API, activating a heading permalink copies the absolute URL, updates the fragment in the address bar, and announces the copy through a polite live region. If copying is unavailable, the permalink keeps its normal anchor behavior.
The TOC levels are controlled by Hugo’s standard markup.tableOfContents configuration.