Lazy Load YouTube Embed Gutenberg Block

Save as e.g. youtube_facade.php in the WordPress plugins directory and activate.

	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:

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
	$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='. $matches[1] .'?autoplay=1><img decoding=async src='. $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 );
Jem Turner +44(0)7521056376

Comments are closed.