Hugo YouTube Playlist Shortcode

How to embed a Youtube playlist in a Hugo site with custom Shortcode

One time, I wanted to embed my YouTube playlist (not a single video) into my Hugo site, but I found that there is no built-in shortcode for that. So I created a custom shortcode for it.

The shortcode is very simple. I just modified it from the built-in Hugo YouTube shortcode.

YouTube Playlist Shortcode for Hugo

To create the shortcode, create a new HTML file named youtube-playlist.html inside the layouts/_shortcodes directory.

Here’s the YouTube playlist shortcode. Feel free to copy it:

  1{{- /*
  2Renders an embedded YouTube playlist.
  3
  4@param {bool} [allowFullScreen=true] Whether the iframe element can activate full screen mode.
  5@param {bool} [autoplay=false] Whether to automatically play the video. Forces mute to be true.
  6@param {string} [class] The class attribute of the wrapping div element. When specified, removes the style attributes from the iframe element and its wrapping div element.
  7@param {bool} [controls=true] Whether to display the video controls.
  8@param {int} [end] The time, measured in seconds from the start of the video, when the player should stop playing the video.
  9@param {string} [id] The YouTube playlist id. Optional if the id is the first and only positional argument.
 10@param {string} [loading=eager] The loading attribute of the iframe element.
 11@param {bool} [loop=false] Whether to indefinitely repeat the video. Ignores the start and end arguments after the first play.
 12@param {bool} [mute=false] Whether to mute the video. Always true when autoplay is true.
 13@param {int} [start] The time, measured in seconds from the start of the video, when the player should start playing the video.
 14@param {string} [title] The title attribute of the iframe element. Defaults to "YouTube video".
 15
 16@returns {template.HTML}
 17
 18@reference https://developers.google.com/youtube/player_parameters
 19
 20@example {{< youtube-playlist PLy4N_3BZ1ec3jGntdLBPVBV2TSTwySvrx >}}
 21@example {{< youtube-playlist id=PLy4N_3BZ1ec3jGntdLBPVBV2TSTwySvrx loading=lazy start=30 >}}
 22*/}}
 23
 24{{- $pc := .Page.Site.Config.Privacy.YouTube }}
 25{{- $remoteErrID := "err-youtube-remote" }}
 26{{- if not $pc.Disable }}
 27  {{- with $id := or (.Get "id") (.Get 0) }}
 28
 29    {{- /* Set defaults. */}}
 30    {{- $allowFullScreen := true }}
 31    {{- $autoplay := 0 }}
 32    {{- $class := "" }}
 33    {{- $controls := 1 }}
 34    {{- $end := 0 }}
 35    {{- $loading := "eager" }}
 36    {{- $loop := 0 }}
 37    {{- $mute := 0 }}
 38    {{- $start := 0 }}
 39    {{- $title := "YouTube Playlist" }}
 40    {{- $iframeAllowList := "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" }}
 41
 42    {{- /* Get arguments. */}}
 43    {{- if in (slice "true" true 1) ($.Get "allowFullScreen") }}
 44      {{- $allowFullScreen = true }}
 45    {{- else if in (slice "false" false 0) ($.Get "allowFullScreen") }}
 46      {{- $allowFullScreen = false }}
 47    {{- end }}
 48    {{- if in (slice "true" true 1) ($.Get "autoplay") }}
 49      {{- $autoplay = 1 }}
 50    {{- else if in (slice "false" false 0) ($.Get "autoplay") }}
 51      {{- $autoplay = 0 }}
 52    {{- end }}
 53    {{- if in (slice "true" true 1) ($.Get "controls") }}
 54      {{- $controls = 1 }}
 55    {{- else if in (slice "false" false 0) ($.Get "controls") }}
 56      {{- $controls = 0 }}
 57    {{- end }}
 58    {{- if in (slice "true" true 1) ($.Get "loop") }}
 59      {{- $loop = 1 }}
 60    {{- else if in (slice "false" false 0) ($.Get "loop") }}
 61      {{- $loop = 0 }}
 62    {{- end }}
 63    {{- if or (in (slice "true" true 1) ($.Get "mute")) $autoplay }}
 64      {{- $mute = 1 }}
 65    {{- else if in (slice "false" false 0) ($.Get "mute") }}
 66      {{- $mute = 0 }}
 67    {{- end }}
 68    {{- $class := or ($.Get "class") $class }}
 69    {{- $end := or ($.Get "end") $end }}
 70    {{- $loading := or ($.Get "loading") $loading }}
 71    {{- $start := or ($.Get "start") $start }}
 72    {{- $title := or ($.Get "title") $title }}
 73
 74    {{- /* Adjust iframeAllowList. */}}
 75    {{- if $allowFullScreen }}
 76      {{- $iframeAllowList = printf "%s; fullscreen" $iframeAllowList }}
 77    {{- end }}
 78
 79    {{- /* Define src attribute. */}}
 80    {{- $host := cond $pc.PrivacyEnhanced "www.youtube-nocookie.com" "www.youtube.com" }}
 81    {{- $src := printf "https://%s/embed/videoseries" $host }}
 82    {{- $params := dict
 83      "list" $id
 84      "autoplay" $autoplay
 85      "controls" $controls
 86      "end" $end
 87      "mute" $mute
 88      "start" $start
 89      "loop" $loop
 90    }}
 91    {{- if $loop }}
 92      {{- $params = merge $params (dict "playlist" $id) }}
 93    {{- end }}
 94    {{- with querify $params }}
 95      {{- $src = printf "%s?%s" $src . }}
 96    {{- end }}
 97
 98    {{- /* Set div attributes. */}}
 99    {{- $divStyle := "position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;" }}
100    {{- if $class }}
101      {{- $divStyle = "" }}
102    {{- end }}
103
104    {{- /* Set iframe attributes. */}}
105    {{- $iframeStyle := "position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" }}
106    {{- if $class }}
107      {{- $iframeStyle = "" }}
108    {{- end }}
109    {{- $referrerpolicy := "strict-origin-when-cross-origin" }}
110
111    {{- /* Render. */ -}}
112    <div
113      {{- with $class }} class="{{ . }}" {{- end }}
114      {{- with $divStyle }} style="{{ . | safeCSS }}" {{- end -}}
115    >
116      <iframe
117        {{- with $iframeAllowList }} allow="{{ . }}" {{- end }}
118        {{- with $loading }} loading="{{ . }}" {{- end }}
119        {{- with $referrerpolicy }} referrerpolicy="{{ . }}" {{- end }}
120        {{- with $src }} src="{{ . }}" {{- end }}
121        {{- with $iframeStyle}} style="{{ . | safeCSS }}" {{- end }}
122        {{- with $title }} title="{{ . }}" {{- end -}}
123      ></iframe>
124    </div>
125  {{- else }}
126    {{- errorf "The %q shortcode requires an id argument. See %s" .Name .Position }}
127  {{- end }}
128{{- end }}
layouts/_shortcodes/youtube-playlist.html

The changes I made from the built-in YouTube shortcode are:

  • Replaced $src value:
    • from: printf "https://%s/embed/%s" $host $id
    • to: printf "https://%s/embed/videoseries" $host.
  • Added the list parameter to $params.

Usage is simple and very similar to the built-in YouTube shortcode.

For example, if I want to embed a playlist from my YouTube channel https://www.youtube.com/playlist?list=PLy4N_3BZ1ec3jGntdLBPVBV2TSTwySvrx, the playlist ID is PLy4N_3BZ1ec3jGntdLBPVBV2TSTwySvrx.

So on my Hugo site, I would write:

{{< youtube-playlist PLy4N_3BZ1ec3jGntdLBPVBV2TSTwySvrx >}}

And here’s how it looks after it’s rendered:

Conclusion

That’s it for today’s post. You can now embed your YouTube playlist on your Hugo site easily.

As usual, if you have any questions or a better method, leave a comment below. Thanks for reading, and see you next time!

References