Configuration
Reference every DevLab setting, default and optional content contract.
DevLab Theme reads homepage options from [extra] and component settings from structured [extra.devlab.*] tables. The fields below are the theme's configuration contract.
If you are building a new site, start with Quick start and add capabilities through Configuration recipes. Return here when you need an exact default, accepted value or edge case.
Recommended site settings
base_url = "https://example.com"
title = "DevLab"
description = "A modern Zola theme for developers, documentation and technical blogs."
author = "Your name"
default_language = "en"
compile_sass = true
build_search_index = true
generate_feeds = true
feed_filenames = ["atom.xml"]
exclude_paginated_pages_in_sitemap = "all"
[search]
index_format = "elasticlunr_javascript"
include_title = true
include_description = true
include_content = true
[markdown]
[markdown.highlighting]
light_theme = "github-light"
dark_theme = "github-dark"
DevLab uses these settings for the document language, Sass, search, syntax highlighting, feed generation and SEO fallbacks. Keep base_url accurate before publishing, because canonical and sharing URLs use it. Set default_language to the site's content language and align non-English search index filenames with it.
Theme settings
[extra]
home_layout = "default"
home_eyebrow = "Developer-first Zola theme"
home_hero_image = ""
home_hero_image_alt = ""
home_primary_action_label = "Get started"
home_primary_action_path = ""
home_secondary_action_label = "Learn more"
home_secondary_action_path = ""
[extra.devlab.brand]
logo_text = "DevLab"
footer_text = "DevLab"
show_logo_mark = false
logo_mark_path = ""
# Optional announcement; requires a version that includes the banner feature.
[extra.devlab.announcement]
show = false
key = ""
label = ""
message = ""
path = ""
dismissible = true
[extra.devlab.footer]
show = true
note = ""
links_label = "Footer links"
show_link_names = false
links = []
[extra.devlab.navigation]
links = [
{ name = "Home", path = "/" },
{ name = "Docs", path = "/docs/", kind = "docs" },
{ name = "Blog", path = "/blog/", kind = "blog" },
]
[extra.devlab.docs]
section = ""
path = ""
get_started_path = ""
show_breadcrumbs = true
show_toc = true
show_pagination = true
# Optional: omit this complete table to hide page provenance actions.
[extra.devlab.docs.page_actions]
show_last_updated = false
show_copy_link = false
edit_url = ""
report_url = ""
date_format = "%Y-%m-%d"
[extra.devlab.blog]
path = ""
date_format = "%d.%m.%Y"
show_reading_time = true
[extra.devlab.appearance]
default_mode = "system"
show_toggle = true
[extra.devlab.i18n]
rtl_languages = []
[extra.devlab.search]
enabled = true
index = ""
[extra.devlab.seo]
og_image = ""
devlab.brandcontrols the header logo text, optional mark and footer label.devlab.announcementcontrols the optional notice above the header, its destination and whether readers can dismiss it.devlab.footercontrols footer visibility and adds an optional note and project links around the centered footer label.devlab.navigation.linkscontrols desktop and mobile navigation.devlab.docsdefines the optional Docs section, public path, getting-started target, top-level navigation manifest and article navigation visibility.devlab.docs.page_actionsoptionally distributes source provenance and contribution controls across the Docs header, table of contents and article footer.devlab.blogdefines the optional public Blog path, displayed date format and keyed author registry.devlab.appearancecontrols the initial color mode and toggle visibility.devlab.i18n.rtl_languageslists active Zola language codes that should render right-to-left.devlab.search.enabledhides DevLab's search interface and scripts without preventing Zola from building an index for another consumer;indexoptionally overrides the language-aware index filename.devlab.seo.og_imagecontrols the optional Open Graph and Twitter preview image.home_layoutcontrols the homepage layout. Usedefaultfor the original constrained layout orwidefor a full-width homepage shell.home_eyebrowcontrols the short label above the homepage title.home_hero_imageandhome_hero_image_altadd a right-side hero image inwidemode.home_primary_action_*andhome_secondary_action_*control homepage hero buttons.
The header is text-only by default, so consumer sites do not inherit the DevLab mark. Set show_logo_mark = true to add a mark. With an empty logo_mark_path, the theme uses its built-in triangle; set the path to a local static asset, an absolute HTTP(S) URL or a protocol-relative URL to use your own image instead.
Set logo_text = "" for a mark-only header. The home link keeps config.title as its accessible name. If both the mark and text are disabled, the visible text safely falls back to config.title instead of leaving an empty link.
Use kind = "docs" for the link that should open the mobile docs panel and use devlab.docs.path. Use kind = "blog" for the optional blog link that should use devlab.blog.path. These special entries can omit their own path; Docs and Blog links are skipped while the corresponding configured path is empty.
Each navigation entry is a TOML table. name is required. A regular entry requires path; a special entry uses kind = "docs" or kind = "blog" and ignores its own path in favor of the configured Docs or Blog path. Other kind values have no special behavior.
Navigation name, path and kind values are strings. devlab.brand.show_logo_mark, devlab.appearance.show_toggle and other switches are booleans. devlab.appearance.default_mode accepts system, light or dark; any other value is normalized to system.
Set devlab.navigation.links = [] to omit desktop and mobile navigation entirely. Search and the color mode toggle remain independent. When a Docs link has a configured path but no section tree, it behaves as a regular mobile link instead of opening an empty Docs panel.
Regular navigation links, devlab.docs.get_started_path, homepage actions, homepage CTA links, announcement links, footer links and the devlab.card component accept local paths, absolute HTTP(S) URLs, protocol-relative URLs, mailto:, tel:, page fragments and query-only references. Local content routes are resolved through Zola so deployments under a subpath keep the correct base URL. Download channel and verification links use the same URL forms but remain artifact destinations rather than language-prefixed content routes.
Announcements
[extra.devlab.announcement] is global site configuration. The banner is available since v0.8.0. See Release announcements for the publishing workflow.
show and dismissible are booleans; key, label, message and path are strings. The banner renders only when show = true and message is non-empty. An empty path renders text without a link, and an empty label omits the prefix. Both text fields are escaped plain text, without Markdown or HTML rendering. These fields are not read from page or section front matter.
The close button requires dismissible = true and a non-empty key. A matching saved key hides the banner when those conditions hold. Changing only message, label or path does not reset dismissal; a new key identifies a new announcement. show = false removes the banner without clearing the saved key. Setting dismissible = false shows the enabled message even if its key was previously dismissed.
DevLab stores the latest dismissed key in localStorage as devlab-announcement-dismissed. This value is shared across paths and languages on the same origin, is not synchronized between devices, and can be lost when site data is cleared. Without storage, dismissal lasts for the current page. Without JavaScript, the banner and link render but closing does not work. Already open tabs apply a saved dismissal on their next load.
path uses the active-language route resolver described above. Ensure that a local destination exists in each active language; the announcement has no missing-translation fallback. The label is hidden at widths of 420px or less, and long messages are truncated on desktop or limited to two lines on mobile. The optional close script is loaded only when the banner renders with a close button.
Multilingual routes
DevLab resolves local header, mobile-menu, homepage, CTA, announcement, footer, feed and Docs routes with the active Zola language. External URLs, protocol-relative URLs, email and telephone links, fragments and query-only references are preserved unchanged.
DevLab determines document direction from an explicit language list. List every right-to-left language so the theme can set the document dir attribute and mirror its interface:
[extra.devlab.i18n]
rtl_languages = ["ar", "he"]
Codes must match the active Zola language codes: default_language and any keys configured under [languages]. Unlisted languages use ltr.
The default-language Docs configuration remains strict: a configured missing Docs root or curated navigation section stops the build. In a secondary language, an untranslated Docs root hides the Docs destinations, while untranslated curated sectors are skipped. If the translated root exists but no navigation link can be rendered, the global Docs destination remains a direct link instead of opening an empty mobile panel. This supports partial translations without silently weakening validation of the primary site. Regular navigation routes assume their translated targets exist; define suitable language-specific configuration when a destination differs or is unavailable.
Content components do not inherit the page language implicitly. For a language-aware local card link, pass the active language explicitly:
<a class="card card--link" href="https://ripetitor.codeberg.page/devlab-theme/docs/getting-started/">
<h3 class="card-title"><span class="card-title-text">Fast setup</span><span class="card-indicator" aria-hidden="true">→</span></h3>
<div class="card-body"><p>Open the translated guide.</p>
</div>
</a>
These routing and direction features do not provide a translation catalog. Configure the supported interface labels for each language and translate authored content with Zola's multilingual content model.
Set devlab.footer.show = false to omit the footer everywhere, including the compact copy in the Docs sidebar and mobile Docs panel. When it is enabled, footer link entries require name and path. An optional icon accepts github, gitlab, codeberg, matrix, zulip, telegram, discord, rss, email or link. By default a supported icon produces a compact icon link with name as its accessible label, while an omitted or unsupported icon keeps the visible text. Set devlab.footer.show_link_names = true to render every link as its icon plus the visible name and to show links_label as a heading above the group. note is plain text, and links_label also names the link group for assistive technology. Empty values preserve the copyright-only footer.
devlab.docs.section is a Zola source path relative to content/, for example docs/_index.md; it is not a public URL or a filesystem path beginning with content/. A non-empty missing section stops the build. Each item in devlab.docs.navigation uses the same source-path format and must identify a section _index.md.
When devlab.docs.navigation contains entries, its array selects and orders the top-level sectors shared by the Docs sidebar, mobile panel and root catalog. Descendants are read automatically from the selected sections. Omitting the setting or using an empty array enables automatic discovery. A section omitted from a non-empty manifest remains published and directly addressable.
devlab.docs.path and devlab.blog.path do not create routes: they must match content already generated by Zola. Use root-relative prefixes with both slashes, such as /docs/ and /blog/, so active states do not miss or overmatch routes.
The Docs article chrome is independently configurable. Set show_breadcrumbs = false to remove the path above articles, show_toc = false to hide heading navigation and avoid loading its enhancement script, or show_pagination = false to omit Previous and Next cards. Disabling the table of contents does not hide a configured Edit this page action: it remains available in the right-side action area on wide screens.
Page provenance actions
Docs pages can expose their authored update date and contribution paths without assuming GitHub, Codeberg, GitLab or another forge. Copy link appears as an icon beside the page title, Edit this page joins the desktop table of contents, and the feedback destination becomes a discussion card after the article. On narrow layouts the table of contents and its edit action are intentionally omitted. Add the optional table only when at least one action is useful:
[extra.devlab.docs.page_actions]
show_last_updated = true
show_copy_link = true
edit_url = "https://codeberg.org/acme/project/_edit/main/content/"
report_url = "https://codeberg.org/acme/project/issues/new"
date_format = "%Y-%m-%d"
show_last_updated renders a date only when the page defines Zola's native updated field. DevLab never substitutes the build time or a publication date:
+++
title = "Configuration"
updated = 2026-08-31
+++
edit_url is a repository-specific prefix. DevLab appends the page's relative_path, including a language suffix when the translated source file has one. Keep the trailing slash and include the repository's content directory in the prefix. report_url is used unchanged, so it can point to a new-issue page, an issue form or another feedback system. Both URLs should be absolute HTTP(S) destinations.
The Copy link control is progressively enhanced. It stays absent when the browser Clipboard API is unavailable and copies the current address, including an active heading fragment, when supported. A successful copy temporarily replaces the link icon with a check while the localized result is announced to assistive technology. Omit the complete page_actions table to render no provenance controls. Empty contribution URLs hide their respective links.
Set devlab.search.enabled = false when Zola should keep building an index for another integration but DevLab should render neither its search field nor its search scripts. When non-empty, devlab.search.index is a local generated JavaScript asset path and must match the filename produced by Zola; an empty value uses the active language automatically. devlab.seo.og_image supports a local static path or an absolute HTTP(S) URL.
home_hero_image accepts a local static path, an absolute HTTP(S) image URL, a protocol-relative image URL or a Zola @/ path to an asset colocated with content. Zola 0.23.4 resolves colocated assets through get_url, so a page bundle can keep its hero image beside its Markdown source.
The Downloads layout uses section-scoped front matter rather than global zola.toml settings. Its complete contract and release example are maintained in the Downloads guide.
Publishing
The theme includes the basic release-facing pieces: SEO metadata, feed autodiscovery, an SVG favicon and a custom 404 page. You usually only need to configure the site values:
base_url = "https://example.com"
title = "DevLab"
description = "Developer documentation and technical notes."
author = "Your name"
generate_feeds = true
feed_filenames = ["atom.xml"]
[extra.devlab.seo]
og_image = ""
Set og_image only when you have a real sharing image. Leave it empty to skip og:image and twitter:image.
More details are in the publishing guide.
Optional Docs
DevLab does not require content/docs/_index.md. A clean site can build without a docs section if the values under extra.devlab.docs stay empty.
To enable docs, create content/docs/_index.md:
+++
title = "Documentation"
description = "Guides and reference pages."
sort_by = "weight"
template = "docs.html"
page_template = "doc-page.html"
+++
Add nested directories with _index.md when you need documentation sectors and expandable descendant groups. Section landing pages expose one level at a time: direct pages and direct child sections become cards, while deeper entries remain on their own parent landing.
Then configure the site:
[extra.devlab.docs]
section = "docs/_index.md"
path = "/docs/"
get_started_path = "/docs/getting-started/"
navigation = [
{ section = "docs/getting-started/_index.md" },
{ section = "docs/guides/_index.md" },
{ section = "docs/reference/_index.md" },
]
[extra.devlab.navigation]
links = [
{ name = "Home", path = "/" },
{ name = "Docs", path = "/docs/", kind = "docs" },
]Optional Blog
DevLab does not require content/blog/_index.md. A clean site can build without a blog section if extra.devlab.blog.path stays empty.
To enable blog, create content/blog/_index.md:
+++
title = "Blog"
description = "Release notes and articles."
sort_by = "date"
paginate_by = 5
template = "blog.html"
page_template = "blog-page.html"
+++
Then configure the site:
[extra.devlab.blog]
path = "/blog/"
date_format = "%Y-%m-%d"
show_reading_time = true
show_toc = true
[extra.devlab.navigation]
links = [
{ name = "Home", path = "/" },
{ name = "Blog", path = "/blog/", kind = "blog" },
]
Blog posts use Zola's native date and updated fields. Add an optional release badge through page extra data:
+++
title = "Project v1.2.0"
date = 2026-07-01
updated = 2026-07-03
[extra]
release = "v1.2.0"
+++
devlab.blog.date_format accepts a date-format pattern. Use %Y-%m-%d for ISO-style dates or %m/%d/%Y for month-first dates. Omit it or leave it empty to keep the default day-first format %d.%m.%Y.
Zola calculates a reading-time estimate for every page. devlab.blog.show_reading_time displays that estimate beside the Blog date by default. Set it to false globally, or add show_reading_time = false to one post's [extra] table, when the estimate is not useful for that publication.
devlab.blog.show_toc adds a table of contents to every post that has at least two headings. On wide screens it sticks beside the article; below that width it collapses into a disclosure above the body. Set it to false to publish posts without a table of contents.
Author profiles are optional and available since v0.8.0. Register the authors taxonomy next to tags, then define recurring writers in data/authors.toml, one table per key:
# zola.toml
taxonomies = [
{ name = "tags", paginate_by = 5 },
{ name = "authors", feed = true },
]# data/authors.toml
[alex]
name = "Alex Morgan"
role = "Project maintainer"
avatar = "/images/people/alex.webp"
links = [
{ name = "Codeberg", path = "https://codeberg.org/alex", icon = "codeberg" },
]
The table name alex is the stable key used by post front matter:
[taxonomies]
tags = ["release"]
authors = ["alex"]
authors is an ordered array of strings. A profile requires name and accepts optional string fields role, avatar and path, plus a links array. Each link needs string fields name and path; icon is optional. Profile text is escaped without Markdown rendering. Local profile, avatar and icon-link paths retain the deployment prefix; profile and icon links receive the active language, while avatar paths do not.
Each credited key renders a single byline row — avatar, linked name, publication date and reading time — in the Blog list and the article header, and links to the author page at the URL generated by Zola for the taxonomy term, which combines the profile header with that writer's post archive. With feed = true the author page publishes the configured feed_filenames and links to the first one. A profile path overrides the author-page destination for that writer. An unknown key degrades to a plain linked name instead of failing the build. Empty or omitted post authors preserve the previous layout. See Blog authors for multiple writers, fallbacks, metadata and localization behavior.
The starter configuration shows five posts per page. Omit paginate_by when all posts should remain on one page. The template supports both paginated and non-paginated sections.
Homepage
The homepage always renders the hero from content/_index.md. The richer landing sections are opt-in: add home_features, home_learn, home_workflow or home_cta only when you want those sections.
+++
title = "DevLab Theme"
description = "A modern Zola theme for developers, documentation and technical blogs."
[extra]
home_layout = "wide"
home_eyebrow = "Developer-first Zola theme"
home_hero_image = ""
home_hero_image_alt = ""
home_primary_action_label = "Get started"
home_primary_action_path = "/docs/getting-started/"
home_secondary_action_label = "Learn more"
home_secondary_action_path = "#home-learn-more"
home_features = [
{ kicker = "Docs", title = "Structured documentation", description = "Build clean technical documentation with sections, pages and readable navigation." },
{ kicker = "Blog", title = "Technical writing", description = "Publish development notes, release posts, tutorials and engineering articles." },
{ kicker = "Projects", title = "Project showcase", description = "Present open-source work, internal tools and product experiments in one place." },
]
[extra.home_learn]
eyebrow = "Features"
title = "Why DevLab is different"
description = "DevLab keeps the theme small and Zola-native while giving documentation sites the navigation patterns readers expect."
cards = [
{ kicker = "Navigation", title = "One docs structure", description = "Sidebar, mobile menu, overview, breadcrumbs and prev/next links follow the same section tree." },
{ kicker = "Mobile", title = "Single site menu", description = "One mobile drawer handles global navigation and documentation links without adding a second burger menu." },
]
[extra.home_workflow]
eyebrow = "Workflow"
title = "Built for maintainable documentation"
description = "DevLab favors reusable partials, Zola section trees and plain Markdown examples."
points = [
{ title = "Shared partials", description = "Docs navigation is rendered once and reused across desktop and mobile." },
{ title = "Live examples", description = "Feature docs show rendered output and the Markdown syntax behind it." },
]
[extra.home_cta]
title = "Ready to build your docs?"
description = "Start with the getting started guide or jump straight into the documentation overview."
primary_label = "Get started"
primary_path = "/docs/getting-started/"
secondary_label = "View docs"
secondary_path = "/docs/"
+++
Use home_layout = "default" to keep the original homepage width. Use home_layout = "wide" when the homepage should span the same broad canvas as feature grids and richer landing pages.
Homepage values can live globally in config.extra or locally in the homepage front matter. The example above is valid in content/_index.md; to use the same settings globally, place its tables under [extra] in zola.toml or config.toml without the +++ front matter delimiters.
Local values in content/_index.md win over global values. home_features is replaced as one complete array. The home_learn, home_workflow and home_cta tables resolve field by field, so an omitted local field continues to inherit its global value.
home_layout accepts default or wide; any other value renders the default layout. Hero and CTA buttons render only when their path is non-empty. With no explicit global hero path, home_primary_action_path falls back to devlab.docs.get_started_path; an explicitly defined local homepage value, including an empty string, has final priority.
If the optional homepage sections are omitted, DevLab does not render placeholder feature cards or a default call to action. This keeps clean external sites from inheriting DevLab marketing copy.
An explicitly empty local array has a narrower meaning:
home_features = []hides the complete feature row.home_learn.cards = []hides the cards but keeps the learn-more heading and description.home_workflow.points = []hides the numbered points but keeps the workflow heading and description.
Once home_learn, home_workflow or home_cta is configured globally, that section remains enabled for the homepage. Keep a table in the homepage front matter instead of the global config when the entire section should be opt-in for that page.
home_features controls the feature row. Each entry supports:
kickertitle(required)description
home_learn controls the learn-more section:
eyebrowtitledescriptioncards, where each card requirestitleand optionally supportskickeranddescription
When the home_learn table exists but omits text fields, its defaults are Features, Why DevLab is different and the built-in theme description.
home_workflow controls the split workflow section:
eyebrowtitledescriptionpoints, where each point requirestitleand optionally supportsdescription
When the home_workflow table exists but omits text fields, its defaults are Workflow, Built for maintainable documentation and the built-in theme description.
home_cta controls the final homepage call to action:
titledescriptionprimary_labelprimary_pathsecondary_labelsecondary_path
When the home_cta table exists, omitted values fall back to Ready to build your docs?, the built-in description, Get started, devlab.docs.get_started_path, View docs and devlab.docs.path, respectively. An empty resolved path hides its button.
Defaults
| Setting | Default | Purpose |
|---|---|---|
devlab.brand.logo_text | config.title | Header logo text. |
devlab.brand.footer_text | config.title | Footer copyright label. |
devlab.brand.show_logo_mark | false | Whether to render a compact image or the built-in theme mark. |
devlab.brand.logo_mark_path | Empty | Optional local or remote image that replaces the built-in mark. |
devlab.announcement.show | false | Render the site-wide banner when its message is non-empty. |
devlab.announcement.key | Empty | Announcement identity; a non-empty key is required for dismissal. |
devlab.announcement.label | Empty | Optional plain-text prefix; hidden at widths of 420px or less. |
devlab.announcement.message | Empty | Plain-text announcement; an empty message hides the banner. |
devlab.announcement.path | Empty | Optional link resolved with the active language; empty renders text. |
devlab.announcement.dismissible | true | Show a close button when the banner is enabled and has a key. |
devlab.footer.show | true | Whether to render regular and compact footers. |
devlab.footer.note | Empty | Optional plain-text footer information. |
devlab.footer.links | Empty array | Optional project, social or utility links. |
devlab.footer.links_label | Footer links | Accessible name for the footer link group. |
devlab.footer.show_link_names | false | Show each link's name next to its icon and render links_label as a visible heading. |
devlab.seo.og_image | Empty | Optional Open Graph and Twitter preview image path or absolute URL. |
devlab.appearance.default_mode | system | Initial color mode before a visitor choice is saved. |
devlab.appearance.show_toggle | true | Whether to render the color mode toggle button. |
devlab.i18n.rtl_languages | Empty array | Active Zola language codes rendered right-to-left; unlisted languages use ltr. |
devlab.docs.section | Empty | Optional section used by docs sidebar, mobile docs menu and links. |
devlab.docs.path | Empty | Optional public Docs prefix and fallback target for the homepage CTA secondary action. |
devlab.docs.get_started_path | Empty | Optional fallback target for the hero primary action and homepage CTA primary action. |
devlab.docs.navigation | Not set | Optional ordered top-level section manifest for the Docs sidebar, mobile panel and root catalog; omission or an empty array enables automatic discovery. |
devlab.docs.show_breadcrumbs | true | Whether Docs articles render their breadcrumb path. |
devlab.docs.show_toc | true | Whether Docs pages and sections render heading navigation. |
devlab.docs.show_pagination | true | Whether Docs articles render Previous and Next cards. |
devlab.docs.page_actions.show_last_updated | false | Show page.updated below a Docs page when the field is present. |
devlab.docs.page_actions.show_copy_link | false | Add a progressively enhanced control that copies the current page URL. |
devlab.docs.page_actions.edit_url | Empty | Repository edit-URL prefix; page.relative_path is appended. |
devlab.docs.page_actions.report_url | Empty | Complete issue or feedback URL used without modification. |
devlab.docs.page_actions.date_format | %Y-%m-%d | Display format for the Docs updated value. |
devlab.blog.path | Empty | Optional public URL prefix for blog links and active blog states. |
devlab.blog.date_format | %d.%m.%Y | Display format for published and updated dates. |
devlab.blog.show_reading_time | true | Show Zola's reading-time estimate; a post can override it through extra.show_reading_time. |
devlab.blog.show_toc | true | Render a post table of contents: sticky beside the article on wide screens, collapsed above it on narrow ones. |
home_layout | default | Homepage layout mode. |
home_eyebrow | Developer-first Zola theme | Homepage hero eyebrow. |
home_hero_image | Empty | Optional local path or absolute URL for the wide hero image. |
home_hero_image_alt | Empty | Alt text for home_hero_image. |
home_primary_action_label | Get started | Homepage hero primary button label. |
home_primary_action_path | devlab.docs.get_started_path, then empty | Local path, absolute URL or fragment for the primary hero action. |
home_secondary_action_label | Learn more | Homepage hero secondary button label. |
home_secondary_action_path | Empty | Local path, absolute URL or fragment for the secondary hero action. |
devlab.search.enabled | true | Whether DevLab renders its search interface and loads its adapter. |
devlab.search.index | Empty | Optional generated-index filename override; empty selects search_index.<lang>.js. |
devlab.navigation.links | Home plus hidden Docs/Blog entries | Header and mobile links; special entries appear when their configured paths are non-empty. |
Interface text
Supported global interface labels live directly under [extra]:
[extra]
docs_sidebar_title = "Documentation"
docs_section_toggle_label = "Toggle section: {title}"
breadcrumb_label = "Breadcrumb"
toc_label = "On this page"
previous_label = "Previous"
next_label = "Next"
search_label = "Search"
search_placeholder = "Search..."
menu_open_label = "Open menu"
menu_label = "Menu"
menu_close_label = "Close menu"
menu_back_label = "Back to main menu"
menu_docs_label = "Open documentation navigation"| Setting | Used for |
|---|---|
docs_sidebar_title | Visible desktop Docs sidebar title and its navigation label |
docs_section_toggle_label | Accessible label for subsection disclosure buttons; keep the {title} placeholder |
breadcrumb_label | Accessible label for breadcrumb navigation |
toc_label | Visible and accessible title of the Docs table of contents |
previous_label, next_label | Docs previous and next controls |
search_label, search_placeholder | Search field accessible name and placeholder |
menu_open_label | Mobile menu button accessible name |
menu_label, menu_close_label, menu_back_label, menu_docs_label | Mobile menu title and controls |
docs_overview_label is no longer used. Docs navigation now takes landing-link text from each section's title; an older consumer configuration can leave the removed field in place without breaking a build, but it has no effect. To expose an item named Overview, create a real page or section with that title and position it with weight.
Announcements, search states, Blog metadata, Docs page actions and Copy feedback use [extra.labels]:
[extra.labels]
announcement = "Announcement"
announcement_dismiss = "Dismiss announcement"
search_start = "Start typing to search."
search_no_results = "No results found."
search_unavailable = "Search is currently unavailable."
search_results = "Search results"
search_results_count = "Results found: {count}."
published = "Published"
updated = "Updated"
post_authors = "Written by"
reading_time = "min read"
author_feed = "Posts by {author}"
page_actions = "Page actions"
last_updated = "Last updated"
copy_link = "Copy link"
link_copied = "Link copied"
copy_link_failed = "Failed"
copy_link_success = "Page link copied to clipboard."
copy_link_error = "Unable to copy page link."
edit_page = "Edit this page"
feedback_prompt = "Questions or feedback?"
report_issue = "Report an issue"
copy = "Copy"
copied = "Copied"
copy_failed = "Failed"
copy_success = "Code copied to clipboard."
copy_error = "Unable to copy code."| Setting | Used for |
|---|---|
announcement | Accessible name of the announcement region; default Announcement |
announcement_dismiss | Close button accessible label and tooltip; default Dismiss announcement |
search_start | Empty search prompt |
search_no_results | Visible message when no result matches |
search_unavailable | Visible message when the search index or library is unavailable |
search_results | Accessible results-list label |
search_results_count | Search status announcement; keep the {count} placeholder |
published, updated | Blog date labels |
post_authors | Accessible name for Blog author groups; default Written by |
author_feed | Author feed link accessible name and tooltip; keep the {author} placeholder |
reading_time | Suffix after Zola's numeric Blog reading-time estimate; default min read |
page_actions | Accessible name for the article-end Docs provenance area |
last_updated | Docs page update-date label |
copy_link, link_copied, copy_link_failed | Docs link-copy button states |
copy_link_success, copy_link_error | Docs link-copy live-region announcements |
edit_page | Docs source-edit link label |
feedback_prompt, report_issue | Docs article-end discussion prompt and action label |
copy, copied, copy_failed | Code-block button states |
copy_success, copy_error | Clipboard live-region announcements |
Every interface label value is a string. These fields are the supported label contract, not a complete translation catalog. Static strings such as the skip link, theme-mode names and generic pagination labels remain theme-owned in the current release.
Search
Search is optional. DevLab's browser adapter requires Zola's elasticlunr_javascript index format. Set it explicitly in new sites so a future Zola default or copied configuration cannot silently change the runtime contract:
build_search_index = true
[search]
index_format = "elasticlunr_javascript"
include_title = true
include_description = true
include_content = true
If build_search_index is false or devlab.search.enabled is false, the search field and search scripts are not rendered. They are also omitted when search.index_format is explicitly set to any other format, because the bundled adapter loads elasticlunr.min.js and expects the JavaScript index to define window.searchIndex. When index_format is absent, DevLab preserves compatibility with sites where the active Zola default already produces elasticlunr_javascript.
When search is enabled, DevLab selects search_index.<lang>.js from the active Zola language automatically:
build_search_index = true
[search]
index_format = "elasticlunr_javascript"
[extra.devlab.search]
index = ""
Set devlab.search.index only when the generated JavaScript file has a custom name. It changes the asset path, not the required index format.
If search is missing, confirm that build_search_index = true, devlab.search.enabled = true and that search.index_format is either elasticlunr_javascript or omitted while Zola still uses that default. If the control renders but reports that search is unavailable, check that the generated elasticlunr.min.js and search_index.<lang>.js files exist at the configured paths.
Customization
Configuration is the preferred customization layer. When a site needs palette changes, additional assets or markup overrides, keep them outside themes/devlab-theme/ and follow the Customization overview.
- Brand and colors documents logo assets, CSS loading and supported tokens.
- Template extensions documents base hooks, partial precedence and layout overrides.