Add Edit with VSCode to your local Hugo site.

Hugo is a great static site generator. This site you are visiting right now is powered by Hugo. With Hugo, I can manage my entire site using Git. It works along with CI services, such as the service provided by Netlify. By pushing commits to the repo, Netlify will automatically rebuild and publish the entire site in a minute. If you don’t like playing with Git, there is also the Netlify CMS, which provides a web interface for managing the content of your Hugo site.

Why run Hugo locally?

I want to mirror that experience locally, on my own computer. One reason for that is I keep notes in Markdown and manage them with Git. This simple methodology has immense power. First, there are a bunch of editors that work greatly on Markdown (One example would be VSCode). Second, Git keeps your notes in sync and the history of the notes in place. Plus, that git grep is a lighting fast way to search notes.

Although raw Markdown is awesome, I’d like to view Markdown as web pages from time to time. I want these Markdown files organized and present themselves nicely with links and images. That’s where Hugo comes in, it builds Markdown files to a static website.

There are tons of similar tools out there, but Hugo is the fastest one, it builds your site in a blink. Most such tools can’t even finish a build in a breadth.

A shortcoming on the workflow

However, there is a shortcoming in the workflow. It comes from the nature of all static site generators. When you’re browsing a generated web page, you find there is a typo there and you want to correct it. Then you have to go all the way back, locate the source file (e.g. the Markdown file) that is used to generate the web page. You fix the typo in the source file. After that, you run the tool chain again, to re-build the web page. If you are unlucky, some generators would re-build the whole site.

If you host the static website online, there are some ways to remedy this tedious workflow related problem. For example, if you host it on GitHub Pages, you can use the online editor provided by GitHub to update the source file accordingly. Other options are available, you can use a “backend” to act as a CMS (Content Management System) to help manage and update source files. Netlify CMS is one of such options. You can view more options on Headless CMS.

Edit source files with local editors

As mentioned earlier in the post, we intend to run a Hugo site locally. For a local site, running a local Headless CMS to help manage and update source files is possible but would seem extravagance. Why not just make use of your favorite editors on your computer, for example, VSCode (Visual Studio Code), Sublime Text, Vim, Emacs, etc.

To be more specifically, can the generated web page contain a link. That by clicking on the link, a local editor is launched and with the source file opened in it? It’s kind of like “Edit the source in XXX”, where “XXX” is your favorite editor.

Edit the source in VSCode

Let’s do the VSCode version of “Edit the source in XXX”.

As of version 1.23, VSCode adds a support for Protocol Handler API, which enables your to do things like cloning a Git repository by visiting a URI (e.g. vscode://vscode.git/clone?url=foobar) , or opening a file through a URI (e.g. vscode://file/C:/Users/name/file.md). The latter case is documented in Opening VS Code with URLs.

With that functionality at hand, all you need to do is provide a URI link on the web page. So that by clicking on the URI link, the browser launches VSCode with the local file specified in the URI link.

Note that at present VSCode only supports [Protocol Handler API] on Windows and macOS.

Hugo theme support

Your Hugo theme must support that “Edit the source in VSCode” link. A suitable Hugo them is DocDock. On each page generated by DocDock, there is a link on the bottom named Improve this page. All we need to do is to customize Improve this page for VSCode. For doing that, just configure the following parameter editURL in Hugo’s config file config.toml:

# the example is for Windows

[params]
editURL = "vscode://file/C:/Users/name/hugosite/content/"

After pointing editURL to the content directory of your Hugo site, DocDock will use it to generate the URI needed by VSCode.

SafeURL issue

There is one more issue needs to be resolved. As Hugo is programmed in golang, the template library of golang only allows URI to start with a few prefixes, for instance, http, https etc. vscode is not in them. So, for security concerns, the URL vscode://file/C:/Users/name/file.md will be translated into something like #ZgotmplZ. To disable this for vscode:// URIs, you have to use the safeURL function provided by Hugo. safeURL tells that a URI is safe, and not translation is required.

Speaking of DocDock we use, we must do a little update on it: Copy the partials/flex/body-aftercontent.html from DocDock to your Hugo site root, keeping the directory levels that html file. Then change the following content:

    <div class="github-link">
      <a href="{{ .Site.Params.editURL }}{{ replace .File.Dir "\\" "/" }}{{ .File.LogicalName }}" target="blank"><i class="fa fa-code-fork"></i>
        {{T "Edit-this-page"}}</a>
    </div>

into

    <div class="github-link">
      <a href="{{ (print (.Site.Params.editURL) (replace .File.Dir "\\" "/") (.File.LogicalName) ) | safeURL}}"><i class="fa fa-code-fork"></i>
        {{T "Edit-this-page"}}</a>
    </div>

Then all is set and done. You can use Hugo (DocDock) with VSCode hand in hand.

Other References