DevLab Theme reads a small [extra] contract from your Zola config. These settings keep common theme customization out of templates.

base_url = "https://example.com"
title = "DevLab"
description = "A modern Zola theme for developers, documentation and technical blogs."
compile_sass = true
build_search_index = true
generate_feeds = true
feed_filenames = ["atom.xml"]

[search]
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 Sass, search, syntax highlighting, Atom feed generation and SEO fallbacks. Keep base_url accurate before publishing, because canonical and sharing URLs use it.

Theme settings

[extra]
logo_text = "DevLab"
footer_text = "DevLab"
og_image = ""
theme_default = "system"
theme_toggle = true
docs_section = ""
docs_path = ""
get_started_path = ""
blog_path = ""
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 = ""
search_index = "search_index.en.js"
nav_links = [
  { name = "Home", path = "/" },
  { name = "Docs", path = "/docs/", kind = "docs" },
  { name = "Blog", path = "/blog/", kind = "blog" },
]
  • logo_text controls the text next to the header mark. It falls back to title.
  • footer_text controls the copyright label. It falls back to title.
  • og_image controls the optional Open Graph and Twitter preview image.
  • theme_default controls the initial color mode when the visitor has not chosen one. Use system, light or dark.
  • theme_toggle controls whether the color mode toggle button is rendered.
  • docs_section points to the optional Zola section used for documentation navigation. Leave it empty when the site does not have docs.
  • docs_path is the optional public path prefix for documentation pages.
  • get_started_path controls the homepage primary call to action when docs are enabled.
  • blog_path is the optional public path prefix for blog links and active blog states.
  • home_layout controls the homepage layout. Use default for the original constrained layout or wide for a full-width homepage shell.
  • home_eyebrow controls the short label above the homepage title.
  • home_hero_image and home_hero_image_alt add a right-side hero image in wide mode.
  • home_primary_action_* and home_secondary_action_* control homepage hero buttons.
  • search_index controls the generated search index file path used by the search script.
  • nav_links controls desktop and mobile navigation.

Use kind = "docs" for the link that should open the mobile docs panel and use docs_path. Use kind = "blog" for the optional blog link that should use blog_path. Docs and blog links are skipped while their paths are empty.

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."
generate_feeds = true
feed_filenames = ["atom.xml"]

[extra]
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 docs_section, docs_path and get_started_path 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"

[extra]
nav_groups = [
  { title = "Start", pages = ["docs/getting-started.md"] },
]
+++

Then configure the site:

[extra]
docs_section = "docs/_index.md"
docs_path = "/docs/"
get_started_path = "/docs/getting-started/"

nav_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 blog_path stays empty.

To enable blog, create content/blog/_index.md:

+++
title = "Blog"
description = "Release notes and articles."
sort_by = "date"
template = "blog.html"
page_template = "blog-page.html"
+++

Then configure the site:

[extra]
blog_path = "/blog/"

nav_links = [
  { name = "Home", path = "/" },
  { name = "Blog", path = "/blog/", kind = "blog" },
]

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 grouped navigation." },
  { 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, grouped docs metadata 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. Local values in content/_index.md win over global values.

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.

home_features controls the feature row. Each entry supports:

  • kicker
  • title
  • description

home_learn controls the learn-more section:

  • eyebrow
  • title
  • description
  • cards, where each card supports kicker, title and description

home_workflow controls the split workflow section:

  • eyebrow
  • title
  • description
  • points, where each point supports title and description

home_cta controls the final homepage call to action:

  • title
  • description
  • primary_label
  • primary_path
  • secondary_label
  • secondary_path

Defaults

SettingDefaultPurpose
logo_textconfig.titleHeader logo text.
footer_textconfig.titleFooter copyright label.
og_imageEmptyOptional Open Graph and Twitter preview image path or absolute URL.
theme_defaultsystemInitial color mode before a visitor choice is saved.
theme_toggletrueWhether to render the color mode toggle button.
docs_sectionEmptyOptional section used by docs sidebar, mobile docs menu and links.
docs_pathEmptyOptional public URL prefix for docs links and active docs states.
get_started_pathEmptyOptional homepage primary call to action target.
blog_pathEmptyOptional public URL prefix for blog links and active blog states.
home_layoutdefaultHomepage layout mode.
home_eyebrowDeveloper-first Zola themeHomepage hero eyebrow.
home_hero_imageEmptyOptional right-side hero image in wide mode.
home_hero_image_altEmptyAlt text for home_hero_image.
home_primary_action_labelGet startedHomepage hero primary button label.
home_primary_action_pathEmptyHomepage hero primary button path.
home_secondary_action_labelLearn moreHomepage hero secondary button label.
home_secondary_action_pathEmptyHomepage hero secondary button path.
search_indexsearch_index.en.jsSearch index script generated by Zola.
nav_linksHome, optional Docs/BlogHeader and mobile menu links.

Search is optional. If build_search_index is false, the search field and search scripts are not rendered.

When search is enabled, keep the generated index filename aligned with extra.search_index:

build_search_index = true

[extra]
search_index = "search_index.en.js"

For non-English Zola search indexes, set search_index to the generated file name.

Search UI messages can be overridden through extra.labels:

[extra.labels]
search_start = "Start typing to search."
search_no_results = "No results found."