Building an about page in Hugo without touching single.html
How to use Hugo's layout key to give a standalone page its own template, rather than bending a shared layout with conditionals.
The temptation
You have a working layouts/_default/single.html for article pages. It renders a hero image, an eyebrow label, a date, and a comments section. Now you need an About page — same fonts, same nav, same footer, but none of that article-specific structure.
The tempting path: add a conditional.
{{ if ne .Type "about" }}
<div class="article-hero-image">...</div>
<div class="eyebrow">Route report · {{ .Date.Format "January 2006" }}</div>
{{ end }}Don’t. Every conditional you add to a shared layout is a claim that two fundamentally different things are the same thing. single.html accumulates special cases over time, and eventually you’re reading a template full of if branches trying to reconstruct which of five page types you’re on.
The layout front matter key
Hugo has a cleaner answer. Any content file can declare the template it wants:
---
title: Hello.
layout: about
---Hugo looks up layouts/_default/about.html and uses it for this page. single.html is never involved. The about page gets its own template, does exactly what it needs to do, and nothing else changes.
The layout file
{{ define "main" }}
<div class="prose">
<header class="about-header">
<div class="eyebrow">About</div>
<h1 class="about-title">{{ .Title }}</h1>
</header>
{{- with .Params.portrait -}}
{{- $img := resources.Get (strings.TrimLeft "/" .src) -}}
{{- if $img -}}
{{- $portrait := $img.Resize "680x webp" -}}
<figure class="about-portrait">
<img src="{{ $portrait.RelPermalink }}"
alt="{{ $.Params.portrait.caption | default $.Title }}"
loading="lazy">
{{- with $.Params.portrait.caption -}}
<figcaption>{{ . }}</figcaption>
{{- end -}}
</figure>
{{- end -}}
{{- end }}
{{ .Content }}
</div>
{{ end }}{{ define "main" }} plugs into the baseof.html base template — the about page still gets the nav, footer, and any globally-loaded scripts. It just has a different main block.
The portrait image is optional. resources.Get returns nil if the file doesn’t exist; the {{ if $img }} guard means the figure is simply omitted rather than causing a build error. The page renders correctly before you have a photo to put on it.
The content file
---
title: Hello.
description: One sentence for the HTML meta description.
layout: about
portrait:
src: /images/about/portrait.jpg
caption: Somewhere alongside the Loire.
---
Body text here, written in Markdown as normal.description is kept for <meta name="description"> but the layout doesn’t render it on the page — the design goes straight from h1 to photo to prose. One field, two uses, no duplication.
When to use a dedicated layout
This pattern is worth reaching for whenever a page differs structurally from the norm rather than just in content. Good candidates:
- An About page (no hero, no date, no comments)
- A Contact page (a form, no article body)
- An index page that needs a custom header or grid
If a page needs a single field suppressed, a conditional in the shared template is probably fine. If it needs multiple sections replaced or a different overall structure, give it its own layout. The distinction is: am I configuring the template, or am I fighting it?