DEV Community

Tyler Smith
Tyler Smith

Posted on • Edited on

Get the absolute path to the project directory in Hugo

Hugo doesn't seem to make it possible to get the absolute path of the project directory: all of its filesystem functions use the main project directory as the root. However, there may be times that you want to know the absolute path to the project, like if you wanted to build an "edit" link on your posts that would open the markdown file in VS Code.

Though Hugo doesn't provide access to the project path directly, we can grab it using the system's environment variables.

By default, Hugo can only access variables that are prefixed with HUGO_. Therefore, we must explicitly give Hugo access to the $PWD system environment variable. Add the following to the project's config.toml file:

# config.toml

[security]
  [security.funcs]
    getenv = ['^HUGO_', 'PWD']
Enter fullscreen mode Exit fullscreen mode

Now you can use the $PWD environment variable in your Hugo template:

<p>The working directory is {{ os.Getenv "PWD" }}</p>
Enter fullscreen mode Exit fullscreen mode

This will print the $PWD shell environment variable, which is the current working directory. If you ran hugo from your project's main directory, PWD will be the absolute path to that directory.

Considering edge cases

The code above will work in 95% of cases: most people run the hugo command from the main project directory. However, Hugo lets you specify any project directory with the --source flag.

hugo --source /path/to/project
Enter fullscreen mode Exit fullscreen mode

In this case, PWD would give you whatever directory you ran this command from, which probably isn't the project directory.

In this case, you could use an environment variable to specify the project path:

HUGO_PROJECT_PATH=/path/to/project hugo --source /path/to/project
Enter fullscreen mode Exit fullscreen mode

You can now access the HUGO_PROJECT_PATH variable in your template using the following:

<p>
  The HUGO_PROJECT_PATH variable is
  {{ os.Getenv "HUGO_PROJECT_PATH" }}
</p>
Enter fullscreen mode Exit fullscreen mode

If you wanted to use the HUGO_PROJECT_PATH variable if it is set, and fallback to PWD if it's not, you could do that with the following:

{{ or (os.Getenv "HUGO_PROJECT_PATH") (os.Getenv "PWD") }}
Enter fullscreen mode Exit fullscreen mode

On the other hand, maybe you want to make HUGO_PROJECT_PATH a required variable for Hugo to even start. You can do that by throwing an error if the project path isn't set.

{{ if os.Getenv "HUGO_PROJECT_PATH" }}
  {{ os.Getenv "HUGO_PROJECT_PATH" }}
{{ else }}
  {{ errorf "Must have a HUGO_PROJECT_PATH environment variable to run project" }}
{{ end }}
Enter fullscreen mode Exit fullscreen mode

In an ideal world, Hugo would provide a first-class way to access the project directory within your templates. Since it doesn't seem to do that at the time of writing (December 2021), these workarounds might be good enough for now.

Top comments (0)