https://shaneosullivan.wordpress.com/2025/08/11/fighting-with-youtube-to-show-a-preview-image/ Skip to content Unknown's avatar SOS Shane O'Sullivan's technical blog... really ties the room together Fighting with YouTube to show a preview image Shane O'Sullivan Technical August 11, 2025August 11, 2025 2 Minutes TLDR: Click here for code to implement a lightweight, resilient clickable YouTube preview. YouTube videos are expensive to load on a web page. This compounds if you want your page to display many videos at the same time for the user to choose from. Before the user even plays the video, it loads 4MB onto your previously zippy page. [screenshot-2025-08-11-at-23] Of course, YouTube does a decent job of caching these resources, but your browser is still doing all this work, creating another complete page context per video, executing all it's JavaScript etc. The ideal state is that an iframe is only created when the user plays the video, so if you're listing dozens of videos that can be played in place you only pay the performance penalty when the user actually requests the video to play. A solution ... that YouTube makes brittle One solution is to first show a preview image using a thumbnail image from the video, and when that is clicked, swapping it out for the iframe. This works great! ... until it doesn't. The Problem The url for a thumbnail image looks like https://img.youtube.com/vi/ bJ7mTY9501c/maxresdefault.jpg . Note the maxresdefault.jpg at the end, this specifies the highest quality possible preview image. The problem is that this only exists on some videos and not others. It should be easy to add an onerror handler though right? Then we can fall back to a lower res preview image. Haha, yeah, but no. Instead of simply failing to return the image, sending a 404 response header and causing the element to trigger it's onerror listener, YouTube both sends a 404 response and sends a small ugly placeholder image that makes your site look broken. This triggers the onload listener instead of the the expected onerror listener. [maxresdefault] The Solution Instead of an onerror , add an onload handler to the element, and check the size of the image. The ugly fallback image is 120px wide and 90px tall. Check the size of the image, and if the fallback image is detected, iterate through the available thumnail images until one loads. The image below shows an implementation of this. [screenshot-2025-08-12-at-00] Full Example There's a full no-framework example at https://chofter.com/examples/ youtubePreview.html , view the source for the full example. This can be easily adapted for any framework like React, Vue etc. Prior Art Paul Irish describes another solution to this problem that I found after I built this, check it out here. That also points to these three implementations that are also worth perusing. * https://github.com/ampproject/amphtml/blob/master/extensions/ amp-youtube * https://github.com/Daugilas/lazyYT * https://github.com/vb/lazyframe I like mine as it uses the least code and is trivial to implement in whatever framework you like, but another of these might suit your needs or taste better. Share this: * Share * * Click to share on Facebook (Opens in new window) Facebook * Click to share on X (Opens in new window) X * Like Loading... Related * Tagged * digital-marketing * performance * seo * webspeed * youtube Unknown's avatar Published by Shane O'Sullivan I am a software engineer and manager from Ireland. I spent 7 years working in Ireland from 2003 - 2010, then ten years in Silicon Valley from 2010 to 2020. In California I spent about 6.5 years at Facebook Engineering, the last three of which I was an engineering manager in the Ads organisation focusing on customer facing products for creating and managing ads. At Stripe I built the Developer Productivity organisation, with teams that were responsible for the use of the Ruby language, testing infrastructure, documentation, developer tooling (e.g. IDE integrations) and more. At Promise, I was Head of Engineering from 2018 - 2020, responsible for building the first few iterations of our products, hiring for all product roles, meeting with clients and investors, and anything else needed to get a tiny startup bootstrapped and successful. Now I'm back in Ireland, working various projects while advising the great people at Stainless (stainless.com). This blog contains my various musings on all things technical/interesting on the interweb and beyond. View all posts by Shane O'Sullivan Published August 11, 2025August 11, 2025 Post navigation Previous Post On Designing For Children One thought on "Fighting with YouTube to show a preview image" 1. Pingback: Yu YouTubeZheng Qu Xian Shi Yu Lan Tu Xiang . - Pian Zhi De Ma Nong Leave a comment Cancel reply [ ] [ ] [ ] [ ] [ ] [ ] [ ] D[ ] Other me * X * LinkedIn * Facebook Recent Posts * Fighting with YouTube to show a preview image * On Designing For Children * Search Huge JSON files on the Web * Explore Wallpapers for Mac * Optimizing iWittr.com to reduce Google Cloud & Vercel costs Archives Archives [Select Month ] Subscribe [feed-icon] Atom 0.3 [feed-icon] RSS 2.0 Recent Posts * Fighting with YouTube to show a preview image * On Designing For Children * Search Huge JSON files on the Web * Explore Wallpapers for Mac * Optimizing iWittr.com to reduce Google Cloud & Vercel costs Blogs * Alex Russell * Carol Jones * Chofter.com Blog * James Snell * Rob Yates Interests * DojoBuilder * GreaseMonkey Scripts * MapViewer for Robotics Links * JavaScript JS Documentation: JS Array join, JavaScript Array join, JS Array .join, JavaScript Array .join Projects * Chofter webOS Apps * Chofter.com Publications * Benchmarking Map Building Algorithms * Evaluation of Sonar Models * IBM WMC ISV Integration Guide * Linear Feature Prediction * Masters Thesis * Vectorising Spatial Maps Visits to this blog [shaneosull] Blog at WordPress.com. * Comment * Reblog * Subscribe Subscribed + [croppe] SOS Join 31 other subscribers [ ] Sign me up + Already have a WordPress.com account? Log in now. * + [croppe] SOS + Subscribe Subscribed + Sign up + Log in + Copy shortlink + Report this content + View post in Reader + Manage subscriptions + Collapse this bar Loading Comments... Write a Comment... [ ] Email (Required) [ ] Name (Required) [ ] Website [ ] [Post Comment] %d [b]