There are times when I want to include a YouTube video in a post, but I’m not content with a regular link. YouTube
provides embeds for this purpose, but they use <iframe>
and come with a hefty JavaScript payload.
Among other things, this payload tracks visitors on my site if they play a video embedded in one of my posts. I don’t
particularly like the idea of Google tracking people visitingmy website; if I wanted Google to have any
information about my visitors I’d run Google Analytics.
yttget
: An Alternative to YouTube Embeds
If I don’t want embeds because of JavaScript and analytics, but plain links are too bland, what can I do? I can wrap a thumbnail inside a link with a tooltip and caption advising visitors to click the image to watch the video, and have the link open in a new tab.
Every video has an unique identifier, such as “o0W91FrTlYk”. This identifier represents the official video for “End of the
Beginning” by Black Sabbath. You can get the ID out of the URL for a particular video, which in this case
ishttps://www.youtube.com/watch?v=o0W91FrTlYk
. Once you have the ID, you can retrieve its associated
thumbnail, which currently lives at http://i3.ytimg.com/vi/o0W91FrTlYk/hqdefault.jpg
If you’re on a Unix-like machine1, you can automate the process of extracting the ID from a given YouTube URL and fetching its thumbnail with a
reasonably small shell script. You can even have this script create HTML for displaying the thumbnail and pipe it to
your clipboard. I did that myself with a little script I callyttget
, for “YouTube Thumbnail GET”2. Here’s the code, sans license
text.
#!/bin/sh -e
URL="$1"
ID=$(echo $URL | cut -d = -f 2)
FILENAME="youtube-${ID}"
CWD=$(pwd)
JPG="${CWD}/${FILENAME}.jpg"
THUMB_URL="http://i3.ytimg.com/vi/${ID}/hqdefault.jpg"
CAPTION="click to view"
curl ${THUMB_URL} --output ${JPG}
echo "<figure>
<a href=\"https://www.youtube.com/watch?v=${ID}\"
title=\"${CAPTION}\"
target=\"_blank\"
rel=\"noreferrer noopener nofollow\">
<picture>
<source srcset=\"/media/${FILENAME}.avif\" type=\"image/avif\">
<source srcset=\"/media/${FILENAME}.webp\" type=\"image/webp\">
<source srcset=\"/media/${FILENAME}.jpg\" type=\"image/jpeg\">
<img src=\"media/${FILENAME}.jpg\"
alt=\"preview image for YouTube video ID ${ID}\"
width=\"480\"
loading=\"lazy\">
</picture>
</a>
<figcaption>(${CAPTION})</figcaption>
</figure>" | pbcopy
yttget
It should run on any system that provides a POSIX-compliant shell, and requires curl
. Since I’m on a
Mac I use pbcopy
to pipe standard output into the system’s clipboard, but people using GNU/Linux or
BSD can easily replace it with xclip
or xsel
. Hell, you could probably replace curl
with wget
if you wanted to, but I couldn’t be bothered.
Using yttget
Here’s how you use yttget
. (Don’t forget to replace the URL unless you really like Black Sabbath.)
- Navigate to the directory in which you want to place the thumbnail.
- Type
yttget "https://www.youtube.com/watch?v=o0W91FrTlYk"
3 - Paste the resulting HTML into your editor.
The script generates HTML, particularly a <picture>
element wrapped inside a <figure>
. You should edit this to taste, especially if you don’t want to deal with generating WEBP and
AVIF files from JPEG images. You can paste it directly into a HTML or Markdown file. You can also use this with Org mode in GNU Emacs, but you’ll need to
wrap it in a #+BEGIN_EXPORT html
block. You should also add text inside the <figcaption>
for your readers’ benefit.
Once you do, it should look like something like this when rendered.

The link has rel="noreferrer noopener nofollow"
for security and SEO reasons. The first two, noreferrer
and noopener
,
mitigate exploits involving the JavaScipt function window.open()
. The use of nofollow
means that I’m not giving YouTube any “link juice”, which it shouldn’t need anyway because it’s user-generated
content and Google owns it.
Getting yttget
You can grab a copy here. It’s available under the zero-clase BSD license.
Tools Used in yttget
curl
(tutorial)cut
(manual page)echo
(manual page)
Extra: Generating Alternate Image Formats
If you want to use the <picture>
element to serve more modern image formats like WEBP and
AVIF, you’ll need to generate these formats from the JPEG you downloaded from YouTube. You can do this with ImageMagick, which provides
a suite of command-line image processing tools. The patch looks something like this:
diff --git a/media/yttget.sh b/Users/starbreaker/bin/yttget
index a692369..beb2458 100755--- a/media/yttget.sh
+++ b/Users/starbreaker/bin/yttget
@@ -21,11 +21,16 @@ ID=$(echo $URL | cut -d = -f 2)
FILENAME="youtube-${ID}"
CWD=$(pwd)
JPG="${CWD}/${FILENAME}.jpg"+WEBP="${CWD}/${FILENAME}.webp"
+AVIF="${CWD}/${FILENAME}.avif"
THUMB_URL="http://i3.ytimg.com/vi/${ID}/hqdefault.jpg"
CAPTION="click to view"
curl ${THUMB_URL} --output ${JPG}
+magick -quality 80 ${JPG} ${WEBP}
+magick -quality 80 ${JPG} ${AVIF}
+
echo "<figure>
<a href=\"https://www.youtube.com/watch?v=${ID}\" title=\"${CAPTION}\"
yttget
for image conversionYou need not do your image conversion piecemeal, of course. If you have some experience in writing and editing makefiles and you’re using one to build and deploy your website, it’s easy to implement batch conversion. I did it myself when customizing the makefile in my copy of pblog.