# Template menu generation .URL messed up using relativeURLs: true

**URL:** <https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527>\
**Category:** support\
**Created:** [June 16, 2016, 8:35pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527 "2016-06-16T20:35:01Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![fnurl](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/fnurl/32/1592_2.png) [@fnurl](https://discourse.gohugo.io/u/fnurl)\
**Post date:** [June 16, 2016, 8:35pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/1 "2016-06-16T20:35:01Z")

</div>

I wanted to use relative URLs because that would make writing markdown links easier. Given me having

```
BaseURL: "http://www.example.com/~userdir"

```

in my `config.yaml`.

My goal was to be able to link to it using the following markdown

```
blabla [page1](/section1/page1) blablabla

```

to link to the file `content/section1/page1.md` where the `/` would refer to the `BaseURL`. This worked great, but unfortunately my menu generated by my template got messed up. `{{ .URL }}` ended up being rendered as `http://www.example.com/~userdir/~userdir/section/page`.

Here is my menu template for reference (basically the [snippet shown in the documentation](https://gohugo.io/extras/menus/)):

```
{{ $currentNode := . }}
{{ range .Site.Menus.main }}
  <!-- output child elements -->
  {{ if .HasChildren }}
            <!-- first the lvl 1 node -->
            <li {{ if $currentNode.HasMenuCurrent "main" . }} class="active section"{{ else }} class="inactive section"{{ end }}><a href="{{ .URL }}">{{ .Name }}</a>
              <!-- then the children inside a <ul> using range .Children where . refers to a child node -->
              <ul {{ if $currentNode.HasMenuCurrent "main" . }} class="expanded"{{ else }} class="collapsed"{{ end }}>
    {{ range .Children }}
                  <li {{if $currentNode.IsMenuCurrent "main" . }} class="active"{{ end }}><a href="{{ .URL }}">{{ .Name }}</a></li>
    {{ end }}
              </ul>
            </li>
  <!-- no child elements, so just output the top node -->
  {{ else }}
            <li {{if $currentNode.IsMenuCurrent "main" . }} class="active"{{ end }}><a href="{{ .URL }}">{{ .Name }}</a></li>
  {{ end }}
{{ end }}

```

Anybody have any idea on what might be causing this?

---

<div class="post-metadata">

**Author:** ![digitalcraftsman](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/digitalcraftsman/32/4142_2.png) [@digitalcraftsman](https://discourse.gohugo.io/u/digitalcraftsman)\
**Post date:** [June 16, 2016, 8:55pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/2 "2016-06-16T20:55:12Z")

</div>

It seems that `.URL` is built prepended with the base url by default. You can use the `relURL` template function to get the relative url that you expected.

---

<div class="post-metadata">

**Author:** ![fnurl](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/fnurl/32/1592_2.png) [@fnurl](https://discourse.gohugo.io/u/fnurl)\
**Post date:** [June 16, 2016, 10:17pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/3 "2016-06-16T22:17:29Z")

</div>

Thanks for the help, however, what I had to use was `absURL`!

I was a bit wrong in my original post as I hovered the links rather than checking the source. Google Chrome showed the link as `http://www.example.com/~userdir/~userdir/section/page2` but they were actually rendered as `../~userdir/section1/page2`. So rather than just having `{{ .URL }}` I had to use `{{ .URL | absURL }}`.

This might however be a bug, since the real relative URL given that my current URL was `http://www.example.com/~userdir/section1/page1` should have been `./page2` or `../section1/page2`.

Is this a bug?

---

<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:** [June 16, 2016, 10:32pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/4 "2016-06-16T22:32:22Z")

</div>

> [@fnurl](#):
>
> This might however be a bug, since the real relative URL given that my current URL was [http://www.example.com/~userdir/section1/page1](http://www.example.com/~userdir/section1/page1) should have been ./page2 or …/section1/page2.
> 
> Is this a bug?

That doesn’t make much sense.

---

<div class="post-metadata">

**Author:** ![fnurl](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/fnurl/32/1592_2.png) [@fnurl](https://discourse.gohugo.io/u/fnurl)\
**Post date:** [June 17, 2016, 9:09am UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/5 "2016-06-17T09:09:56Z")

</div>

> [@bep](#):
>
> That doesn’t make much sense.

Yes, I realized that it might be a trailing slash issue that I had not paid any attention to (what the browser interpretes the current location as).

What I mean is that if the current page is

```
URL1: http://www.example.com/~userdir/section1/page1/

```

and I have a second page at

```
URL2: http://www.example.com/~userdir/section1/page2/

```

the _relative URL_ to `URL2` from `URL1` should be one of the following (as they are equivalent)

```
../page2
../../section1/page2/
../../../~userdir/section1/page2/

```

What Hugo gave me was

```
URL3: ../~userdir/section1/page2

```

which would have been correct if the current `URL` had been `http://www.example.com/~userdir/section1/page1` i.e. `URL1` without the trailing slash.

Could it be that the internal representation of the `URL` is without a trailing slash but when the browser visits the `URL` a trailing slash is added since it is a directory when using pretty `URL`s?

I tried switching to `uglyurls: true` which does not have any issues with the generated relative `URL`s.

_Edit_: … unless I am on an `index.html` page whose `URL` is shown without the actual `index.html` just the parent directory with a trailing slash.

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [June 17, 2016, 2:25pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/6 "2016-06-17T14:25:02Z")

</div>

@fnurl,  
I think you are misunderstanding what Hugo means by a _relative URL_ (I initially tripped over this, too). A _relative URL_ is simply a URL **path** without a hostname (or user, scheme, etc). It doesn’t mean that the path itself is a relative path. So, `../page2/` and `/~userdir/section1/page2/` are both _relative URLs_ to Hugo.

What you are talking about is canonicalization of relative URLs. Read the [docs](https://gohugo.io/extras/urls#canonicalization) and look over the [relURL test cases](https://github.com/spf13/hugo/blob/8b54843a0db694facbaf368af4e777d0ae5fb992/helpers/url_test.go#L81-L90) to see how `canonifyURLs` works.

---

<div class="post-metadata">

**Author:** ![fnurl](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/fnurl/32/1592_2.png) [@fnurl](https://discourse.gohugo.io/u/fnurl)\
**Post date:** [June 22, 2016, 6:47pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/7 "2016-06-22T18:47:21Z")

</div>

Ah, ok. Then I get it. Thanks for the info and the link to the test cases!

---

<div class="post-metadata">

**Author:** ![Rob\_Arnold](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/rob_arnold/32/1923_2.png) [@Rob\_Arnold](https://discourse.gohugo.io/u/Rob_Arnold)\
**Post date:** [January 29, 2017, 4:59pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/8 "2017-01-29T16:59:53Z")

</div>

I kind of think the responses went off on a tangent to the original issue after the first (and helpful) response by digitalcraftsman.

The menu implementation in Hugo does prepend the URLs or do some version of relURL type manipulation of them. The issue is that the relativeURLs setting _also_ does it’s thing. While on a site hosted directly at a root dir level (base URL “/”) that’s no big deal, it breaks under project rooted sites.

Given the config setting below, the actual url `<a href="{{ .URL }}">` writes in the html file is `<a href="./examplesite/tags">`. (as was understood above)

The suggestion to use relURL to get the relative url you expect doesn’t make sense to me. You almost need the opposite 🙂 - a way to get back the original url so that relativeURL can process the original. If you cal relURL on .URL you’ll just end up getting another level of the path components of baseurl.  
For  
[[menu.main]]  
name = "tags"  
url = "/tags"  
identifier = "fa fa-tags"  
weight = 5

`{{ printf "(%#v), relurl is (%s)" .URL (relURL .URL) }}` prints:  
`(&#34;/examplesite/tags&#34;), relurl is (/examplesite/examplesite/tags)`

I guess one could get the base url from the site variables and do a string edit to remove it from the .URL, but seems hacky. The nav bar implementation is often in theme code, and it’s always nice if theme code would actually work without requiring or assuming final site destination (subdir vs. root) or config settings like relativeURL, canonifyURLs, etc.

I know this is an old topic, but I think it’s still a relevant and open one. Is there a best practices topic for writing good url handling in themes, site buildings, etc. taking into account relative urls? Any suggestion on what the cleanest thing to do in this situation would be? As the original poster discovered, you could punt on the issue and use absURL but that blows the benefits of staying relative away of course.

---

<div class="post-metadata">

**Author:** ![Rob\_Arnold](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/rob_arnold/32/1923_2.png) [@Rob\_Arnold](https://discourse.gohugo.io/u/Rob_Arnold)\
**Post date:** [February 13, 2017, 9:32pm UTC](https://discourse.gohugo.io/t/template-menu-generation-url-messed-up-using-relativeurls-true/3527/9 "2017-02-13T21:32:35Z")

</div>

Note linked topic. If `relativeURLs=true` then setting `canonifyURLs=true` will make the URL manipulation done by the menu code not include context root, and therefore not get the path doubled as I posted above. In this case, the `canonifyURLs=true` will _not_ make all the relative urls canonicalized into absolute urls as one might expect given the docs.

> **[CanonifyURLs & RelativeURLs interaction](https://discourse.gohugo.io/t/canonifyurls-relativeurls-interaction/5448)**
>
> PSA: CanonifyURLs and RelativeURLs interact with each other, and in particular if you use RelativeURLs=true, you may want to use CanonifyURLs=true also. If both are true, CanonifyURLs will not actually canonify all your relative urls… It will...
