# Is there an example of how to use the new multidimensional content model?

**URL:** <https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516>\
**Category:** support\
**Tags:** content-dimensions\
**Created:** [January 6, 2026, 3:52pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516 "2026-01-06T15:52:51Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Travis\_Beckham](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/travis_beckham/32/22067_2.png) [@Travis\_Beckham](https://discourse.gohugo.io/u/Travis_Beckham)\
**Post date:** [January 6, 2026, 3:52pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/1 "2026-01-06T15:52:51Z")

</div>

I maintain a few documentation sites and have to deal with multiple versions of docs, and was looking forward to the new multidimensional content model. I’ve read through the updated documentation on `sites matrix` and the new `Rotate` method, but I don’t quite understand how the content and templates should be set up. I probably have the wrong idea in my head on how this is suppose to work. Does anyone know if there’s a demo repo available that shows how to use versions, and demonstrates the power the new model provides?

---

<div class="post-metadata">

**Author:** ![nekr0z](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nekr0z/32/18320_2.png) [@nekr0z](https://discourse.gohugo.io/u/nekr0z)\
**Post date:** [January 8, 2026, 8:40am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/2 "2026-01-08T08:40:11Z")

</div>

I would also very much like to see an example demonstrating how to use sites.complements. The documentation says it can be used “to fill in the Swedish pages where pages for Norway are missing” or something of that sort, which is exactly what I’ve been doing for years now using all kinds of weird techniques. I would very much like to give the new approach a try, but I can’t wrap my head around it.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 8, 2026, 11:40am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/3 "2026-01-08T11:40:34Z")

</div>

I didn’t want to drag that feature unreleased into a new year, which is why I pushed the release right before Christmas. There’s a ton of integration tests, so I’m confident that it works, but you’re right, I don’t know about any great examples.

I will put on my TODO list to create a basic demo site that at least shows the versions and languages at play. @nekr0z you are right, this is is a head twister if you just look at the current documentation – but I think it gets much easier with some examples. Stay tuned.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [January 8, 2026, 6:03pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/4 "2026-01-08T18:03:56Z")

</div>

This needs some adjusting (consider it a work in progress), but it’s a starting point…

This is an example of the multidimensional content model introduced in Hugo [v0.153.0](https://github.com/gohugoio/hugo/releases/tag/v0.153.0). This framework enables content to be organized across multiple languages, roles, and versions simultaneously. For this specific example, we are focusing on the version dimension to demonstrate a software documentation site where pages are added, modified, or removed with each release.

v0.1.0

- Added `/docs/functions/average`
- Added `/docs/functions/mean`

v0.2.0

- Added `/docs/functions/variance`
- Modified` /docs/functions/mean`

v0.3.0

- Added `/docs/functions/standard-deviation`
- Modified` /docs/functions/variance`
- Removed `/docs/functions/average`

v0.4.0 (`defaultContentVersion`)

- Added `/docs/functions/median`

Expected result when viewing the v0.4.0 site:

- `/docs/function/mean` from v0.2.0
- `/docs/functions/standard-deviation` from v0.3.0
- `/docs/functions/variance` from v0.3.0
- `/docs/functions/median` from v0.4.0

Try it:

```plaintext
git clone --single-branch -b hugo-forum-topic-56516 https://github.com/jmooring/hugo-testing hugo-forum-topic-56516
cd hugo-forum-topic-56516
hugo server

```

Notes:

- Hugo does not create an alias in the root of the public directory that points to the `defaultContentVersion`. I need to figure out how to handle that. For now, visit [http://localhost:1313/v0.4.0/](http://localhost:1313/v0.4.0/).
- This doesn’t use `module.mounts.sites.complements`. I’m not sure how that should be configured for this example. Consequently, the desired inheritance isn’t working as desired.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 9, 2026, 9:37am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/5 "2026-01-09T09:37:40Z")

</div>

> [@jmooring](#):
>
> Hugo does not create an alias in the root of the public directory that points to the `defaultContentVersion`. I need to figure out how to handle that. For now, visit [http://localhost:1313/v0.4.0/](http://localhost:1313/v0.4.0/).

That’s a detail i missed in the original implementation, I will fix that reasonably fast:

> <https://github.com/gohugoio/hugo/issues/14354>
>
> This seems to be a detail left out in the multidimensional content model. As rep…orted in https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/3 it seems that we redirect to the language root.
> 
> This works fine in most cases, but not in the common "docs versioning case".
> 
> So given:
> 
> \`\`\`
> defaultContentInSubDir = true
> defaultVersionInSubDir = true
> \`\`\`
> 
> Going to \`https://localhost:1313/\` should take you to \`https://localhost:1313/en/v1.0.0\`.

As to “the desired inheritance isn’t working as desired”, let me know some more. I’m pretty sure it works on the technical level, but maybe it need to improved on the … practical level.

---

<div class="post-metadata">

**Author:** ![nekr0z](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nekr0z/32/18320_2.png) [@nekr0z](https://discourse.gohugo.io/u/nekr0z)\
**Post date:** [January 9, 2026, 7:00pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/6 "2026-01-09T19:00:50Z")

</div>

Wow, impressive, thank you!  
(I’m even more confused about sites complements now, though ;).

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [January 9, 2026, 7:04pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/7 "2026-01-09T19:04:56Z")

</div>

> [@nekr0z](#):
>
> Wow, impressive, thank you!

Well, it will be when the published site matches the “expected result” as documented in my initial post.

> [@bep](#):
>
> let me know some more

I’ve add an “expected result” list to my initial post. The actual result doesn’t match, so either my expectations are wrong or I’m doing it wrong… I suspect the latter because I don’t understand (and am not using) `module.mounts.sites.complements`. It would be helpful if you could look at site config.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 9, 2026, 8:05pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/8 "2026-01-09T20:05:52Z")

</div>

See [Investigate the sites matrix file mount merge logic · Issue #14357 · gohugoio/hugo · GitHub](https://github.com/gohugoio/hugo/issues/14357)

The file mount merge result looks fishy in your example, and I guess that is the main workflow for the “versions use case” (e.g. mount different GitHub branches). I’m a little surprised by this, though, but thanks testing this.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 10, 2026, 10:05am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/9 "2026-01-10T10:05:27Z")

</div>

> [@nekr0z](#):
>
> (I’m even more confused about sites complements now, though ;).

- sites.complements is probably not relevant for versions, possibly for some language use cases.

- conceptually it’s working the same as the lang.Merge func, but this is an auto merge into all. of Hugo’s page collections (e.g. site.RegularPags)

- The main use case I had in mind, though, was for membership sites using the role dimension. The `member` site would _complement_ `guest` site with content, the guest site would list it with a title and summary (and a + sign or something to mark that it needs a membership), but it would link to e.g. `/member/a-cool-article`, which would trigger authentication/subscription\*

- The authentication part would need to live outside of Hugo, but is much much simpler and cheaper than doing the entire thing on a server.

---

<div class="post-metadata">

**Author:** ![nekr0z](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nekr0z/32/18320_2.png) [@nekr0z](https://discourse.gohugo.io/u/nekr0z)\
**Post date:** [January 10, 2026, 11:54am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/10 "2026-01-10T11:54:30Z")

</div>

Perhaps, my mental model lacks some important elements. Take [this sample repo](https://github.com/nekr0z/hugo-56516): from what I read in documentation, as well as your explanations, I’d expect `/public/de/posts/index.html` in the rendered site to have links to two pages, one in English and one in German, based on what’s in `/content/posts/_index.de.md`, but that isn’t the case.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 10, 2026, 12:56pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/11 "2026-01-10T12:56:58Z")

</div>

@jmooring see this branch for a way to reconfigure your site to make it work, also with some links to some context: [Rework the mounts · bep/hugo-testing@434a9dd · GitHub](https://github.com/bep/hugo-testing/commit/434a9dd6145680aa4c60b54ea7e64a332c76bb21)

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [January 10, 2026, 9:13pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/12 "2026-01-10T21:13:18Z")

</div>

> [@bep](#):
>
> reconfigure your site to make it work

Well, that was easy. Thanks. With v0.154.4 this works as expected:

```plaintext
git clone --single-branch -b hugo-forum-topic-56516 https://github.com/jmooring/hugo-testing hugo-forum-topic-56516
cd hugo-forum-topic-56516
hugo server

```

---

<div class="post-metadata">

**Author:** ![Travis\_Beckham](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/travis_beckham/32/22067_2.png) [@Travis\_Beckham](https://discourse.gohugo.io/u/Travis_Beckham)\
**Post date:** [January 11, 2026, 12:34am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/13 "2026-01-11T00:34:42Z")

</div>

Thanks for the demo! This helped so much.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [January 11, 2026, 1:56am UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/14 "2026-01-11T01:56:19Z")

</div>

Thanks. At some point I’ll add another content dimension (language) to this.

---

<div class="post-metadata">

**Author:** ![chalin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/chalin/32/21469_2.png) [@chalin](https://discourse.gohugo.io/u/chalin)\
**Post date:** [January 29, 2026, 10:34pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/15 "2026-01-29T22:34:18Z")

</div>

I finally got the [OTel](https://opentelemetry.io/) **multilingual site with `en` fallback** working with the `sites.matrix` 😅. In case you’d like to see the config changes, here’s the PR:

- [chore(hugo-config): refactor language mounts to use matrix sites config by chalin · Pull Request #9070 · open-telemetry/opentelemetry.io · GitHub](https://github.com/open-telemetry/opentelemetry.io/pull/9070)

A note about the [OTel.io](http://OTel.io) site design: each non-`en` site is complete in itself. Locale users never have to leave their (locale) site. English pages have a banner atop that say something like “This page hasn’t been translated yet, want to help?” 🙂 So I don’t use `complements` but rather map the `en` pages as backup locale pages. Hopefully this might be a useful example to some.

I do have some use cases for `complements` and `version`, which I’ll hopefully get to try soon. Thanks all!

p.s. The base config is in [config/\_default/hugo.yaml](https://github.com/open-telemetry/opentelemetry.io/blob/main/config/_default/hugo.yaml)

---

<div class="post-metadata">

**Author:** ![Tom\_Durand](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tom_durand/32/14460_2.png) [@Tom\_Durand](https://discourse.gohugo.io/u/Tom_Durand)\
**Post date:** [January 30, 2026, 11:38pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/16 "2026-01-30T23:38:00Z")

</div>

I’ll wait until it’s been ironed out and most importantly the documentation fully fleshed out, because this is complex enough that just tinkering with the content tree won’t do it to intuitively grasp it. But as long as using plain ol’ language extensions still works and page sorting works, it doesn’t bother other users.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [February 19, 2026, 4:07pm UTC](https://discourse.gohugo.io/t/is-there-an-example-of-how-to-use-the-new-multidimensional-content-model/56516/17 "2026-02-19T16:07:35Z")

</div>

3 posts were split to a new topic: [Using the multidimensional content model to fill-in missing translations](https://discourse.gohugo.io/t/using-the-multidimensional-content-model-to-fill-in-missing-translations/56741)
