Contents

Migrating from ox-hugo

Keep your Org files, switch the exporter, and update the few Hugo-specific constructs that Zola does not share.

Quick start§

  1. Install ox-zola alongside ox-hugo.
  2. Change the export command from org-hugo-export-* to ox-zola-export-*.
  3. Export your posts. Most Org files need no changes.
;; Before, with ox-hugo
(org-hugo-export-wim-to-md)

;; After, with ox-zola
(ox-zola-export-wim-to-md)

Keywords§

Both HUGO_* and ZOLA_* keywords are recognized. You can keep existing keywords or migrate gradually:

;; These are equivalent
#+hugo_base_dir: ~/myblog
#+zola_base_dir: ~/myblog

#+hugo_section: posts
#+zola_section: posts

#+hugo_tags: emacs org-mode
#+zola_tags: emacs org-mode

Subtree properties§

Both Hugo-named and Zola-named properties are accepted. New files should use the Zola names:

Hugo propertyZola property
EXPORT_HUGO_SECTIONEXPORT_ZOLA_SECTION
EXPORT_HUGO_SECTION_FRAGEXPORT_ZOLA_SECTION_FRAG
EXPORT_HUGO_BUNDLEEXPORT_ZOLA_BUNDLE
EXPORT_HUGO_TAGSEXPORT_ZOLA_TAGS
EXPORT_HUGO_CATEGORIESEXPORT_ZOLA_CATEGORIES
EXPORT_HUGO_WEIGHTEXPORT_ZOLA_WEIGHT
EXPORT_HUGO_LAYOUTEXPORT_ZOLA_TEMPLATE
EXPORT_HUGO_AUTO_SET_LASTMODEXPORT_ZOLA_AUTO_SET_LASTMOD

Additional Zola-named keywords include ZOLA_AUTO_SET_LASTMOD, ZOLA_USE_CODE_FOR_KBD, ZOLA_PREFER_HYPHEN_IN_TAGS, ZOLA_ALLOW_SPACES_IN_TAGS, ZOLA_BUNDLE, ZOLA_DATE_FORMAT, ZOLA_LEVEL_OFFSET, ZOLA_CUSTOM_FRONT_MATTER, and ZOLA_FRONT_MATTER_KEY_REPLACE.

Subtree and file export§

The WIM export detects whether to export the current subtree or the whole file.

Front matter transformations§

Ox-Zola converts Hugo-specific front matter to Zola's shape:

HugoZolaNotes
lastmodupdatedRenamed
layouttemplateRenamed
tags: [...][taxonomies]Restructured
categories: [...][taxonomies]Restructured
menu, resources, outputsremovedZola does not use them

Example:

# Hugo front matter
+++
title = "My Post"
tags = ["emacs", "org"]
categories = ["tutorials"]
lastmod = 2024-01-15
layout = "post"
+++
# Zola front matter
+++
title = "My Post"
updated = 2024-01-15
template = "post.html"

[taxonomies]
tags = ["emacs", "org"]
categories = ["tutorials"]
+++

Hugo's relref shortcode is replaced with Zola's @/ path syntax:

# Hugo output
[other post]({{< relref "other.md" >}})
[heading]({{< relref "post.md#section" >}})

# Zola output
[other post](@/posts/other.md)
[heading](@/posts/post.md#section)

Shortcodes and components§

Hugo shortcodes do not map directly to Zola 0.23 components. Convert each one manually.

# Hugo paired shortcode
{{< quote >}}
Content here
{{< /quote >}}

# Zola 0.22 legacy shortcode syntax
{% quote() %}
Content here
{% end %}

# Zola 0.23 component call
{% <site.quote> %}
Content here
{% </site.quote> %}
# Hugo inline shortcode
{{< youtube abc123 >}}

# Zola 0.22 legacy shortcode syntax
{{ youtube(id="abc123") }}

# Zola 0.23 component call
{{<site.youtube id="abc123" />}}

If you still target Zola 0.22, ox-zola can emit the legacy shortcode syntax for Org special blocks. For 0.23 and newer, define and call Tera components instead. See Components and Special Blocks.

Figures§

For Zola 0.23 and newer, use a figure component or plain HTML:

<figure>
  <img src="/images/diagram.png" alt="Diagram">
  <figcaption>A caption</figcaption>
</figure>

The old Hugo and Zola shortcode forms are for legacy Zola versions only.

Page bundles§

Hugo and Zola differ in page bundle conventions:

HugoZola
content/posts/my-post/index.mdcontent/posts/my-post/index.md
Leaf bundleSection with _index.md or a page
resources front matterCo-located assets

Simple bundles containing a post and images work similarly. Complex Hugo bundles with resource processing need manual adjustment.

Manual changes§

  • Replace Hugo-specific export snippets with HTML or component calls.
  • Rewrite custom Hugo shortcodes as Tera components.
  • Remove Hugo menu configuration; Zola navigation lives in the template configuration instead.

Hugo's menu system does not exist in Zola. Remove #+hugo_menu entries and configure navigation in config.toml or the site templates.