Granular Output Configuration

Did you know you can disable rendering of taxonomy/term pages by simply creating an empty layout file?

I discovered this lifesaver after trying and failing to find a configuration-based approach. Since Google came up dry in my journey, I’ll share my story here in the hopes that it helps someone else down the road.

We’re taking advantage of some custom output formats to serve structured data for certain taxonomies/terms. For instance, creating JSON output for our years taxonomy, listing all available terms (years) and, for each term, all available posts. We achieve this with Hugo’s extensible output formats feature. Here’s an example from our hugo.yaml:

outputFormats:
  calendar:
    baseName: calendar
    isPlainText: true
    mediaType: application/json
outputs:
  taxonomy:
    - html
    - calendar
  term:
    - html
    - calendar

This was working great for our purposes, but as our site content grew (1000+ pages, 8 taxonomies), build times started creeping up fast, at one point taking more than 30 seconds for the initial build.

Examining the /public directory, I noticed that every single taxonomy and term had a calendar.json file being rendered. All because one of our eight taxonomies needed it.

To solve this, I first tried moving the list.calendar.json and terms.calendar.json files from /layouts/_default to /layouts/years. This solved the issue of extraneous pages being rendered, but then Hugo started throwing warnings at build time to let me know I was missing default layouts.

On a hunch, I created empty layout files in the /layouts/_default directory. This made the warnings go away, which is great! I then presumed I would find empty calendar.json files all over the place in the /public folder. But no, it turns out Hugo detects the empty file and skips it altogether! Yay!

That’s when I realized I could use the same approach to selectively disable HTML listing pages for taxonomies and terms. So I went through our taxonomies and disabled several templates we never use on our site. When I was finished, I purged the /public directory and ran a full build. Total build time went from >30s to under 7 seconds!

I hope this helps someone else improve their build times and clean up their output folders.

Typically you would handle this with build or cascade options. Was there a reason that wouldn’t work in this case?

For example, this…

[taxonomies]
author = 'authors'
category = 'categories'
tag = 'tags'

[outputs]
taxonomy = ['html']
term = ['html']

[[cascade]]
outputs = ['html','calendar']
[cascade._target]
path = '{/authors,/authors/**}'

…produces this:

public/
β”œβ”€β”€ authors/
β”‚   β”œβ”€β”€ author-a/
β”‚   β”‚   β”œβ”€β”€ index.html
β”‚   β”‚   └── index.ics
β”‚   β”œβ”€β”€ author-b/
β”‚   β”‚   β”œβ”€β”€ index.html
β”‚   β”‚   └── index.ics
β”‚   β”œβ”€β”€ index.html
β”‚   └── index.ics
β”œβ”€β”€ categories/
β”‚   β”œβ”€β”€ category-a/
β”‚   β”‚   └── index.html
β”‚   β”œβ”€β”€ category-b/
β”‚   β”‚   └── index.html
β”‚   └── index.html
β”œβ”€β”€ tags/
β”‚   β”œβ”€β”€ tag-a/
β”‚   β”‚   └── index.html
β”‚   β”œβ”€β”€ tag-b/
β”‚   β”‚   └── index.html
β”‚   └── index.html
β”œβ”€β”€ favicon.ico
β”œβ”€β”€ index.html
β”œβ”€β”€ index.xml
└── sitemap.xml

In the above notice that only the authors taxonomy/term pages have the calendar output format.

1 Like

Wow, this is a great solution, and one that I managed to miss completely while searching & browsing the docs. Thanks!

1 Like