diff --git a/src/components/common/Favicon.tsx b/src/components/common/Favicon.tsx index a6b5e522..9edbb03f 100644 --- a/src/components/common/Favicon.tsx +++ b/src/components/common/Favicon.tsx @@ -1,3 +1,4 @@ +import { useEffect, useMemo, useState } from 'react'; import { useConfig } from '@/components/hooks'; import { FAVICON_URL, GROUPED_DOMAINS } from '@/lib/constants'; @@ -13,10 +14,39 @@ export function Favicon({ domain, ...props }) { return null; } - const url = config?.faviconUrl || FAVICON_URL; const hostName = domain ? getHostName(domain) : null; - const domainName = GROUPED_DOMAINS[hostName]?.domain || hostName; - const src = hostName ? url.replace(/\{\{\s*domain\s*}}/, domainName) : null; + const domainName = hostName ? GROUPED_DOMAINS[hostName]?.domain || hostName : null; + const candidates = useMemo(() => { + if (!domainName) { + return []; + } - return hostName ? : null; + const urls = [`https://${domainName}/favicon.ico`]; + + if (globalThis?.location?.protocol !== 'https:') { + urls.push(`http://${domainName}/favicon.ico`); + } + + if (config?.faviconUrl) { + urls.push(config.faviconUrl.replace(/\{\{\s*domain\s*}}/, domainName)); + } + + urls.push(FAVICON_URL.replace(/\{\{\s*domain\s*}}/, domainName)); + + return urls; + }, [config?.faviconUrl, domainName]); + const [index, setIndex] = useState(0); + const src = candidates[index] || null; + + useEffect(() => { + setIndex(0); + }, [candidates.join('|')]); + + function handleError() { + setIndex(current => (current + 1 < candidates.length ? current + 1 : current)); + } + + return hostName && src ? ( + + ) : null; }