Generate Hugo Website as E-Book (epub)

The widely used e-book file format epub is actually just a zip folder with a fixed structure of XHTML files, images and some metadata. That’s why I came up with the idea to develop a HUGO theme that creates an e-book directly from the HUGO content folder without further manual intervention. This makes it possible, for example, to easily offer an existing HUGO blog for download as an e-book or to convert Markdown formatted texts directly into cleanly formatted, valid e-books.

So far the documentation is unfortunately only available in German language. If it is useful for other people, I will translate it into English. But the theme is mostly self-explanatory:

  • Just download and unpack.
  • The theme is ready to run immediately. The call of “hugo” in the HUGO root directory creates the demo e-book in the public folder – but unpacked yet.
  • To get the desired epub format, the content of the public folder has to be zipped. The zip archive must have the extension .epub. Done!
    Important: the file mimetype must be the first file in the zip archive. So the call of “zip” should (e.g.) be like this …
# hugo
# cd public
# zip -rX ../ebook.epub mimetype OEBPS META-INF

… to create an e-book named ebook.epub, which is located in the HUGO root directory

  • To avoid file garbage in the e-book, the files in public-folder and the zip/epub file should be deleted before the e-book is recreated. For Linux a deploy bash script is part of the theme, which does all steps automatically.
  • In order to create your own e-book, you only need to adjust the metadata in config.toml and replace the page resources in the content/posts/ folder with your own content in markdown format.
  • In addition, the file static/OEBPS/cover.jpg should be exchanged with your own cover (ideally in portrait format).

Download HUGO epub theme

Documentation (in German)


The switch --cleanDestinationDir can take care of that.


Nice project: have you the project to translate the documentation in English?

Maybe the translation of GoogleTranslate of this article is already enough for you? I will wait with the translation for a while, if there are still bugs or ideas for improvement.

1 Like

Hi, thanks a lot for sharing this interesting project! Do you have a github repo to follow the changes/improvents of the theme?

not yet.

Hi, I would like to use your theme for producing different outputs with Hugo (web, PDF, EPUB), what is the associated license? Are you ok if I create a public repository (GitHub or GitLab) with some parts of your work?


I have looked at your website. Very interesting what you are doing! You are welcome to use my theme for your purposes. I make my work in the sense of CC freely available to everyone. I saw that you publish under the Creative Commons BY-SA license. So I would be also happy about credits (including URL :smiley:

Please post a link to the repository here, if it’s available.

Peaceful 2nd Advent! :candle: :candle:


Oh thanks! I love to play with static site generators for publishing/editing workflows!
Sorry I’ve missed to mention that of course I will credit your work (readme of the repository, perhaps directly in the templates and config files, and in a post on my website).
I’m comeback here in few weeks when I build something!
:christmas_tree: :christmas_tree: :christmas_tree: :christmas_tree: :christmas_tree: :christmas_tree: :christmas_tree: :christmas_tree:

1 Like

Thank you. Great project.

  1. If I need to add NoIntrotext: true to all posts, where can I make it global?
  2. Is it possible to reverse the page order by global parameter?

Thank you very much.

Thanks @kentsin!

this theme is not finished yet and I published it primarily for developers. Therefore not everything is configurable yet. But you can easily change that yourself:

You can delete the line 35 in ./epub-theme/themes/epub/layouts/_default/single.xhtml

{{ if .Params.NoIntrotext }}{{ else }}<p class="introtext">{{ .Summary }}</p>{{ end }}

Add everywhere .Reverse where you can find this line:

{{ range ( where .Site.RegularPages "Section" "ne" "" ).ByPublishDate }}
{{ range ( where .Site.RegularPages "Section" "ne" "" ).ByPublishDate.Reverse }}

  1. ./epub-theme/themes/epub/layouts/_default/single.xhtml (line 25)
  2. ./epub-theme/themes/epub/layouts/s/index.ncx (line 33)
  3. ./epub-theme/themes/epub/layouts/s/index.opf (line 42 and line 62)

Now on Github (Thanks to pevaristo)

Github Repo:

Github Repo:


This look realy cool. A quick note: It would make it easier to use if you did not put the theme into a /themes sub folder – storing “everything” at the root level would make more sense.


You are right. I will release another proper theme soon.

1 Like

here it is: GitHub - weitblick/epub: An epub theme for the Static Site Generator HUGO.

This is my first theme. I hope, everything is fine. I am open to suggestions for improvement and support.

1 Like

english documentation: epub/ at main · weitblick/epub · GitHub

1 Like

Great work @emk :clap: I will test this very soon :smiley:
Just a quick question: do you think it’s possible to generate both en EPUB and a (more classical) website?

This is my personal reason why I developed the theme. I’ll write a blog article about it soon. In a nutshell:
I have a normal classic HUGO website (1) and additional the HUGO epub theme (2) as two separate HUGO projects.
For a deploy of the ebook I first copy the current content folder from (1) to (2) via shell script.
Normally you don’t want a website to become an ebook 1:1. In a website there are often many links or embedded code or text sections that are superfluous in the ebook, or you want to have an extra paragraph in the ebook …
That’s why I wrote some shortcodes to control that. Depending on the environment (ebook or website) certain content will be displayed or not or different (e.g. links as normal text).
Look at this example (website and ebook: Blog als E-Book runterladen | Weitblick Blog)

We’re doing pretty much the same thing with the darktable documentation, and this worked well when we were only generating a single language ePub. However, now we’re multilingual, and I’m having problems getting the OEPBS, mimetype and META-INF directories to copy into their respective language folders in hugo. Any idea on how to do that, besides just copying them in after the fact?

I’m sorry: multilangual is not my field of expertise