9.1 What Archetypes Do: Bootstrapping Front Matter for New Content
Right, let’s talk about the part of this system that actually saves you from your own forgetfulness: bootstrapping front matter. You know, that YAML block at the top of every Markdown file that looks like it was designed to torture people who forget to close their quotes. Manually typing that out for every new blog post or documentation page is a special kind of hell. It’s repetitive, error-prone, and frankly, beneath you. This is where Archetypes flex their first and most glorious muscle.
An Archetype is essentially a content template with pre-defined front matter. When you create a new piece of content using a specific archetype, it doesn’t just give you an empty file. It gives you a file already populated with the front matter structure that particular type of content requires. No more forgetting to add the draft: true flag and accidentally publishing your half-baked rant about semicolons. The archetype handles it for you.
The Mechanics of the Bootstrap
Think of an archetype file as the mold. Your new content is the molten metal you pour into it. The system takes the mold, makes a copy, and places it in the correct directory for you. Here’s a ridiculously simple example. Let’s say you have an archetype for blog posts at archetypes/blog.md. Its contents might look like this:
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
description: "A new post about something hopefully interesting."
categories: ["uncategorized"]
tags: []
---
Now, when you run the command to create a new post:
hugo new blog/my-awesome-post.md
Hugo doesn’t create an empty my-awesome-post.md file. It creates one that’s already filled out:
---
title: "My Awesome Post"
date: 2023-10-27T14:26:01-04:00
draft: true
description: "A new post about something hopefully interesting."
categories: ["uncategorized"]
tags: []
---
See what happened there? The magic isn’t magic at all; it’s the {{ }} syntax from Go’s text template engine. .Name is a variable that represents the filename you provided (my-awesome-post), and the pipeline replace .Name "-" " " | title takes that string, replaces hyphens with spaces, and then title cases it. .Date is another built-in variable that simply drops in the current datetime. It’s a simple, brilliant way to ensure consistency from the very first keystroke.
Why This is a Game Changer
The value here isn’t laziness—well, not just laziness. It’s consistency and correctness. It ensures that every single piece of content of a certain type has the exact same front matter structure. This is non-negotiable if you’re doing anything even slightly advanced.
- Your templates won’t break. If your list template expects every post to have a
descriptionfield, an archetype guarantees it will always be there, even if empty. No moreifstatements checking for existence of common fields because some intern forgot the schema. - It enforces a content schema. You can define required fields right in the archetype. New authors on your team can’t mess it up because the system pre-populates the correct structure for them.
- It saves cognitive load. You don’t have to think, “What fields does a ‘project’ need again?” You just run
hugo new projects/cool-project.mdand the scaffolding is already there, allowing you to focus on the actual content.
Going Beyond the Basics: Predefined Values
The real power comes when you start pre-populating fields with sensible defaults beyond just draft: true. Let’s create a more advanced archetype for a “talk” for a conference.
---
title: "{{ replace .Name "-" " " | title }}"
event: "Replace With Event Name"
event_url: "https://"
location: "City, Country"
date: {{ .Date }}
draft: true
abstract: "Your brilliant abstract here."
speakerdeck_id: ""
youtube_id: ""
---
This does a few things. It gives the new speaker (you) a clear checklist of what needs to be filled out: the event name, its URL, location, etc. It also includes fields for post-talk details like the SpeakerDeck and YouTube IDs. This isn’t just a template; it’s a guide and a reminder of the entire workflow for creating and publishing a talk page. It codifies your process.
Common Pitfalls and the Gotchas
It’s not all sunshine and automatically generated titles. You have to be aware of the quirks.
- The
draftDilemma: The classic rookie mistake is to forget your archetype hasdraft: trueand then wonder for three hours why your glorious new post isn’t showing up on the live site. It’s a rite of passage. Welcome. - Over-templating: Don’t get so clever with your template logic that it becomes unreadable. The goal is clarity and consistency, not to show off your Go template fu. If you need complex logic for generating front matter, it might be a sign that your content structure is too complicated.
- Wrong Content Type: Remember that the
hugo newcommand uses the first segment of the path to find the archetype.hugo new blog/post.mdusesarchetypes/blog.md, buthugo new blog/special/project.mdwill look forarchetypes/blog/special.md. If it doesn’t find a match, it just falls back to the defaultarchetypes/default.md. Always know which archetype you’re actually invoking.
The bottom line is this: Archetypes for front matter are the ultimate “work smarter, not harder” tool. They remove the tedious, error-prone bits and let you focus on what actually matters: writing. Any system that doesn’t have this concept is essentially asking you to do data entry. And you’re better than that.