Hi there,

this small post will briefly cover how HUGO templates lookup selects your layouts to render Markdown content.

Structure of a Hugo Site Link to heading

The most simple case is when you define a layout inside your .md content file or front matter:

---
title: "Skills"
layout: "skills"
---

HUGO engine will search for skills.html layout inside /layouts directory and renders your content based on the data.

index.html is a template for an entry point of your webpage.

List pages Link to heading

Section and taxonomies are list pages. They are rendered based on _index.md front matter properties in the metadata file. So if you didn’t specify a layout in the example of content/blog/_index.md front meta as in the example above for the Skills page then layouts/_default/list.html is used instead by a Hugo engine to render all pages in the /blog folder.

So you may define different layouts or use base default ones for you pages or represent the same folder structure for layout templates as your content have to override default behaviour instead without the need of front matter.

  • Section: blog and projects are sections because they are top-level directories in content/.
  • Taxonomy: Tags or categories assigned in front matter, like tags: ["hugo", "static-site"], are taxonomies.

Single pages Link to heading

If you place a file (e.g., index.md) directly in the root of the /content/ directory, it is treated as a single page, and Hugo uses:

  • layouts/_default/single.html (default fallback for single pages).
  • If a content file with front matter resides in a subdirectory of /content/, Hugo considers it part of a section, and it uses the following template order: layouts/{section}/single.html (if defined for that section), layouts/_default/single.html - fallback.

So here are a diagram to summarize the cases:

content/
├── index.html <- /layout/index.html
│── skills.md <- /layouts/skills.html if layout: set "skills"
├── blog/
│   ├── _index.md <- /blog/list.html or _default/list.html if no layout: set
│   ├── post1.md
│   ├── post2.md
├── projects/
│   ├── _index.md  <- /projects/list.html or _default/list.html if no layout: set
│   ├── project1.md
│   ├── project2.md
├── about/
│   ├── index.md <- single.html if no layout: set
layouts/
|── _default/
|   ├── baseof.html
|   ├── single.html
|   ├── list.html
|   |-- nutrition-data.html <- some custom layout
|-- projects/
|   |-- list.html
|── partials/
|   ├── footer.html
│── index.html
│── skills.html  <- some custom layout, no difference with the _default

Baseof layout and partials Link to heading

HUGO engine alows amazing composition of layouts for e.g. you may define a baseof.html layout which will a common for all pages something like this:

<html>
<head>
  <link rel="icon" type="image/png" sizes="16x16" href="{{ "favicon-16x16.png" | relURL }}">
  {{ if .IsHome }}
  <title>{{ .Site.Title }}</title>
  <meta name="description" content="{{ .Site.Params.homeDescription }}">
  {{ else if eq .Type "nutrition-data" }}
  <title>Example title {{ .Title }}</title>
  {{ else }}
  <title>{{ .Title }}</title>
  <meta name="description" content="{{ if .Params.meta }}{{ .Params.meta }}{{ else }}{{ .Params.Title }} - custom page meta {{ end }}">
  <meta name="robots" content="index, follow">
  {{ end }}
  {{ partial "head-styles.html" . }}
</head>

<body>
  <header data-pagefind-ignore>{{ partial "navbar.html" . }}</header>
  {{ partial "pagefind-search.html" . }}
  <main data-pagefind-body>{{ block "main" . }}{{ end }}</main>
  {{ partial "scroll-up-button.html" . }}
  </br>
  <footer>{{ partial "footer.html" . }}</footer>
</body>

</html>

Notice how cool the conditional rendering per a page based on different frontend matters like e.g. type of a layout, literally nutrition-data.html is a custom layout.

Inside /layouts/partials folder you may add any custom reusable html templates to include in different pages for e.g. as the footer.html in the example

Notice {{ block "main" . }}{{ end }} will render next layout content for e.g. list.html, single.html

Some important difference about index.md and _index.md Link to heading

Feature _index.md index.md
Purpose Defines a section or taxonomy list page. Defines a single, standalone page.
Context Used for folders representing sections. Used for standalone or leaf bundles.
Result Creates a list page (e.g., /blog/). Creates a single page (e.g., /about/).

The lookup order ensures you only need to create templates as specific as your site requires.

Data Link to heading

To inject for example some data onto a page from a json, create a folder data, place a json file into it e.g. 2652.json, define in your front matter json source like this:

jsonSrc: "2652"

no need to include the extension, in your html template to access the data and start reading values from keys:

{{ with index .Params.jsonSrc }}

Javascript Link to heading

in your html files you may add javascript and/or use Hugo to manipulate data provided in your front matter

I hope this information will be helpful to you, Happy Codding!