Hook

useThumbnail

Resolves the highest available YouTube thumbnail for a video ID.

How it works

Probes thumbnail URLs in priority order using imperative Image() objects. Stops at the first URL that loads successfully. Resets automatically when videoId changes.

Priority order

PriorityURLResolutionAlways exists?
1maxresdefault.jpg1280×720No (720p+ uploads only)
2hqdefault.jpg480×360Almost always
3mqdefault.jpg320×180Yes
4default.jpg120×90Yes

Returns

thumbnailUrl
string | null

Best available thumbnail URL, or null while still loading.

thumbnailLoaded
boolean

True when the thumbnail image has loaded successfully.

thumbnailFailed
boolean

True when all thumbnail URLs failed to load (private video).

Handling failures

failure-handling.tsx
const { thumbnailUrl, thumbnailFailed } = useThumbnail(videoId)

// If thumbnail failed, skip directly to iframe loading
if (thumbnailFailed) {
  setPhase("loading")
  initializeIframe()
}

// Otherwise show the thumbnail while loading
if (thumbnailUrl) {
  return <img src={thumbnailUrl} alt="Video thumbnail" />
}