Disable generating empty index.html pages created for sections

I am using Hugo to create a book site with articles that are grouped by sections, so I have like:

  • content/
    • apples/
      • _index.md
      • green-apples.md
      • washington-apples.md
    • bananas/
      • _index.md
      • african-bananas.md
      • cloned-bananas.md

So I use the _index.md of sections in my book’s homepage template to give “title” and “weight” to each section. For example, content/apples/_index.md reads:

---
title: About Apples
weight: 10
---

Just because I have this _index.md, for each section, it creates an index.html page:

http://DOMAIN/apples/index.html

I do not want /apples/ or /apples/index.html to work, because I’m directly linking to /apples/green-apples/ from my homepage, and /apples/index.html is just an empty file with no content.

Is there a way to disable generating these empty index.html pages coming from _index.md of sections?

Look for “disableKind” in the documentation.

1 Like

Thanks for the speedy answer! However doing disableKinds=["section"] is breaking this theme (it returns no value/empty for .Sections):

{{ range  .Sections }}
<h1>{{.Title}}</h1>
<ul>
  {{ range .Pages }}
  <li>><a href="{{ .Permalink }}">{{.Title}}</a></li>
  {{ end }}
</ul>
{{ end }}

I’m currently relying on the .Sections variable to discover the table of contents from the files in content/.

Disabling this kind and printing {{.Sections}} in the template prints: Pages(0) to the HTML output.

I haven’t tested this myself but how about entering your top level unwanted section URLs as aliases in the _index.md of your nested sections.

Ah, OK. But with Hugo > 0.33 you can do layout: dummy in your “_index.md” file.

Note that “dummy” is just some string I made up now …

1 Like

What’s the reason this would be preventing the index.html from being created? I guess it would help get an empty page, but the file would still exist (and therefore visiting /apples/ would still work).

I suppose you’re suggesting I should redirect /apples/ to /apples/green-apples/ using "aliases", which would still create an /apples/index.html.

The redirection is not quite I’m looking for, I’m trying to not have the index.html in the first place.

Are you asking me? Do you need a reason? It was a practical suggestion. Hugo does no create empty pages when no layout can be found. It is kind of a hack, but you asked for it. I think.

4 Likes

@bep (Apologies, the reply button malfunctioned on me.) By the way, I really appreciate you helping out. I believe it’s not working as you described even though I have hugo v0.37.1.

hugo --debug show that I still get /apples/index.html even though I specify layout:invalid. Log line shows:

DEBUG 2018/03/13 23:01:04 Render section to “/apples/index.html” with layouts [“apples/invalid.en.html.html” “theme/apples/invalid.en.html.html” “apples/apples.en.html.html” […]

Full log message here

I ran a stat on all these files it’s looking up, but of them actually exist: (see output) However, index.html is still being rendered with the default layout as if I didn’t specify the layout: key in the front-matter.

The debug message isn’t telling which layout it has chosen, but none of the listed files exist for sure.

I know this is an old post, but I recently stumbled (again) over the same issue.
There is a simple (but rather undocumented) way to do this. You need to set the _build flag for the branch bundle (see Page Bundles | Hugo) within _index.md and adjust for the children using cascade.

This is a working _index.md (confirmed with 0.112.6) that does the trick for me:

---
_build:
  render: never
  list: never
  publishResources: false
cascade:
  _build:
    list: false
    render: true
title: Survey
url: /survey/
---

This is the tree of the source (multilingual site):

tree content/en/survey/
content/en/survey/
├── _index.md
├── it-security-starts-with-top-management.md
└── lets-start-talking.md

and this is the rendered output:

tree public/en/survey/
public/en/survey/
├── information-security-begins-in-the-management
│   └── index.html
└── lets-start-talking
    └── index.html

As you can see, this technique prevents the (empty) index.html from being built for the root section, but the children are still there.

The use case here are landing pages that can be reached by finishing a survey in an external limesurvey instance. They need to have a common section, but should not have an index.

1 Like