Ronalds Vilciņš

How I Organize My Hugo Site

The best Hugo project structure is not the cleverest one. It is the one I can open after six months and understand without searching through three abstraction layers.

I stay close to Hugo’s standard directory structure and introduce a new convention only when the site has a repeated problem.

Let content resemble the public site

content/
├── blogs/
├── projects/
└── about/

When an article owns images or downloads, I use a page bundle:

content/blogs/my-article/
├── index.md
├── hero.jpg
└── diagram.svg

Hugo’s page bundle documentation explains the resource model. Keeping an article and its resources together is easier than matching it to files in one enormous global image directory.

Separate copied files from processed assets

I put files that should be copied as-is in static: icons, verification files, and standalone downloads are common examples.

Files Hugo should process belong in assets:

assets/
├── css/
│   └── main.css
└── js/
    └── main.js

One main CSS entry point can import smaller files without making the template responsible for loading a dozen unrelated stylesheets.

Keep templates named after their job

layouts/
├── _default/
├── blogs/
└── partials/
    ├── header.html
    ├── footer.html
    └── article-card.html

I prefer partials that represent understandable pieces of the page. Splitting every two lines into a partial creates navigation overhead; leaving the whole site in one template creates a different kind of overhead.

Template logic should also remain obvious. If a direct range expresses the page list, I do not hide it behind several layers solely to make the project look architectural.

Keep configuration and URLs deliberate

Configuration grows quickly when every small value moves out of the template. I keep genuine site-wide settings there and leave local presentation close to the code that uses it.

Content paths, slugs, and aliases affect public URLs, so reorganising files deserves care. A tidier repository is not worth breaking old links.

I also use Git history instead of keeping header-old.html, header-final.html, and the inevitable header-final-2.html. Deleted code remains recoverable without living beside the current version.

My test is whether the directory tree can answer three questions quickly: where is the content, where is its resource, and which template renders it? A structure that does that will usually age better than one built around every feature Hugo happens to support.

Enjoyed reading this?

If you found this article helpful, consider supporting my writing. Every little bit helps keep this blog going.

← Back to all articles