Build an "Edit Page" button in a Hugo template
Tags: hugo, jamstack
Published: 2021-12-05 21:14:45

---
title: Build an "Edit Page" button in a Hugo template
published: true
description: Build a button that opens the markdown file for the current page in VS Code.
tags: Hugo, JAMstack
---

One of the downsides of using a static site generator is that the content directory can become difficult to navigate once a site has more than ten pages. Sometimes it would be easier to find a page in the browser than in a code editor.

Platforms like WordPress show "edit page" buttons to logged-in users who are viewing the site. Wouldn't it be nice if Hugo could display an edit page button that launched the current page's markdown file in VS Code?

It can.

## Building an "edit page" button

Add the following to the project's `config.toml` file to allow Hugo to access the system's `PWD` environment variable:

```toml
# config.toml

[security]
  [security.funcs]
    getenv = ['^HUGO_', 'PWD']
```

The following markup will display an "edit page" button (it's actually a link) when the site environment is set to `development`:

```html
{{ if eq hugo.Environment "development" }}
  {{ $projectPath := or (os.Getenv "HUGO_PROJECT_PATH" ) (os.Getenv "PWD") }}
  <a 
    href="vscode://file/{{ $projectPath }}/content/{{ .File.Path }}"
    class="button"
  >
    Edit Page
  </a>
{{ end }}
```

Let's break down what's happening.

## Checking the environment

```html
{{ if eq hugo.Environment "development" }}
   ...markup
{{ end }}
```

This conditional will show the "edit page" link when you're running the server with `hugo server`. When you build the site with `hugo`, the site environment will be set to `production` so the link won't be displayed. 

You can also manually set the environment from the command line by using the `-e` flag. If you wanted to see how the site looks in a `production` environment while running the development server, you could start Hugo by running `hugo server -e production`.

You can learn more about setting the environment by reading my post: [How to check if a Hugo site is in development or production](https://dev.to/tylerlwsmith/check-if-a-hugo-site-is-in-development-or-production-2beb). 

### Getting the absolute project path

```html
{{ $projectPath := or (os.Getenv "HUGO_PROJECT_PATH" ) (os.Getenv "PWD") }}
```

The code above will set the project path to an environment variable called `HUGO_PROJECT_PATH`, and if it's not defined it will use the current working directory (`PWD`) where you ran the `hugo` command. 

You can probably ignore the `HUGO_PROJECT_PATH` variable: it exists to prevent uncommon edge cases. You can read more about why I use `HUGO_PROJECT_PATH` in my post: [Get the absolute path to the project directory in Hugo](https://dev.to/tylerlwsmith/get-the-absolute-path-to-the-project-directory-in-hugo-4c1b).

### Using a VS Code URL handler

```html
# Only showing the relevant segments of the href
<a
  href="vscode://file/..."
>
```

VS Code has the ability to open files using URLs via its URL handling mechanism. You can read more about that in the [Opening VS Code with URLs](https://code.visualstudio.com/docs/editor/command-line#_opening-vs-code-with-urls) documentation.

### Getting the markdown file path

```html
# Only showing the relevant segments of the href
<a
  href=".../content/{{ .File.Path }}"
>
```

The code above will display the path of the current page's markdown file _relative to the project's content directory_. Because the path is relative to the content directory, we explicitly include the `/content/` segment in the URL path.

You can read more about this in Hugo's [File Variables](https://gohugo.io/variables/files/) documentation.

---

I hope this post helps you manage the content in your Hugo sites. Please leave a like or comment if you found this helpful!