Skip to main content

Template System

View SourceEdit this page (external link)

This article introduces Hugo's template lookup mechanism, which determines which template applies to each page. Three core concepts drive this mechanism: page kind, page type, and the layout manually specified in front matter. Once you understand these core concepts, we'll walk through the full template classification, then explain the complete lookup order. Two examples at the end will tie everything together.

Page Kind Link to this heading

Page Kind maps directly onto the concepts covered in Content Structure:

  • home: the site's home page
  • page: a single content page, formerly called single
  • section: a section's list page, formerly called list
  • taxonomy: the list page for every term under a given taxonomy, for example /tags/
  • term: the page for a single term under a taxonomy

Here's how the content/ directory structure maps to each page kind:

content/
content
├── _index.md       # Maps to layouts/home.html
├── docs
│   ├── _index.md   # Maps to layouts/section.html
│   └── p1.md       # Maps to layouts/page.html
│
└── tags
    ├── _index.md   # Maps to layouts/taxonomy.html
    └── my-tag.md   # Maps to layouts/term.html

Page Type Link to this heading

After Hugo determines the page kind, it determines the page type, which decides which set of templates to use within that kind.

For example, pages of the same page kind under content/posts/ and content/movies/ can use different templates through different types:

layouts/
layouts/
├── movies/
│   ├── page.html      # page template for movies
│   └── section.html   # section template for movies
├── home.html
├── section.html
├── taxonomy.html
├── term.html
└── page.html

Type defaults to the name of the directory containing the content. For example, content/movies/p1/index.md defaults to type movies. You can also set it explicitly through the type field in front matter:

content/movies/p1/index.md
---
title: 'My Post'
type: 'posts'
---

Layout Link to this heading

Beyond kind and type, you can specify a template filename directly through the layout field in front matter:

---
title: 'My Post'
layout: 'custom'
---

This maps to:

layouts/
├── custom.html    # set by layout: custom
├── home.html
├── section.html
├── taxonomy.html
├── term.html
└── page.html

The layout field takes precedence over kind- or type-based resolution.

Tip

A simple way to think about the three:

  1. Page kind identifies the page type, such as a tag list or a regular post.
  2. Page type further narrows this down, letting different types use different templates.
  3. Layout is set manually in front matter, suited to standalone pages like about or privacy.

Template Categories Link to this heading

This section introduces the template categories under the layouts directory, including important content such as base templates and page templates.

layouts Directory Overview Link to this heading

The layouts/ directory holds the templates that render your site. Here's the overall structure:

layouts directory overview
layouts/
├── baseof.html     # Base template
├── page.html       # kind: page
├── home.html       # kind: home
├── section.html    # kind: section
├── taxonomy.html   # kind: taxonomy
├── term.html       # kind: term
├── single.html     # Fallback for page
├── list.html       # Fallback for home / section / taxonomy / term
├── all.html        # Final fallback for every page template
├── _markup/        # Configures how Markdown elements render (render hooks)
├── _shortcodes/    # Called from content pages, not a page template
└── _partials/      # Reusable fragments, not a page template

This section covers everything inside layouts/.

Base Templates Link to this heading

A base template is baseof.html, the shared outer structure for all page templates. It typically defines common elements such as html, head, and body, keeping the site consistent and easier to maintain.

A base template typically calls the block (external link) function, which Hugo replaces with the matching section from a page template when the following conditions are met:

  • The page template contains a define action
  • The page template contains no content that would render directly

If these conditions aren't met, Hugo ignores the base template and renders the page template on its own. Examples of correct and incorrect usage follow:

layouts/baseof.html
<!DOCTYPE html>
<html lang="{{ site.Language.Locale }}">
<body>
  <main>
    {{ block "main" . }}
      This content gets replaced by the matching
      define "main" action in the page template
      that applies this base template.
    {{ end }}
  </main>
</body>
</html>
layouts/home.html
{{ define "main" }}
  This content replaces the block "main" action
  in the base template.
  {{ template "inlineTemplate" }}
{{ end }}

{{/* Only whitespace and comments are allowed outside define actions */}}

{{ define "inlineTemplate" }}
  Inline define is allowed here because it doesn't render directly.
{{ end }}

Page Templates Link to this heading

Page templates map directly to each page kind:

  • layouts/home.html
  • layouts/page.html
  • layouts/section.html
  • layouts/taxonomy.html
  • layouts/term.html

Along with these fallbacks:

  • layouts/single.html is the fallback for page.
  • layouts/list.html is the fallback for home, section, taxonomy, and term.
  • layouts/all.html is the fallback for every page template.

Other Templates Link to this heading

Beyond page templates, Hugo supports the following specialized template types:

Render Hooks Link to this heading

Render hooks let you customize how Hugo converts specific Markdown elements to HTML, such as customizing the output of images, links, or headings. Render hooks live under _markup/ and support the following types:

The _partials Directory Link to this heading

layouts/_partials holds reusable template fragments, invoked with the partial function. To render layouts/_partials/head.html:

{{ partial "head.html" . }}

The first argument is the template name, and the second argument . is the context passed in.

The _shortcodes Directory Link to this heading

layouts/_shortcodes holds templates called from Markdown content, used to insert structured components such as embedded audio, video, or other HTML elements.

View Link to this heading

A view (external link) template automatically applies a different template depending on the page, rather than always rendering through one fixed template the way partial does.

View templates render through the .Render method, and follow the same lookup order as other Hugo templates.

Lookup Order Link to this heading

The basic priority order is as follows:

  1. A layout set manually in front matter
  2. A dedicated template for the page kind (home, section, taxonomy, term, page)
  3. The single fallback for page, or the list fallback for home / section / taxonomy / term
  4. all.html, the final fallback

This covers only the basic concepts. Hugo's actual lookup rules go further: filenames can chain multiple conditions with ., and the directory depth of a template also affects priority. Both are covered below.

Chaining Conditions with . Link to this heading

A filename separated by . lets a single template filter on multiple conditions at once, such as language, output format, or page kind. Separate each condition with . in the filename:

# Section page, German only
section.de.html

# Home page JSON output, German, v2.0.0 only
home.de._version_v2.0.0_.json

The available conditions are:

As of v0.161.0 (external link), you can also mark these more explicitly, for example home._outputformat_rss_.xml, section._language_de_.html, or baseof._kind_section_._language_de_.html.

Path Distance Link to this heading

The closer a template's path is to the content being rendered, the higher its priority, and path distance takes precedence over filename conditions. Hugo only compares filename conditions when path distance is equal.

Support Overview Link to this heading

Support for the advanced lookup order varies by template type. The table below summarizes this:

Page KindOutput FormatLanguagePath Distance
Base templateYesYesYesYes
Page templateYesYesYesYes
Render hook❌YesYesYes
Shortcode❌YesYes❌
Partial❌❌❌❌
View❌❌❌Not applicable

Complete Site Example Link to this heading

The following two examples show how every template type covered in this article comes together in a real project.

Simple Site Link to this heading

The most basic site needs only one base template, plus one page template per page kind.

layouts/
├── baseof.html
├── home.html
├── page.html
├── section.html
├── taxonomy.html
├── term.html
├── _markup/
│   └── render-image.html
├── _partials/
│   ├── header.html
│   └── footer.html
└── _shortcodes/
    └── audio.html

Complex Site Link to this heading

A larger site may need dedicated templates and render hooks for specific types or sections, and use view templates to render the same content differently depending on context.

layouts/
├── baseof.html
├── home.html
├── page.html
├── section.html
├── taxonomy.html
├── term.html
├── all.html
├── custom.html
├── movies/
│   ├── page.html
│   ├── _views/
│   │   └── card.html
│   ├── section.html
│   ├── _markup/
│   │   └── render-image.html
│   └── action/
│       ├── page.html
│       └── _markup/
│           └── render-image.html
├── films/
│   ├── _views/
│   │   └── card.html
│   ├── page.html
│   └── section.html
├── _markup/
│   └── render-image.html
├── _partials/
│   ├── header.html
│   └── footer.html
└── _shortcodes/
    └── audio.html

Accessibility settings

Font size