index.tsx raw

   1  import { faviconUrl } from '@/lib/faviconUrl'
   2  import { cn } from '@/lib/utils'
   3  import { useContentPolicy } from '@/providers/ContentPolicyProvider'
   4  import { useState } from 'react'
   5  
   6  export function Favicon({
   7    domain,
   8    className,
   9    fallback = null
  10  }: {
  11    domain: string
  12    className?: string
  13    fallback?: React.ReactNode
  14  }) {
  15    const { faviconUrlTemplate } = useContentPolicy()
  16    const [loading, setLoading] = useState(true)
  17    const [error, setError] = useState(false)
  18    if (error) return fallback
  19  
  20    const url = faviconUrl(faviconUrlTemplate, `https://${domain}`)
  21  
  22    return (
  23      <div className={cn('relative', className)}>
  24        {loading && <div className={cn('absolute inset-0', className)}>{fallback}</div>}
  25        <img
  26          src={url}
  27          alt={domain}
  28          className={cn('absolute inset-0', loading && 'opacity-0', className)}
  29          onError={() => setError(true)}
  30          onLoad={() => setLoading(false)}
  31        />
  32      </div>
  33    )
  34  }
  35