Right, let’s talk about the little nametags and sticky notes you can slap onto your pages. This isn’t just bureaucratic nonsense; this is how you tell Hugo what a page is, so it can do clever things with it later. We’re talking about the metadata that lives at the top of your .md files in what’s called the “front matter.” This is the control panel for your content.

The Front Matter Formats: YAML, TOML, or JSON. Pick Your Poison.

Hugo is a polyglot and supports three formats for this data. YAML is the default and what you’ll see in most examples because it’s relatively human-friendly. TOML is a bit more explicit (which some people love), and JSON is, well, JSON. The choice is yours, but consistency is key. Don’t be that person with a mix of all three; your future self will hate you.

Here’s the same basic data in all three, so you can see the difference:

---
title: "My Excellent Blog Post"
date: 2023-10-26T08:19:20-04:00
draft: false
params:
  subtitle: "A Journey Into Front Matter"
---
+++
title = "My Excellent Blog Post"
date = 2023-10-26T08:19:20-04:00
draft = false
[params]
  subtitle = "A Journey Into Front Matter"
+++
{
   "title": "My Excellent Blog Post",
   "date": "2023-10-26T08:19:20-04:00",
   "draft": false,
   "params": {
      "subtitle": "A Journey Into Front Matter"
   }
}

See? YAML is the least noisy. I use it, and I recommend it. Let’s move on.

Title vs. The linkTitle Escape Hatch

The title is the canonical, full-fat name of your page. It’s what will be used in the <title> tag for the HTML head, in your rss.xml feed, and as the main headline on the page itself. But sometimes you have a brilliantly witty and descriptive title that’s 14 words long and looks ridiculous in a navigation menu.

That’s where linkTitle comes in. It’s a shorter alias to be used wherever a link to this page is generated. It’s a life-saver for your nav bars and breadcrumbs.

---
title: "An In-Depth Analysis of the Coelacanth: Why This 'Living Fossil' is the Coolest Fish on the Planet"
linkTitle: "Coelacanth Analysis"
---

Now, in your menu, it’ll show the nice, concise “Coelacanth Analysis,” but the page itself will still boast the full, glorious title. Everyone wins.

The Wild West of params

This is where Hugo gets out of your way. The params section is your personal junk drawer, your custom variable playground. You can put anything you want in here to be used in your templates. Common uses include: a subtitle, a custom color for a page, a flag to enable a special feature, or an author name.

Accessing this in a template is straightforward. For a page variable, it’s .Params.your_variable_name.

---
title: "My Post"
params:
  hero_image: "/img/special-bg.jpg"
  show_newsletter_signup: true
---

Then, in your template (e.g., layouts/_default/single.html):

{{ if .Params.hero_image }}
<header style="background-image: url('{{ .Params.hero_image }}')">
</header>
{{ end }}

{{ if .Params.show_newsletter_signup }}
    {{ partial "newsletter-form.html" . }}
{{ end }}

Pitfall Warning: The most common mistake here is typos. .Params.hero_image and .Params.heroimage are two completely different things. Hugo won’t yell at you for this; it will just return a nil value and fail silently, leaving you to wonder why your beautiful background isn’t showing up. Be meticulous.

The Subtle Power of .Page Resources and Names

This is a feature so cool it’s almost hidden. Any file within a page’s directory (except the index.md itself) becomes a Page Resource. Think of images, PDFs, data files—anything. Why is this brilliant? Because Hugo gives you a way to access them programmatically from the page itself.

Let’s say your post directory looks like this:

content/post/my-fish-post/
├── index.md
├── coelacanth.jpg
└── anatomy-diagram.png

From within the index.md template, you can access these resources via .Page.Resources.GetMatch "filename". This is Hugo’s way of saying, “I know about these files and I can process them for you.”

{{ $image := .Page.Resources.GetMatch "coelacanth.jpg" }}
<img src="{{ $image.RelPermalink }}" alt="A grumpy-looking coelacanth">

But wait, it gets better. You can also give resources a metadata name directly in the front matter using the resources field. This is incredibly useful for setting alt text or other data without cluttering your template with hardcoded filenames.

---
title: "My Fish Post"
resources:
  - src: "coelacanth.jpg"
    name: "hero"
    title: "A Coelacanth in its Natural Habitat"
  - src: "anatomy-diagram.png"
    name: "diagram"
    params:
      credit: "Dr. Marine Biology"
---

Now, you can fetch them by name, which is much more robust than hoping a filename never changes:

{{ $hero := .Page.Resources.GetMatch "**hero*" }}
<figure>
    <img src="{{ $hero.RelPermalink }}" alt="{{ $hero.Title }}">
    <figcaption>Credit: {{ $hero.Params.credit }}</figcaption>
</figure>

This approach moves crucial image metadata out of your layout and into the content, where it belongs. It’s the difference between a static site generator and a proper content management system. Use it. It separates the pros from the amateurs.