diff --git a/helpers/listing-page.js b/helpers/listing-page.js index dc3a2b0..35579ee 100644 --- a/helpers/listing-page.js +++ b/helpers/listing-page.js @@ -1,4 +1,5 @@ +import has from 'just-has' import { getAppType @@ -21,17 +22,47 @@ function makeDescription ( listing ) { } export function getVideoImages ( video ) { + + // Catch the case where the video has no thumbnails + if ( !has( video, 'thumbnail' ) ) throw new Error('No thumbnail found') + + const convertYoutubeImageUrl = ( stringWithUrls, extension ) => stringWithUrls.replaceAll('ytimg.com/vi/', `ytimg.com/vi_${ extension }/`).replace(/.png|.jpg|.jpeg/g, `.${ extension }`) + const webpSource = { ...video.thumbnail, - srcset: video.thumbnail.srcset.replaceAll('ytimg.com/vi/', 'ytimg.com/vi_webp/').replace(/.png|.jpg|.jpeg/g, '.webp') + srcset: convertYoutubeImageUrl( video.thumbnail.srcset, 'webp' ), + src: convertYoutubeImageUrl( video.thumbnail.src, 'webp' ), + type: 'image/webp' } - return { - src: video.thumbnail.src, - srcset: { - webp: webpSource, - jpeg: video.thumbnail + const jpgSource = { + ...video.thumbnail, + type: 'image/jpeg' + } + + const sources = { + webp: webpSource, + jpeg: jpgSource + } + + // Responsive Preloads + // https://blog.laurenashpole.com/post/658079409151016960/preloading-images-in-a-responsive-webp-world + // + const preloads = Object.entries( sources ).map( ([ typeKey, typeSource ]) => { + return { + 'rel': 'preload', + 'as': 'image', + 'href': typeSource.src, + 'media': typeSource.sizes, + 'imagesrcset': typeSource.srcset, + 'type': typeSource.type } + }) + + return { + imgSrc: video.thumbnail.src, + sources, + preloads } } @@ -110,10 +141,8 @@ export class ListingDetails { return null } - get videoPosterSources () { - if ( this.initialVideo === null ) return null - - return getVideoPosterSources( this.initialVideo ) + get hasInitialVideo () { + return this.initialVideo !== null } get structuredData () {