Index.md is generated in subfolder /index/index.html (Hugo 0.20)

I’ve upgraded to Hugo v0.20.5 and the generated file location of the index.md files changed. I don’t think this was intended. Here is what happened:

I use following content structure to keep content and images together:

├── content
│   └── blog
│       ├── my-blog-post-1
│       │   └── index.md
│       │   └── image-for-post-1.jpg

This generates the following structure:

Hugo before v0.20 (expected behavior)

This is how it should be.

├── public
│   └── blog
│       ├── my-blog-post-1
│       │   └── index.html
│       │   └── image-for-post-1.jpg

Hugo v0.20 (wrong behavior)

├── public
│   └── blog
│       ├── my-blog-post-1
│       │   └── image-for-post-1.jpg
│       │   └── index
│       │       └── index.html

I think it is not intended behavior to have an additional index subfolder (/index/index.html).

There is a workaround if I set slug = '/' in the front matter but I would rather not do that.

I see this as a bug and think it should be reverted to the original behavior. I opened https://github.com/spf13/hugo/issues/3396 for that on GitHub but I was directed to discuss it here. Can someone help with clarifying what happened and what should be done? Thank you.

1 Like

Using index.md for list (node) Pages was always a hack, and the order of rendering pages was always unpredictable. With v18, everything became a page. Use _index.md for your section index pages.

How to make your template:

https://hugodocs.info/templates/lists/#adding-content-and-front-matter-to-list-pages

How to organize your content:

https://hugodocs.info/content-management/organization/#index-pages-index-md

Thanks for your answer @rdwatters.

I do use _index.md for my list pages and they work well. But I was talking about single page files inside subfolders of a section. A more complete example:

└── content
    ├── blog
    |   ├── _index.md        // <- yoursite.com/blog/index.html
    |   ├── my-blog-post-1   // (subfolder blog post)
    |   |   ├── index.md     // <- yoursite.com/blog/my-blog-post-1/index.html
    |   |   └── picture.jpg  // <- yoursite.com/blog/my-blog-post-1/picture.jpg
    |   ├── my-blog-post-2   // (subfolder blog post)
    |   |   ├── index.md     // <- yoursite.com/blog/my-blog-post-2/index.html
    |   |   └── picture.jpg  // <- yoursite.com/blog/my-blog-post-2/picture.jpg

I like to keep all my blog posts in separate subfolders together with their images. This used to work well. Now with Hugo v0.20 the images are still in the right place but the blog post html files are in an additional index subfolder: yoursite.com/blog/my-blog-post-1/index/index.html

I just don’t think it makes sense to generate a single page index.md into index/index.html. Or do you see a better solution for me to organize the content?

Have you tried renaming the files to _index.md in the subfolders? Honestly, I have yet to build a Hugo site with subsections, so I haven’t tested this:)

Yes, I tried (sorry, could have written that before). This also doesn’t work. I think Hugo treats the _index.md in subfolders also as list content instead of page content.

It’s actually a very simple use case (no need for subsections or the like). It’s just one list section called blog with blog entries. And instead of keeping the assets in the static folder they are in the same folder as the markdown content.

There have been several issues and discussions that attempted to do this:

Most of this was already possible but with the recent change in Hugo v0.20 the behavior of index.md is just a bit strange (as shown above).

I would see two possible fixes for this:

  • Revert to the previous behavior and generate index.html from index.md in single page folders. Or…
  • Also use the _index.md filename for the single page subfolders to generate the index.html. This might be even more consistent. And it would have the benefit of having the _index.md file always at the top of an alphabetically sorted folder structure and not somewhere between the asset files.

This was never stable behavior; it’s also why the shift was made to _index.md to add content and front matter to list pages. You can also fiddle with the disableKinds directive in your configuration file if you want to ignored this change.

Yes, this is as designed. List pages (aka, “nodes”) have different methods immediately available to them, and the index pages for sections have always been lists and not nodes; as I said, the index.md as a single page was technically a hack :smile: You should add _index.md content files to sections and subfolders and then expect them to pull from list templates: https://hugodocs.info/templates/lists/

I think you are now talking about two different things here:

  1. How to add content and front matter to list pages, which is a feature as of v18 that allows you to do this by treating list pages/nodes as a “page” that has content and front matter pulled from _index.md. Not that it was done with extreme care by @bep so that it didn’t break previous sites (with the exception of those who were using the index.md hack).
  2. Asset management. To my knowledge, this hasn’t changed in that it is still advised to keep images and other static assets inside the static folder, which is copied over as is, which has been the behavior of that folder since I started

Reverting to features that worked as hacks in Hugo from three+ versions ago could be disastrous for the thousands of sites that have been built since 17 came out. I don’t think reverting _index.md is in the cards. It’s actually a considerable improvement from what users had to do before, which included data files and other weird workarounds for adding content and front matter to lists/nodes…

@marcojakob raises a good point really. Functionality was added to enable users to store assets in the content folder back in 0.15 I think. For those that do that, the new _index.md ‘everything is a page’ approach does break certain setups as shown above (hack or not). It maybe be recommended to keep assets that don’t need processing in /static but seeing as functionality was specifically added to support for keeping assets in the content folder it’s worth looking at this in more detail.

I’m not sure what would be best in this case. Possibly renaming the _index.md file to match the parent folder and then use slug to set the correct URL? That should work around the OP issue but could be a lot of work.

There was a lot of interest in this ‘assets alongside content’ setup when it was being discussed so if anyone here is using it and it’s working it would help to see what you are doing.

1 Like

The asset bundling is still on the road map.

I have note read this entire thread, but this issue has been debated before, and I will only say this:

  • This still works for the Hugo versions in question. The Hugo binary is static, and you can build your index.md site for the next decades with no issues. No breakage, future proof!
  • To move forward, we had to make this change.
  • We could maybe have done it with less noise, and if someone wants to spend time on working on a clean and well tested patch that makes this somewhat working again, please do. I’m not spending time on it.

So, if you don’t want to change your sites, use an older version of Hugo (or contribute a clean and well tested code change that makes this somehow magically work AND fits into the future plans of Hugo).

1 Like

@JoshArcher I think that this functionality was only half-baked, so it’s best to use the recommended method of keeping all your images in static, which will continue to be copied over as is.

@marcojakob Have you tried not only renaming the index.md to _index.md but also changing your templating so that these files are pulling from list templates? If you then have a problem, we can go from there and see if how to fix the problems you’re currently having…again, the shift to _index.md is a considerable improvement, and reverting Hugo back to previous behavior is a genuinely bad idea.

I’m closing this discussion as there are no arguments left. We understand what happened. In 0.20 all the hard coded “index.html” conditionals are gone. This fixed a lot of URL and file path related issues. It also obviously had some negative side effects on some sites, but that is the downside of becoming popular – the site variations in the wild become very big, and it is hard to think about every corner case.

If you still think that this is a bug or a feature that Hugo really needs, please register an issue on GitHub, if not already there.

Then, if someone wants to contribute some of their valuable hours to create a well thought out fix for this, then maybe everyone can be happy.

1 Like

Thank you for this fix @bep. I try to be as helpful as possible to the Hugo community but I’m not very fluent in Go yet. Maybe in the future I will be able to also contribute code. For now, it’s just experience with content and my thoughts.

Yes, Hugo got very popular. I want to express my deep respect for people like @bep and @rdwatters and all the others that keep improving the code and try to manage such a large and diverse community. Let me tell you as a Hugo user and Hugo admirer that I am perfectly fine with some breaking changes even if they mean some refactoring of my Hugo websites. The future should not be built on hacks of some users.

Content Organization Best Practice

I have thought long and hard about how I want to organize my content. The prominent statement in the Hugo docs about content organization caught my eye:

Hugo believes that you organize your content with a purpose.

For a static site generator this is crucial and has set Hugo apart from most other SSGs. I started a separate thread to make it more transparent how Hugo users are organizing their content and to discuss best practices: Content Organization Best Practice