Reach for a template only when configuration and CSS cannot express the change. Zola loads a site template before a theme template with the same path, so the site can extend a block or replace one partial without editing the installed DevLab copy.

Choose the maintenance boundary

The site needs...Use...What the site owns
Metadata, CSS, JavaScript or an integrationA base-template hookOnly the added markup
Different content inside the built-in footerpartials/footer-content.htmlFooter content, not its layout
A completely different shared componentOne matching partialThat component and its behavior
A different structure for one page typeOne layout blockThat block's markup

Prefer extension over copying

Extend the namespaced DevLab template and override one block. A complete copied template may build successfully while silently missing accessibility or navigation improvements from a later release.

Extend the base template

Create templates/base.html in the site. Keep only the blocks the project actually uses:

{% extends "devlab-theme/templates/base.html" %}

{% block head_extra %}
<meta name="application-name" content="Acme Docs">
{% endblock head_extra %}

{% block extra_styles %}
<link rel="stylesheet" href="{{ get_url(path='custom.css') }}">
{% endblock extra_styles %}

{% block extra_scripts %}
<script src="{{ get_url(path='js/custom.js') }}"></script>
{% endblock extra_scripts %}

Put referenced files under the site's static/ directory. get_url keeps their URLs correct when the site is deployed below a path prefix.

The base template exposes these focused hooks:

BlockPositionGood fit
head_extraAfter DevLab metadata and main.cssVerification tags, metadata and preload hints
extra_stylesLast in the page headSite stylesheets
body_startAfter the skip link, before the site shellEnvironment banners and accessibility integrations
extra_scriptsAfter DevLab scriptsSite JavaScript that uses rendered theme markup
body_endLast before </body>Integrations that must be the final body markup

The structural title, main_class and content blocks belong to page layouts. Override them in a specific layout instead of changing the site-wide base wrapper.

Override one partial

A site partial replaces the theme partial at the same relative path:

your-site/
└── templates/
    └── partials/
        └── footer-content.html

footer-content.html is the smallest useful footer override. DevLab continues to own the separator, centered layout and compact Docs variant while the site controls the inner markup. The partial receives:

  • footer_text and footer_year;
  • footer_note;
  • footer_links and footer_links_label;
  • footer_compact for the Docs presentation.

Reuse site-footer-note, site-footer-copyright, site-footer-links, site-footer-link and site-footer-link-icon when you want to keep the built-in responsive styling.

You can also replace partials/header.html or partials/footer.html, but that is a complete component replacement. The site then owns its keyboard behavior, accessible names, responsive states and every runtime hook the component needs. A full footer override must handle footer_compact, because the same partial appears below regular pages, in the desktop Docs sidebar and in the mobile Docs panel.

Header and navigation overrides must retain the data-* hooks used by site-menu.js, search.js and theme.js, or deliberately provide equivalent behavior. DevLab's CSS classes and JavaScript DOM hooks are implementation details in v0.8.0, not a stable extension API.

Override one layout block

Suppose ordinary content pages need a project-specific header but should keep every other DevLab block. Create templates/page.html:

{% extends "devlab-theme/templates/page.html" %}

{% block content %}
<article class="content custom-page">
  <header class="page-header">
    <p class="hero-eyebrow">Acme</p>
    <h1>{{ page.title }}</h1>
  </header>

  {{ page.content | safe }}
</article>
{% endblock content %}

The same pattern works with index.html, section.html, docs.html, doc-page.html, blog.html, blog-page.html and downloads.html. Extending the namespaced file keeps every untouched block connected to the installed theme.

Zola documents namespaced inheritance and site-template priority in Customizing a theme.

Validate the override

Run the native checks after every template change:

zola check
zola build

Then review only the surfaces the override can affect:

  • desktop and mobile widths;
  • light and dark modes;
  • keyboard focus and accessible names;
  • the mobile menu when header or navigation markup changed;
  • compact Docs presentation when footer markup changed;
  • stored Docs groups, search results and active navigation when their hooks changed.

Upgrade without surprises

Before selecting a new DevLab tag, list the site's template overrides. For each one, compare the matching file or parent block in the new release. A valid build proves that Tera can render the page; it does not prove that a copied component includes newly added accessible markup or runtime hooks.

After the comparison, run the checks again and repeat the focused manual review. If an override has grown difficult to compare, move any styling back to CSS and any behavior back to configuration, then keep only the structural markup that still requires a template.