Confusion with baseURL

Hi there, long time user, first time poster…

I’m confused on how I should use baseURL.

I used Hugo to build a 2000+ page website which has been very well received (people can’t believe there’s no database stuff going on!). It sits at the top of its domain, and so I had baseURL pointing to the domain.

I’ve now moved it under an official directory structure, and modified the baseURL accordingly. The site is now working fine, but in doing the move, I’ve found that I don’t understand how baseURL works at all - to get things to work, I had to replace .Site.BaseURL with my own creation .Site.Params.mybaseurl - ugly :(.

I’m using the latest Hugo, Hugo Static Site Generator v0.40.3 darwin/amd64 BuildDate: and have built a barebones site to try this out.


baseURL = ""
languageCode = "en-us"
title = "My New Hugo Site, using"
theme = "simple"

I deliberately chose as I thought using might trigger some internal code.

The ‘theme’ simple, is something I built just to test things, the file at themes/simple/layouts/_default/single.html is just this (literally, I removed the html boilerplate):


.Site.Title: {{ .Site.Title }} <br>
.Site.BaseURL: {{ .Site.BaseURL }} <br>

{{ .Content }}

I then created a page $ hugo new post/ and put some content in it (flipped draft to false, and put ‘Hello World’ in). When I navigate to http://localhost:1313/post/start/ this is what I see;


.Site.Title: My New Hugo Site, using 
.Site.BaseURL: http://localhost:1313/ 
Hello World

It seems that the output .Site.BaseURL bears no relation to the value in config.toml?

I also found that the case of the parameter in the template is really important. You’ll see that the template is using .Site.BaseURL whilst config.toml is baseURL - that works (but the .Site.BaseURL still doesn’t show the value in config.toml. I changed the parameter in config.toml to be baseurl = "" and the site still showed output.

What didn’t work though, is changing the case in the template, if I edit simple.html like this, the site won’t build;


.Site.Title: {{ .Site.Title }} <br>
.Site.BaseURL: {{ .Site.BaseURL }} <br>
.Site.baseurl {{ .Site.baseurl }} <br>
{{ .Content }}

and gives this error;

ERROR 2018/05/24 11:09:41 Error while rendering "page" in "post/": template: theme/_default/single.html:6:26: executing "theme/_default/single.html" at <.Site.baseurl>: can't evaluate field baseurl in type *hugolib.SiteInfo

Can anyone shed some light on this? I’m grateful things are working with my dreadful kludge, but I suspect I’m missing something pretty fundamental here. Also, any clarification on the ‘casedness’ of parameters in config.toml would be appreciated!

many thanks,

1 Like

Because you’re running hugo server it overrides baseURL to be localhost:1313 - because that’s where your test server is running. If it returned then links on your site wouldn’t work whilst you’re.

If you build your site (just run hugo) then the html files that get output in the public folder will have the BaseURL value from your config.toml in them.

1 Like

Thanks for that, it makes a lot of sense.

Hugo seems to override the domain and port part of baseURL and replace that with localhost:1313 (by default). As you say, if you build the site (just run hugo) and look in public, you’ll find the html files have been properly expanded.

I found that I was making a really stupid mistake as well, I was referring to the config baseURL in my templates as .Site.Params.baseURL, instead of .Site.BaseURL. The former is always blank (unless there is a .baseURL in the [params] block) - I tried it with .Site.Params.reallyNotHere and got a blank - no build error, just blank, whilst the latter is the value of the baseURL config parameter.

Because I was deploying the site at the root level, I never saw this issue.

Now, I have some find-and-replace to do…

The case-ness of the config parameters still confuses me though; for parameters in a [params] block, the case of the parameter seems to be ignored in the config and template. For parameters at the top level (eg our friend baseURL), the case in the config file seems irrelevant, but when they are accessed in templates they are very much case-dependent. The configuration documentation has a long list of configuration options, but it’s not obvious how they should be referred to in templates. I suppose that’s for another day…

Thanks again for the clarification, it’s very helpful.

In my development I use BrowserSync (with Gulp) to serve the site instead of hugo server. This gives the advantage that you can connect your other devices to the Dev-URL as well and every change is reflected there. Fantastic. In the development environment I have baseURL: "/" and in production environment I use the config-chain config.toml, config_prod.toml where the 2nd config overwrites the baseURL with the production url (e. g. https://domain.tld).

In the same manner I have the environments stage and local as well.

Perhaps this helps.


Thank you, it does help - particularly around using multiple configs in a chain. It’s something I used to do in Django, but hadn’t thought about it with Hugo.

BrowserSync also looks fascinating - I’ll give that a good look over.


A post was split to a new topic: Confusion regarding baseURL