{{craftSnippets}}
Home Articles Plugins Starter theme Components on Github Gists About
  • Home
  • Articles
  • Responsive and lazy-loaded youtube videos with Craft CMS
Posted on Aug 25, 2019 by Piotr Pogorzelski

Responsive and lazy-loaded youtube videos with Craft CMS

Twig macro turning youtube video URL into responsive and lazy-loaded player on Github gists
Twig macro making embedded youtube players responsive and lazy-loaded on Github gists
In this article, you will learn how to create responsive and lazy-loaded embedded youtube player in Craft CMS templates using Twig macro.
Table of contents:
  • Lazy loading
  • Responsive youtube players
  • Macro turning youtube URL into a responsive and lazy-loaded player
  • Macro making embedded players responsive and lazy-loaded
  • Embedded youtube videos in redactor fields
  • Plugins providing youtube videos fields
  • Further reading
  • Article change history

There are two ways in which embedded youtube players can be improved - they can be made responsive and lazy-loaded. In this article, I will show you two macros:

  • Macro turning youtube video URLs into responsive and lazy-loaded embedded players.
  • Macro making embedded players already existing in HTML responsive and lazy-loaded.

I will also talk about inserting youtube videos into redactor fields and youtube-related plugins.

Lazy loading #

Thanks to lazy loading, iframes containing youtube embedded players will load their contents only when users actually see them. Usually, each youtube player loads around 1,5 MB of data, even before the video starts playing - thanks to lazy loading we can save tons of bandwidth.

Lazy loading in macros is handled by native lazy loading. This functionality is available for Chrome since version 75 released in July 2019. Other browsers will ignore this feature - hopefully not for long.

Responsive youtube players #

Embedded players are placed in iframes and iframes by default are not responsive - they don't maintain aspect ratio when their width changes. What's worse, default embedded player code generated by youtube website sets iframe width to a specific value and it won't fit inside a small screen of the phone.

To fix it, we will use a bit of inlined CSS. Each player with such CSS hack won't have a specific width and will fill up all available space. That's why an embedded player will be wrapped with <div> with class youtube-player - you can use CSS to give it proper max-width value - for example, 560px which is the value used by default embedded player:

.youtube-player{
    max-width: 560px;
}

Macro turning youtube URL into a responsive and lazy-loaded player #

This macro can be used if you have youtube video URLs in your Craft fields content or even hardcoded in Twig template. Here are parameters of the macro:

  • Youtube video URL. It can be standard video URL, like this: https://www.youtube.com/watch?v=GRxofEmo3HA, URL with additional parameters like this: https://www.youtube.com/watch?v=GRxofEmo3HA&feature=youtu.be or URL generated by "share" functionality of youtube, like https://youtu.be/SVZIs2WLHnU.
  • Lazy loading - optional parameter, set to true by default. Decides if lazy loading is used.

Here is macro code:

{%- macro ytAddress(url, lazy = true) -%}
{% if url is not empty %}
{% set id = url|split('v=')|last %}
{% set id = id|split('&')|first %}
{% set id = id|split('/')|last %}

<div class="youtube-player">
<figure style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; margin: 0px;">
<iframe src="https://www.youtube.com/embed/{{id}}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"{{ lazy ? ' loading="lazy"'}}></iframe>
</figure>
</div>
{% endif %}
{%- endmacro -%}

Macro making embedded players responsive and lazy-loaded #

This macro makes embedded players already existing in HTML responsive and lazy-loaded. It uses Retcon plugin and won't work without it. Retcon can parse and modify HTML elements in strings of text - it's a bit like jQuery for Twig templates.

Here are parameters of the macro:

  • HTML string containing embedded youtube players. Multiple players can be present in the string.
  • Lazy loading - optional parameter, set to true by default. Decides if lazy loading is used.

Here is macro code:

{%- macro ytIframe(html, lazy = true) -%}
{% if html is not empty and craft.app.plugins.isPluginEnabled('retcon') %}
{% set html = html|retconAttr('iframe', {'style' : 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;'} ) %}
{% if lazy %}
{% set html = html|retconAttr('iframe', {'loading' : 'lazy'} ) %}
{% endif %}
{% set html = html|retconWrap( [ 'iframe' ], 'figure')  %}
{% set html = html|retconAttr('figure', {'style' : 'position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; margin: 0px;'} ) %}
{% set html = html|retconWrap( [ 'figure' ], 'div.youtube-player')  %}
{{html}}
{% endif %}
{%- endmacro -%}

Embedded youtube videos in redactor fields #

To place youtube videos into redactor field, you need to enable redactor video plugin. It's not Craft plugin - just extension of Redactor script itself. To enable it, you need to include it in redactor field config:

{
  "buttons": ["html", "formatting", "bold", "italic", "unorderedlist", "orderedlist", "link", "image", "video"],
  "plugins": ["fullscreen", "video"],
}

Now you can open modal, paste in youtube URL and embedded player will be added to redactor field contents. This, however, won't be enough. It turns out that default settings of HTML purifier for redactor fields will remove youtube player from HTML upon saving field contents. To fix it, add this file as video.json to config/htmlpurifier directory:

{
    "HTML.SafeIframe": true,
    "URI.SafeIframeRegexp": "%^(https?:)?//(www\\.youtube(?:-nocookie)?\\.com/embed/|player\\.vimeo\\.com/video/)%",
    "Attr.AllowedFrameTargets": ["_blank"],
    "HTML.AllowedComments": ["pagebreak"]
}

Then open "advanced" section of field settings and select your newly added purifier config. HTML purifier config was provided by Brad Bell, on Craft Stack Exchange.

Plugins providing youtube videos fields #

Want to have a youtube-specific field? While you can just paste youtube link into text field, there are plugins that make working with youtube videos more comfortable.

  • Video embedder - this plugin provides video field. When you paste video link here, it will render youtube player in control panel, allowing you to preview video entered in field. Plugin has also other functionality - like outputting video thumbnails in templates.
  • Embedded assets - this plugin extends regular asset field functionality, allowing it to accept youtube videos (and also instagram posts or twitter posts). These videos are saved as JSON files containing video metadata. Once the specific video gets "uploaded", just like any other asset it can be accessed through any asset field or assets browser. Thanks to that, it can be easily reused in multiple parts of the website. Like video embedder plugin, embedded asset field also renders youtube player in control panel to let administrator preview it.
  • Videos - premium solution. This paid plugin allows you to connect your youtube account to Craft control panel. Thanks to that you can browse and select videos from your account without leaving Craft. Useful if your website is heavily reliant on youtube videos.

Further reading #

  • Native lazy loading - CSS tricks
  • Hybrid lazy loading
  • Responsive iframes

Article change history #

  • 28 august 2019 - fixed default paramater for lazy loading.

TAGS:
#macro #twig
If you want to get latest updates on Craft CMS tutorials and components, follow me on Twitter or subscribe to RSS feed.
Quick links for this article:
Twig macro turning youtube video URL into responsive and lazy-loaded player on Github gists
Twig macro making embedded youtube players responsive and lazy-loaded on Github gists
Articles on blog:
  • Frontend testing for Craft CMS websites with Codeception and Cypress
  • Building reactive Craft Commerce product page with Sprig plugin
  • Dynamically generated PDF attachments for Freeform submissions
  • Using template hooks in Craft CMS
  • Alpine JS modal component for Craft CMS
  • Using template UI elements to extend Craft CMS control panel
  • Matrix within a Matrix - possible solutions for Craft CMS
  • Universal email template for Craft CMS
  • Creating attributes table from entry fields in Craft CMS
  • Namespacing forms in Craft CMS
  • Creating map-based navigation for Craft CMS
  • Placeholder image macro for Craft CMS
  • Building AJAX contact form with Craft CMS
  • Using incognito field plugin for Craft CMS
  • Email footer creator made with Craft CMS
  • Infinite scrolling and lazy loading with Craft CMS
  • Using Javascript in Twig templates with Craft CMS
  • Twig templating tips and tricks for Craft CMS
  • Basic SEO functionality for Craft CMS
  • Working with dates in Craft CMS templates
  • Working with SVG images in Craft CMS templates
  • Responsive and lazy-loaded youtube videos with Craft CMS
  • Debugging and inspecting Twig templates in Craft CMS
  • Creating article excerpts with Twig component in Craft CMS
  • Adding favicons to Craft CMS website
  • Truncating text with Twig macros in Craft CMS
  • Universal language switcher for Craft CMS
  • Read time macro for Craft CMS
  • Using attr() function to render HTML attributes in Craft CMS
  • Building dynamic, AJAX based pagination for Craft CMS
  • How to add Disqus comments to Craft CMS website
  • Ellipsis pagination component for Craft CMS
  • Converting email addresses into links using Twig macro
  • Breadcrumb created from URL for Craft CMS
  • Best developer-oriented Craft CMS plugins
  • Search autocomplete component for Craft CMS
  • RSS feed - template component for Craft CMS
  • Testing emails sent by Craft CMS using Mailtrap
  • Quick edit link - Twig component for Craft CMS
  • Filtering entries in control panel using Searchit plugin
  • Fetching routes into Twig templates in Craft CMS


Frontend testing for Craft CMS websites with Codeception and Cypress

Building reactive Craft Commerce product page with Sprig plugin

Dynamically generated PDF attachments for Freeform submissions

Using template hooks in Craft CMS

Alpine JS modal component for Craft CMS

Using template UI elements to extend Craft CMS control panel

Matrix within a Matrix - possible solutions for Craft CMS

Universal email template for Craft CMS

Copyright ©2023 Piotr Pogorzelski