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;
}