Ctrl K
ComunidadGuías…

hooks/use-avif-support.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
'use client'

import { useEffect, useState } from 'react'

// 1x1 AVIF test image (canonical feature-detection payload). If a browser can
// decode this it supports AVIF.
const AVIF_TEST_IMAGE =
  'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI='

// Module-level cache so the detection runs at most once per page load and every
// gallery item shares the result.
let cachedSupport: boolean | null = null
let pendingDetection: Promise<boolean> | null = null

function detectAvifSupport(): Promise<boolean> {
  if (cachedSupport !== null) {
    return Promise.resolve(cachedSupport)
  }
  if (pendingDetection) {
    return pendingDetection
  }
  pendingDetection = new Promise<boolean>((resolve) => {
    const img = new globalThis.Image()
    img.onload = () => {
      cachedSupport = img.width > 0 && img.height > 0
      resolve(cachedSupport)
    }
    img.onerror = () => {
      cachedSupport = false
      resolve(false)
    }
    img.src = AVIF_TEST_IMAGE
  })
  return pendingDetection
}

/**
 * One-time AVIF capability detection shared across the gallery. Optimistically
 * assumes AVIF (>95% support) until detection settles, then corrects to WebP
 * for the rare client that can't decode it. The custom image loader reads this
 * to pick the variant extension — no per-image `<picture>`/onError fallback and
 * no `Vary: Accept` cache fragmentation on the CDN.
 */
export function useAvifSupport(): boolean {
  const [supported, setSupported] = useState<boolean>(cachedSupport ?? true)

  useEffect(() => {
    let active = true
    detectAvifSupport().then((ok) => {
      if (active) {
        setSupported(ok)
      }
    })
    return () => {
      active = false
    }
  }, [])

  return supported
}