# How Hugo's Page Bundle System Organizes Static Assets with Content: A Complete Guide

> Master Hugo's page bundle system to organize static assets with content. Learn how to co-locate files and process resources directly in templates, streamlining your build.

- Repository: [GoHugo.io/hugo](https://github.com/gohugoio/hugo)
- Tags: how-to-guide
- Published: 2026-02-28

---

**Hugo's page bundle system treats directories containing [`index.md`](https://github.com/gohugoio/hugo/blob/main/index.md) or [`_index.md`](https://github.com/gohugoio/hugo/blob/main/_index.md) as self-contained units that co-locate content files with their static assets, enabling resource-specific processing methods directly in templates without using the global `static/` folder.**

The `gohugoio/hugo` static site generator implements a sophisticated content organization architecture that binds static assets to their logical content owners. This system parses filesystem paths to classify resources, distinguishes between page types using specific filename conventions, and exposes powerful template methods for asset manipulation. Understanding how Hugo processes these bundles at the source code level allows developers to optimize site architecture and asset pipelines.

## What Is a Hugo Page Bundle?

A **page bundle** is a directory within Hugo's content filesystem that contains both a content file ([`index.md`](https://github.com/gohugoio/hugo/blob/main/index.md) or [`_index.md`](https://github.com/gohugoio/hugo/blob/main/_index.md)) and associated **page resources** such as images, PDFs, JSON files, or SVG diagrams. When Hugo parses the filesystem, it builds a `paths.Path` object in [`common/paths/pathparser.go`](https://github.com/gohugoio/hugo/blob/main/common/paths/pathparser.go) to classify each file.

Files residing alongside the index file—or in subdirectories within the bundle—are marked as `TypeContentResource` via the `ModifyPathBundleTypeResource` function. This classification distinguishes page-specific assets from global static files, allowing Hugo to attach them directly to the `Page` object rather than treating them as generic site resources.

## Leaf Bundles vs. Branch Bundles

Hugo recognizes two distinct bundle types based on the content filename, both defined in [`common/paths/pathparser.go`](https://github.com/gohugoio/hugo/blob/main/common/paths/pathparser.go):

- **Leaf bundles** (`TypeLeaf`): Created when a directory contains [`index.md`](https://github.com/gohugoio/hugo/blob/main/index.md). These represent single content pages and cannot contain nested sections.
- **Branch bundles** (`TypeBranch`): Created when a directory contains [`_index.md`](https://github.com/gohugoio/hugo/blob/main/_index.md). These represent section list pages and can contain other pages or nested sections.

The bundle type is exposed through the `PageMetaProvider.BundleType()` method in [`resources/page/page.go`](https://github.com/gohugoio/hugo/blob/main/resources/page/page.go), allowing templates to query the structural role of any given page. Leaf bundles are ideal for articles with associated media, while branch bundles organize section-level resources like category headers or landing page assets.

## How Hugo Processes Page Resources

During site construction, Hugo walks the content tree and classifies resources using the path parser. The `Resources` collection—implemented in `methods/page/Resources`—attaches all detected files to their parent `Page` object. This collection provides lookup helpers including:

- **`Get`**: Retrieves a resource by exact relative path
- **`GetMatch`**: Retrieves a resource by pattern or metadata name
- **`Match`**: Returns all resources matching a glob pattern
- **`ByType`**: Filters resources by MIME type (e.g., `image`, `application`)

Each resource implements the `resource.Resource` interface, exposing methods like `RelPermalink`, `Resize`, `Content`, and `Title`. This architecture ensures that assets are versioned, processed, and published only when their owning page is built, maintaining a tight coupling between content and dependencies.

## Accessing and Processing Bundle Resources in Templates

Page resources are accessible via the `.Resources` method in templates, returning a `resource.Collection`. This enables sophisticated asset pipelines directly within markup.

### Basic Resource Retrieval

Access a specific image and resize it for responsive display:

```go-html-template
{{ with .Resources.Get "hero.jpg" }}
  {{ with .Resize "800x" }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
  {{ end }}
{{ else }}
  {{ errorf "Missing hero image for %s" .File.Path }}
{{ end }}

```

### Pattern Matching and Data Processing

Iterate over all JSON files in the bundle and unmarshal them for display:

```go-html-template
{{ range .Resources.Match "**.json" }}
  {{ $data := . | transform.Unmarshal }}
  <pre>{{ $data | jsonify }}</pre>
{{ end }}

```

### Configuring Resources via Front Matter

You can assign metadata to resources using the `resources` array in front matter, then reference them by name:

```yaml

# content/posts/my-article/index.md

title: My Article
resources:
  - src: hero.jpg
    name: hero
    params:
      alt: "Cover illustration"
  - src: data.json
    title: "Article data"

```

```go-html-template
{{ with .Resources.GetMatch "hero" }}
  <img src="{{ .RelPermalink }}" alt="{{ .Params.alt }}">
{{ end }}

```

## Multilingual Sites and Headless Bundles

According to the Hugo source documentation, multilingual implementations handle page resources efficiently by **not duplicating** shared assets across language variants. Resources are attached once to the default language bundle and referenced from translations, except for non-Markdown formats that require language-specific processing.

**Headless bundles** provide a mechanism for organizing reusable assets without publishing a standalone page. By setting `headless: true` in a branch bundle's front matter, you create a resource repository accessible via `site.GetPage` but excluded from site navigation and output:

```yaml

# content/partials/_index.md

headless: true

```

```go-html-template
{{ $bundle := site.GetPage "partials" }}
{{ range $bundle.Resources.ByType "image" }}
  <img src="{{ .RelPermalink }}">
{{ end }}

```

## Summary

- **Page bundles** in `gohugoio/hugo` are directories containing [`index.md`](https://github.com/gohugoio/hugo/blob/main/index.md) (leaf) or [`_index.md`](https://github.com/gohugoio/hugo/blob/main/_index.md) (branch) plus associated assets, processed via [`common/paths/pathparser.go`](https://github.com/gohugoio/hugo/blob/main/common/paths/pathparser.go).
- **Type classification** occurs through `ModifyPathBundleTypeResource`, marking files as `TypeContentResource` and exposing types via `BundleType()` in [`resources/page/page.go`](https://github.com/gohugoio/hugo/blob/main/resources/page/page.go).
- **Resource methods** include `Get`, `GetMatch`, `Match`, and `ByType`, returning objects with `RelPermalink`, `Resize`, and custom parameters.
- **Multilingual efficiency** prevents resource duplication across languages, while **headless bundles** enable unpublished asset collections for shared components.

## Frequently Asked Questions

### What is the difference between a leaf bundle and a branch bundle in Hugo?

A **leaf bundle** uses [`index.md`](https://github.com/gohugoio/hugo/blob/main/index.md) and represents a single content page that cannot contain child pages, making it ideal for articles with dedicated assets. A **branch bundle** uses [`_index.md`](https://github.com/gohugoio/hugo/blob/main/_index.md) and represents a section list page that can contain nested pages and subsections. The distinction is enforced in [`common/paths/pathparser.go`](https://github.com/gohugoio/hugo/blob/main/common/paths/pathparser.go) through the `TypeLeaf` and `TypeBranch` constants.

### Can I use page bundles with multilingual Hugo sites?

Yes, Hugo's page bundle system supports multilingual sites efficiently. Page resources are attached to the default language bundle and referenced from other languages without duplication, except for non-Markdown formats that require language-specific processing. This architecture minimizes build overhead while maintaining asset localization capabilities.

### How do I process images within a Hugo page bundle?

Images in page bundles are accessed via `.Resources.Get` or `.Resources.GetMatch` and implement the `resource.Resource` interface. You can chain image processing methods like `.Resize`, `.Fit`, or `.Fill` directly on the resource object before generating the `RelPermalink`, enabling on-the-fly image optimization without external build tools.

### What is a headless bundle and when should I use it?

A **headless bundle** is a branch bundle with `headless: true` set in its front matter, which prevents Hugo from publishing a URL or rendering a page while keeping its resources accessible via `site.GetPage`. Use headless bundles to organize shared assets like logos or icon libraries that multiple templates reference but that should not exist as standalone pages on the site.