# Alias paths in v0.155.0 and later

**URL:** <https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674>\
**Category:** tips & tricks\
**Tags:** aliases\
**Created:** [February 3, 2026, 6:42pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674 "2026-02-03T18:42:21Z")\
**Posts on this page:** 7\
**Page:** 1

<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 3, 2026, 6:42pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/1 "2026-02-03T18:42:21Z")

</div>

## Breaking change

Prior to [v0.155.0](https://github.com/gohugoio/hugo/releases/tag/v0.155.0), alias paths beginning with a slash (`/`) were treated as [server-relative](https://gohugo.io/quick-reference/glossary/#server-relative). In v0.155.0 and later, they are now [site-relative](https://gohugo.io/quick-reference/glossary/#site-relative). This change only affects multilingual single-host projects that used alias paths beginning with a slash (`/`) to cross language boundaries.

For example, if you have a file `content/foo.en.md` with the following front matter:

```yaml
aliases:
  - /de/foo-in-german/

```

In v0.155.0 and later, this will resolve to `/en/de/foo-in-german/` instead of `/de/foo-in-german/`.

## The reason for the change

The short version is that the previous implementation was broken in several ways. It was also difficult to reason about in relation to the multidimensional content model introduced in [v0.153.0](https://github.com/gohugoio/hugo/releases/tag/v0.153.0). In this model, a site is no longer defined just by language, but by role and version as well.

To resolve this, we have changed how Hugo interprets alias paths. There are three types of relative URL paths in the context of a Hugo project:

| Type | Example | Description |
| --- | --- | --- |
| [page-relative](https://gohugo.io/quick-reference/glossary/#page-relative) | `foo`, `./foo`, `../foo` | Relative to the current page |
| [site-relative](https://gohugo.io/quick-reference/glossary/#site-relative) | `/foo` | Relative to the current site root (role, version, language) |
| [server-relative](https://gohugo.io/quick-reference/glossary/#server-relative) | `/guest/v1.2.3/de/foo` | Relative to the web server host root |

Prior to v0.155.0, alias paths beginning with a slash (`/`) were treated as _server-relative_. In v0.155.0 and later, they are now _site-relative_. This change ensures that aliases for all output formats work correctly across different roles, versions, and languages.

## Handling missing translations

If you were previously using aliases as a workaround to handle missing translations, there is a much better way to do this now using a [sites matrix](https://gohugo.io/quick-reference/glossary/#sites-matrix).

For example, to set the English version of a page to provide the content for all other missing language translations, add this to your front matter:

```yaml
title: p1
sites:
  matrix:
    languages: ['**']

```

You can also define a sites matrix in your site configuration or cascade it down to descendant pages.

## Updated documentation

We have overhauled the documentation to help you navigate these changes:

- [Front matter: Aliases](https://gohugo.io/content-management/front-matter/#aliases) (minor updates)
- [URL management: Aliases](https://gohugo.io/content-management/urls/#aliases) (complete rewrite)
- [Page methods: Aliases](https://gohugo.io/methods/page/aliases/) (complete rewrite)

---

<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:** [February 4, 2026, 3:34pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/2 "2026-02-04T15:34:50Z")

</div>

#### Amazing work on the docs (and Hugo)! 🙌🏻 🎉 And thanks for this post.

* * *

## Questions

### Q. Is there a semantic distinction between `foo` and `./foo`?

I’m asking because I’ve found it useful to distinguish between them for index pages, for example:

> content/en/docs/collector/\_index.md

```yaml
---
title: Collector
description: Vendor-agnostic way to receive, process and export telemetry data.
aliases: [./about]
...
---

```

Is a shorthand for

```yaml
---
title: Collector
description: Vendor-agnostic way to receive, process and export telemetry data.
aliases: [collector/about]
...
---

```

The interpretation of `./`, helps keep the alias path DRY.

Is this the current Hugo interpretation. If not, can it be? 🙂

### Q. How about in-page links?

I think that the new interpretation of page- and site-relative alias paths is great. It certainly matches my expectations, based on the use case of the projects I work on.

Is the plan to support the same interpretation in the (default) [link render hook](https://gohugo.io/render-hooks/links/)?

* * *

Regarding:

```yaml
languages: ['**']

```

Cool, I didn’t know we could write that.

---

<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 5, 2026, 6:51am UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/3 "2026-02-05T06:51:35Z")

</div>

> [@chalin](#):
>
> Is there a semantic distinction between `foo` and `./foo`?

Hugo interprets those paths in the same way that your OS does; there is no difference between `foo` and `./foo`. Interpreting those differently would be confusing, unexpected, and a departure from the universal standards of path resolution.

To be clear, with this content structure:

```plaintext
content/
└── en/
    ├── docs/
    │ ├── collector/
    │ │ └── _index.md
    │ └── _index.md
    └── _index.md

```

And with this front matter in `content/en/docs/collector/_index.md`:

```plaintext
---
title: Collector
aliases: [about]
---

```

The published site looks like this:

```plaintext
public/
├── de/
│ └── index.html
├── en/
│ ├── docs/
│ │ ├── about/
│ │ │ └── index.html
│ │ ├── collector/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
└── index.html

```

With this front matter:

```plaintext
---
title: Collector
aliases: [./about]
---

```

The published site looks like this (same as above):

```plaintext
public/
├── de/
│ └── index.html
├── en/
│ ├── docs/
│ │ ├── about/
│ │ │ └── index.html
│ │ ├── collector/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
└── index.html

```

With this front matter:

```plaintext
---
title: Collector
aliases: [collector/about]
---

```

The published site looks like this:

```plaintext
public/
├── de/
│ └── index.html
├── en/
│ ├── docs/
│ │ ├── collector/
│ │ │ ├── about/
│ │ │ │ └── index.html
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
└── index.html

```

> [@chalin](#):
>
> Is the plan to support the same interpretation in the (default) [link render hook](https://gohugo.io/render-hooks/links/)?

Unless I’m missing something, we already do. Try it:

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

```

---

<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:** [February 11, 2026, 11:15pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/4 "2026-02-11T23:15:28Z")

</div>

> [@jmooring](#):
>
> Unless I’m missing something, we already do. Try it:

Very cool test project! Thanks for putting that together. Hmm, has markdown link resolution always worked like this? (I think not, but I might have been mistaken) Anyhow, I’m glad it works that way (now)!

* * *

> [@jmooring](#):
>
> Hugo interprets those paths in the same way that your OS does; there is no difference between `foo` and `./foo`. Interpreting those differently would be confusing, unexpected, and a departure from the universal standards of path resolution.

You are right that for file systems, it’s natural for `foo` and `./foo` to refer to the same entity. But that isn’t “universal”. Examples:

- **POSIX shells** : `foo` searches `$PATH`; `./foo` means “run `foo` from current directory”.
- **Node.js** : `require('foo')` resolves a package/core module; `require('./foo')` resolves a local file.
- **Go tooling** : `go test foo` treats `foo` as an import path; `go test ./foo` means local directory `./foo`.
- **Ruby** : `require 'foo'` uses load path; `require './foo'` is explicit relative file.

So, in the context of an alias inside a Hugo index file, IMHO, it wouldn’t be unreasonable to interpret `./foo` as being relative to the folder containing the index file. _But_ I understand not wanting to interpret `./foo` in that way.

Thanks!

---

<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 11, 2026, 11:55pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/5 "2026-02-11T23:55:37Z")

</div>

> [@chalin](#):
>
> has markdown link resolution always worked like this?

If you are asking, “Have Hugo’s embedded link and render hooks always resolved link destinations like this?”, then the answer is yes.

---

<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:** [February 20, 2026, 4:20pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/6 "2026-02-20T16:20:29Z")

</div>

> [@jmooring](#):
>
> “Have Hugo’s embedded link and render hooks always resolved link destinations like this?”, then the answer is yes.

Wow, then I’ve had quite a misconception about this for a while! 😅 Thanks for helping me clarify that.

---

<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 24, 2026, 4:03pm UTC](https://discourse.gohugo.io/t/alias-paths-in-v0-155-0-and-later/56674/7 "2026-02-24T16:03:04Z")

</div>

A post was split to a new topic: [Help with server-relative aliases](https://discourse.gohugo.io/t/help-with-server-relative-aliases/56758)
