Thinking out loud about embedding content
Continuing on from my last post about changes I’m considering as I redesign this website, today I want to talk about embedding content. In short: I’m tired of it.
If you like to live dangerously, go right ahead and copy and paste that embed code. But that’s not how things are done round here. Instead, I get endlessly side-tracked thinking about:
Authoring: Every piece of content on this site is stored as Markdown yet, apart than for images, this format has no provision for embedding content without resorting to HTML.
Several plugins for markdown-it add support for referencing embedded content but there’s little consensus around what the syntax should be.
Perhaps there doesn’t need to be. Embeds are still hyperlinks, it’s just that the referenced content is displayed by the host website. Maybe I can add links in my source Markdown then replace them with the respective embed code during the build process, progressively enhance them in the client, or a bit of both.
Privacy: Okay, but including code on a website that originates from a third-party soon gets into issues around privacy. Maybe this is less of an issue thanks to sandboxing, blockers and other browser features, but I remain wary.
I’ve tried using the
srcdocattribute and looked into using web components that fetch embedded content only once the user initiates it and many other similar approaches, but…
Previewing: If I’m not displaying the content straight away, I’d like to provide a preview. YouTube has a predictable URL scheme for its thumbnail images, although the dimensions rarely match that of the video, and higher resolution thumbnails are not always available.
For other providers, I would need to query their (oEmbed) API to get thumbnail URLs; a separate request and adding further complexity.
Display: Having considered all of the above, including an embed on a responsive page is still fraught with issues. New CSS properties like
aspect-ratiomean old hacks can be retired, but as this needs the aspect ratio for a given embed, I’d need to include that information somewhere in the original markup.
Pimp my link
I’ve decided to take a different approach. For the authoring experience, I’m using Markdown’s link syntax:
[The Rolling Stones – She’s A Rainbow](https://www.youtube.com/watch?v=6c1BThu95d8)
The raw Markdown remains readable and relatively future-proof, while retaining enough information about the embed.
However, I still want to give embedded content some prominence on the page. To achieve this, I’ve created a custom rule for
markdown-it which looks for links to a known set of content providers. These links also need to be the only child of their parent node – I don’t want to upgrade any links that appear midway through a sentence.
With the above Markdown as an example, the plugin will convert it into the following markup:
<figure class="embed"> <a href="https://www.youtube.com/watch?v=6c1BThu95d8" rel="noreferrer noopener" target="_blank"> <img src="http://img.youtube.com/vi/6c1BThu95d8/mqdefault.jpg" alt="" loading="lazy"> <p>The Rolling Stones – She’s A Rainbow<br><span>Watch on youtube.com (opens in a new tab)</span></p> </a> </figure>
Here is a rendered example:
This is something that sits somewhere between a link and an embed. If you want to view the content you can go ahead and click the link. If not, you have not suffered any performance or privacy penalty.
A few implementation details:
As the link opens in a new tab, I have included
rel="noreferrer noopener"to reduce the risk of reverse tabnabbing.
The thumbnail image uses
loading="lazy"so it will only load if it’s likely to appear within the viewport.
The thumbnail also uses an empty
altattribute. As a presentational image for which we cannot provide a detailed description, this seems like the right approach, especially as the remaining link text should be descriptive.
For YouTube videos, I’m using the medium quality thumbnail image, which is 320 × 180 pixels. Reducing its size by 75% should mean it looks good on higher resolution displays.
I’ve added a little play icon, generated using CSS borders so that it doesn’t get announced by screen readers.
As the entire block is a link, I’ve added an underline to the supporting text to indicate this behaviour.
The above example includes a thumbnail image whose source was guessed from the YouTube video ID included in the original URL. Where no thumbnail can be deduced, or if we want to use a different thumbnail, we can use Markdown’s image syntax:
[![Yosemite HD](/path/to/thumbnail.jpg)](https://vimeo.com/35396305 "A time lapse of Yosemite National Park.")
We can also provide an additional caption by repurposing the Markdown syntax originally intended for adding a
title attribute to links.
Given the above Markdown, the following markup is generated:
<figure class="embed"> <a href="https://vimeo.com/35396305" rel="noreferrer noopener" target="_blank"> <img src="/path/to/thumbnail.jpg" alt="" loading="lazy"> <p>Yosemite HD<br><span>Watch on vimeo.com (opens in a new tab)</span></p> </a> <figcaption> A time lapse of Yosemite National Park. </figcaption> </figure>
Hopefully this solution is robust and simple enough that I don’t need to think about how I embed content on my website ever again.