Internal URL to download file

Hi everybody!

I just started with Hugo and I tried to something relatively simple and I have already tried to find an answer in the docs and the www. However, I could not find an answer.

I want to link a downloadable pdf on my page. The problem I face is that my hugo page is not in the root of my website. In particular my hugo page is in therefore I cannot just use [pdf](/downloads/file.pdf). My downloads folder is in /static/

I probably need the variable that gives the baseURL of the hugo project, which is defined in hugo.toml. I have found on this site (I am apparently not allowed to share real links because of my trust level) that there is this .Site.BaseURL variable. However, apparently I don’t know how to use it.

I have tried [pdf]({{.Site.BaseURL}}downloads/file.pdf) and also {{<ref path="{{.Site.BaseURL}}/downloads/file.pdf">}} and some modifications but it always fails to generate a link to the pdf.
the version with the <ref> tag triggers the following error:

ERROR 2023/06/13 14:58:25 [en] REF_NOT_FOUND: Ref "{{.Site.BaseURL}}/downloads/file.pdf": "/Users/path/to/hugo_folder/content/": page not found

Probably the answer to this is very easy but I fail to understand a very basic concept.
I tested this in the local environment hugo server.

Assuming a site config like this:

baseURL = ''

And this structure:

├── downloads/
│   └── a.pdf
└── favicon.ico

The simplest approach is this:


That is somewhat fragile—if you change your baseURL in the future, you’ll need to go back and edit your markdown.

The optimal approach is a link render hook. Let me know if you want to pursue that.

Thanks for this quick response!
I thought that manually adapt the link would work, but as you said this is fragile and probably not the way you should do it.
That is why I would like to use the baseURL variable as i can set it once and I don’t have to change all the internal links afterwards. I assume that is the very reason for this variable or at least on of the reasons.

Well, not really. In retrospect, that variable should never have been exposed to the templates. The right way to handle this is with a link render hook. For example:

git clone --single-branch -b hugo-forum-topic-44787 hugo-forum-topic-44787
cd hugo-forum-topic-44787
hugo server

Then visit http://localhost:1313/foo/

The important bits are in layouts/_default/_markup, and the PDF is in the assets directory instead of the static directory.

Thanks for your answer!
But I don’t really understand what is going on in this layouts/_default/_markup file. This feels ridiculously complicated to achieve a very intuitiv task.

Why is assets the right folder to store my downloads. In all tutorials pictures were stored in static.

Can I create a global variable on my own that saves where the root of the hugo website is compared to the root of my website and call it before every internal link.
Because for now my hugo website is in a subfolder of my website. However, maybe at some point I want to change this.

Dynamic content management systems (e.g., WordPress, Drupal) have routing systems. When you insert a link or image, the routing system queries the database to find the specified resource, then returns a URL based on site and page settings. The site and page settings include things like the base URL, transliteration, path overrides, redirects, language, revision, format, etc.

Hugo, a static content management system, does not have a routing system. By default, the destinations in your markdown links and images are rendered as-is, conforming to the CommonMark specification. However, Hugo’s site and page settings can alter the target URL of pages and resources. So, if you link to “A”, and the site and/or page settings change the target URL to “B”, your link will be broken.

Hugo’s markdown render hooks can bridge the gap, properly resolving destinations in markdown links and images based on site and page settings. Conceptually, link and image render hooks can serve as a routing system.

The key to making this work is to:

  1. Resolve link destinations to a page, page resource, or global resource
  2. Resolve image destinations to a page resource or global resource

Page resources are located within a page bundle. Global resources are located in the assets directory or in directories mounted to assets.

Your “very intuitive task” is just the tip of the iceberg. My “ridiculously complicated” examples help you to avoid the entire iceberg.

1 Like

Thank you for the explanation. I did not want to offend you by my comment that “it feels ridiculously complicated”. I am just surprised that this is not expected as a common task. Moving parts of my webspace into a different directory does not seem very exotic. Hence, I suspected that many people before me ran into this issue. Apparently hugo is not designed to provide a quick solution for that. So I have to dig into machinery of hugo to understand your elaborate solution.

Or you just use it and move on.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.