Lazy Load YouTube Embed Gutenberg Block
Save as e.g. youtube_facade.php in the WordPress plugins directory and activate.
<?php /** Plugin Name: Lazy Load YouTube Embed Block Plugin URI: Description: Filters the gutenberg core/embed youtube block content to load a facade until the block is clicked Version: 1.0 Author: Jem Turner Author URI: https://jemturner.co.uk **/ add_filter( 'render_block_core/embed', function( $block_content, $block ) { // not a youtube embed, dump out original block content if ( stripos( $block['attrs']['url'], 'youtu' ) === false ) return $block_content; preg_match( "/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user|shorts)\/))([^\?&\"'>]+)/", $block['attrs']['url'], $matches ); // if no vid id match, dump out original block content if ( !isset( $matches[1] ) ) return $block_content; // get reasonable alt attribute from title or fall back to blank preg_match( '~title[ ]*=[ ]*["\'](.*?)["\']~is', $block['innerHTML'], $title_matches ); $title_attribute = ( $matches[1] ) ?: ''; // facade magic from https://css-tricks.com/lazy-load-embedded-youtube-videos/ $src_doc = 'srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/'. $matches[1] .'?autoplay=1><img decoding=async src=https://img.youtube.com/vi/'. $matches[1] .'/hqdefault.jpg><span>▶</span></a>"'; $block_content = str_replace( '<iframe','<iframe '. $src_doc, $block_content ); // wptexturize is replacing the quotes in the srcdoc with htmlentities and breaking things // so it's disabled here. this does mean you lose smart quotes etc. in the rest of the content // for pages that contain a youtube video embed, but is that a massive problem? x remove_filter( 'the_content', 'wptexturize'); return $block_content; }, 10, 2 );