Auto-export on Saving

Wouldn’t it be awesome if you can see the live-preview of your Hugo-rendered post each time you saved your post in Org?

Well.. you can do that with these steps, which apply to both per-subtree and per-file flows:

First time setup #

Step 1: Require ox-hugo-auto-export package #

This package is part of the ox-hugo package installation. It implements the auto-exporting behavior on file saves. Among many other things, this package declares the buffer-local variable org-hugo-auto-export-on-save which is used to enable/disable the auto-exporting.

So with ox-hugo installed, add this to your Emacs config:

(require 'ox-hugo-auto-export)

or if using use-package:

(use-package ox-hugo-auto-export)

Step 2: Set org-hugo-auto-export-on-save #

This variable is nil by default, so that the auto-exporting feature can be enabled separately at project level or file level.

Enable for the whole project #

If you want to enable auto-exporting for the whole project, add this to the .dir-locals.el file in the project root:

(("content-org/"
  . ((org-mode . ((org-hugo-auto-export-on-save . t))))))

Above assumes that the Org files are in the “content-org”/ directory (at any nested level in there) relative to that .dir-locals.el file:

<HUGO_BASE_DIR>
  ├── config.toml
  ├── content
  ├── content-org      <-- Org files in there
  ├── static
  ├── themes
  └── .dir-locals.el

If you have the Org file directly in the project root or in the same directory as the .dir-locals.el, add this in that file instead:

((org-mode . ((org-hugo-auto-export-on-save . t))))

Note that with above, org-hugo-auto-export-on-save will be set to t for all Org files in the project. If that’s what you don’t want see Enable only for an Org file.

Enabling for multiple projects #

To enable auto-exporting for multiple projects, simply add similar .dir-locals.el files to the root directories of those projects. Just ensure that the relative Org file directories, like the “content-org”/ in above example, are set correctly.

Enable only for an Org file #

Add below to the very-end of your Org file and save the file:

* Footnotes
* COMMENT Local Variables                          :ARCHIVE:
# Local Variables:
# org-hugo-auto-export-on-save: t
# End:

About Footnotes: Here I recommend adding the * Footnotes header1 too so that in case you add any Org footnotes, they go directly to that section you created. Otherwise, Org will auto-create a new Footnotes heading at the end of the file.. and the Local Variables heading would then no longer be at the end of the file.

Enable for the whole project except for few Org files #

  1. Enable the auto-exporting for the whole project as explained above.
  2. Then add below to the very-end of the Org file where you need to disable the auto-exporting:

    * Footnotes* COMMENT Local Variables                          :ARCHIVE:
    # Local Variables:
    # org-hugo-auto-export-on-save: nil
    # End:

    Note that this time, org-hugo-auto-export-on-save is set to nil to override the t value set in the .dir-locals.el.

After updating the value of org-hugo-auto-export-on-save using either of the above methods, remember to (i) save the Org file where you expect the auto-exporting to work, and (ii) revert the buffer (M-x revert-buffer). That will ensure that the updated org-hugo-auto-export-on-save is effective.

Steps that might need to be taken every time #

Once the initial setup is done, the following steps apply to both blogging flows.

Step 3: Start the engines (Hugo Server) #

We start the hugo server so that we can see the live-preview each time the Org file is saved2.

Run below in your Hugo site root (the directory that contains the site config.toml) to start the server:

hugo server -D --navigateToChanged

Step 4: Open your browser #

By default the site is served locally on port 1313 on localhost. So the above step would have printed something like below at the end:

Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)

So open your favorite browser pointing to that address.

FINAL step that needs to be taken every time #

Step 5: Save and be in awe #

If you are like me, you might not need to repeat steps 3 and 4 above, as you can leave the hugo server running in a separate terminal, and have a browser tab pinned to that localhost.

So with that, have the Emacs and browser frames set up side-by-side, and edit your Org post.

Hit C-x C-s and be in awe as the browser auto-refreshes to the exact post you modified!


  1. I am assuming that the value of org-footnote-section in your Emacs setup is the default value "Footnotes". If it’s not, change the “Footnotes” heading in that example accordingly. [return]
  2. If you are still using a Hugo version older than 0.25, update now! – Because that version added support for the awesome --navigateToChanged switch. [return]
Fork me on GitHub