"use client"; import { getDomain } from "@/lib/utils"; import { useEffect, useState } from "react"; interface IProps { url: string; size?: number; className?: string; timeout?: number; } const WebsiteLogo = ({ url, size = 32, className = "", timeout = 1000, // 1 second }: IProps) => { const domain = getDomain(url); const [imgSrc, setImgSrc] = useState(`https://${domain}/logo.svg`); const [fallbackIndex, setFallbackIndex] = useState(0); const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); const fallbackSources = [ `https://${domain}/logo.svg`, `https://${domain}/logo.png`, `https://${domain}/apple-touch-icon.png`, `https://${domain}/apple-touch-icon-precomposed.png`, `https://www.google.com/s2/favicons?domain=${domain}&sz=64`, `https://icons.duckduckgo.com/ip3/${domain}.ico`, `https://${domain}/favicon.ico`, ]; useEffect(() => { let timeoutId: any; if (isLoading) { timeoutId = setTimeout(() => { handleError(); }, timeout); } return () => { if (timeoutId) { clearTimeout(timeoutId); } }; }, [imgSrc, isLoading]); const handleError = () => { const nextIndex = fallbackIndex + 1; if (nextIndex < fallbackSources.length) { setFallbackIndex(nextIndex); setImgSrc(fallbackSources[nextIndex]); setIsLoading(true); } else { setHasError(true); setIsLoading(false); } }; const handleLoad = () => { setIsLoading(false); setHasError(false); }; return (
{/* placeholder */} {isLoading && (
)} {`${domain} {/* Fallback: Display first letter of domain when all image sources fail */} {hasError && (
{domain.charAt(0).toUpperCase()}
)}
); }; export default WebsiteLogo;