Problem

At the time of writing this post, this website uses Hugo and the Terminal theme by panr. I really like the way this theme handles content and Markdown integration, but there is no native support for videos. This is probably due to the fact that there currently is no way to embed videos in Markdown files, unlike images for example.

This problem reared its head when I was writing my first Pokémon Emerald romhack post. At the time, I planned to use GIFs to illustrate the changes made to the game. However, I quickly realised that GIFs take up a lot of memory and can take quite long to load for readers, contrary to videos, MP4 in our case, which are up to 10 times smaller !

$ du -h static/captures/birch_speech_original.gif
3.1M static/captures/birch_speech_original.gif

$ du -h static/captures/birch_speech_original.mp4
332K static/captures/birch_speech_original.mp4

Solution

The answer to our solution comes in the form of Hugo “shortcodes”. Shortcodes are a way to bridge the gap from Markdown to HTML. Therefore, we can use one to handle integrating videos in our posts' Markdown files.

To get started create a shortcodes sub-directory in your layouts folder. Once that is done create a video.html file in layouts/shortcodes/. The shortcode’s code is as follows:

<video autoplay loop muted playsinline aria-label='{{ .Get "label"}}' style="width: 100%; height: auto;">
    {{ with .Get "mp4" }}<source src="{{ . }}" type="video/mp4">{{ end }}
    {{ with .Get "webm" }}<source src="{{ . }}" type="video/webm">{{ end }}
    <p> Your browser does not support video. </p>
</video>

The syntax is explicit enough to get a basic grasp of how it works. Our shortcode takes three possible parameters: label, mp4, and webm. If label is defined, its contents become the aria-label of the video HTML element. If mp4 or webm is defined, their contents become the source for the video element.

The rest of the shortcode is plain HTML, with inlined style to make it “responsive” and readable on mobile devices.

Using the shortcode in a post’s Markdown file goes like this:

{{< video label="this is a label" mp4="/path/to/video.mp4" >}}

I hope this helps you if you encounter the same problem, good luck!