Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 14

Building Reusable Layouts with Partials

Recommended resources

Hello! Welcome back to our course on building complex websites with AI assistance.

In our last lesson, we focused on how to bring your content to life by using Hugo variables like .Title, .Content, and .Params. You learned how to pull data from your Markdown files into a single template, single.html. However, if you were to create another template—say, for a list page—you'd find yourself copying and pasting the entire <head> section, the site header, and the footer. This is inefficient and makes updates a nightmare. As an SEO manager experienced in delivering scalable digital projects, you know that maintainability is key.

Today, we'll solve this problem. Our learning outcome is to create and use partials to build reusable template components like headers and footers. Partials are Hugo's way of enforcing the "Don't Repeat Yourself" (DRY) principle. By breaking our templates into smaller, reusable snippets, we can manage our site's structure much more efficiently and focus our AI prompting on specific components rather than entire pages.

The DRY Principle and Modularity

Before we write any code, let's establish the core concept. "Don't Repeat Yourself" (DRY) is a fundamental principle in software and web development. The idea is to reduce repetition of information of all kinds.

In web design, this means components that appear on every page—like the main navigation, the meta tags in the <head>, or the copyright notice in the footer—should be defined in only one place. If you need to add a new CSS file or update the copyright year, you only have to change it once, and the update will apply everywhere.

Hugo's solution to this is Partial Templates. You can think of these as "includes" or reusable components, a concept you may have encountered in CMSs like WordPress (e.g., get_header()) or other templating systems.

Partial Templates | Hugo

The article "Partial Templates" from Giraffe Academy offers a great non-technical explanation of this modularity, using analogies like LEGOs to illustrate the concept.

Read the first two sections, 'Modularity' and 'Partial templates'. Focus on the core idea of breaking a website down into smaller, manageable parts.


Creating and Using Partials in Hugo

Let's get practical. The process involves three simple steps:

  1. Create a partials directory inside your layouts folder.
  2. Create HTML files inside layouts/partials/ for each reusable component (e.g., header.html, footer.html).
  3. Use the {{ partial }} function in your main templates to include them.

The following video provides a perfect walkthrough of this entire process.

Partial Templates | Hugo - Static Site Generator | Tutorial 21

Watch this tutorial from Giraffe Academy. It demonstrates exactly how to create a header partial and include it in your templates, clearly explaining the syntax and the crucial concept of passing context.

Watch from the beginning to 04:05. Pay close attention to: The creation of the layouts/partials/header.html file. The syntax used to include the partial: {{ partial "header.html" . }}. The explanation of why the dot (.) is so important for passing the page's data into the partial.

Understanding the partial Function

As you saw in the video, the magic happens with this line of code:

{{ partial "header.html" . }}

Let's break it down:

  • {{ ... }}: This tells Hugo we are executing a command, not just writing plain HTML.
  • partial: This is the name of the Hugo function we are calling.
  • "header.html": This is the first argument, telling Hugo which file to load from the layouts/partials/ directory. You can also organize partials into subdirectories (e.g., "components/card.html").
  • . (The Dot): This is the second argument, and it's the most critical part. As we learned in the last lesson, the dot represents the current context—the data object for the page being rendered. By passing the dot to the partial, you give the partial access to all the same variables (.Title, .Params, etc.) as the parent template. Without it, {{ .Title }} inside your header.html would not work.
Hugo Templating with Partials in VS Code
This image shows a typical Hugo project structure. You can see the `baseof.html` file in the main editor, which calls partials like `head.html`, `header.html`, and `footer.html` from the `layouts/partials` directory shown in the file explorer on the left. This visualizes how a main template is assembled from smaller, reusable parts.

AI-Assisted Workflow for Creating Partials

Now, let's apply this to our "vibe coding" workflow. Instead of asking your AI assistant to generate one monolithic template, you can now direct it to create and use partials.

Let's say you have a single single.html template. You can refactor it with the following prompts:

  1. Isolate the Header:

    "Analyze this Hugo template (single.html). Extract the code from <!DOCTYPE html> through the closing </header> tag into a new Hugo partial named header.html."

  2. Isolate the Footer:

    "Now, take the <footer> section and everything after it from the original single.html and create a new Hugo partial named footer.html."

  3. Rebuild the Main Template:

    "Finally, modify the single.html template to remove the code you extracted. Instead, use the partial function to include header.html at the top and footer.html at the bottom. Remember to pass the current context to both partials."

This modular approach makes your requests to the AI more specific and the generated code easier to manage and debug.

Test your understanding!

Below is a complete single.html template for a blog post. Your task is to refactor it using partials.

Original single.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ .Title }} | My Awesome Site</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <header class="site-header">
        <a href="/">My Awesome Site</a>
        <nav>
            <a href="/blog">Blog</a>
            <a href="/about">About</a>
        </nav>
    </header>

    <main>
        <article>
            <h1>{{ .Title }}</h1>
            <p>Published on {{ .Date.Format "January 2, 2006" }}</p>
            <div>
                {{ .Content }}
            </div>
        </article>
    </main>

    <footer class="site-footer">
        <p>&copy; 2024 My Awesome Site. All rights reserved.</p>
    </footer>
</body>
</html>

How would you rewrite this single.html file after moving the appropriate code into layouts/partials/header.html and layouts/partials/footer.html?

Show answer

After moving the header and footer code into their respective partial files, the single.html template would be simplified to this:

{{ partial "header.html" . }}

<main>
    <article>
        <h1>{{ .Title }}</h1>
        <p>Published on {{ .Date.Format "January 2, 2006" }}</p>
        <div>
            {{ .Content }}
        </div>
    </article>
</main>

{{ partial "footer.html" . }}

This is much cleaner and more maintainable. The header.html partial would contain everything from <!DOCTYPE html> through </header>, and the footer.html partial would contain everything from <footer> through </html>.


An Alternative Approach: Base Templates

Using header and footer partials is a great starting point. However, as sites become more complex, Hugo offers an even more structured approach called base templates and blocks.

Instead of your single.html calling the header and footer, the logic is inverted: a master template, layouts/_default/baseof.html, defines the full page skeleton and marks specific areas as "blocks" that can be overridden.

A simplified baseof.html might look like this:

<!DOCTYPE html>
<html>
    {{ partial "head.html" . }}
    <body>
        {{ partial "header.html" . }}
        <main>
            {{- block "main" . }}{{- end }}
        </main>
        {{ partial "footer.html" . }}
    </body>
</html>

Your single.html then becomes extremely simple, defining only the content for the "main" block:

{{ define "main" }}
<article>
    <h1>{{ .Title }}</h1>
    {{ .Content }}
</article>
{{ end }}

We won't dive deep into this method now, but it's important for you to know it exists. It's often considered a more robust and scalable pattern for complex Hugo sites. You can learn more about it by exploring the article "Getting Started With Hugo Partials" from Yockyard (resource_id: [LINK](https://www.yockyard.com/post/getting-started-with-hugo-partials/)), which discusses this paradigm.


Conclusion

You've taken a significant step towards creating professional, scalable websites with Hugo. By mastering partials, you can now build your templates from reusable, manageable components, which is a cornerstone of efficient web development.

Key Takeaways:

  • Partials are Hugo's tool for implementing the DRY (Don't Repeat Yourself) principle.
  • They live in the layouts/partials/ directory.
  • You include them using the {{ partial "filename.html" . }} function.
  • Passing the dot (.) as the second argument is essential to give the partial access to the page's data context.
  • You can direct your AI assistant to refactor templates into partials, making your workflow more modular.

Preview of the next lesson:
Now that your templates are neatly organized into reusable partials, you have the perfect foundation for refinement. In our next lesson, "Adapt AI-generated template code to match specific design requirements," we will focus on taking the HTML and CSS within these partials and tweaking them to create polished, custom layouts that perfectly match your vision.