ai-chatbot/components/favicon-updater.tsx
Your Name b08b98102a
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix: reduce canvas request bursts
2026-03-25 15:24:52 +08:00

66 lines
1.8 KiB
TypeScript

"use client";
import { useEffect } from "react";
export function FaviconUpdater() {
useEffect(() => {
let isDisposed = false;
const existingIcon =
document.querySelector<HTMLLinkElement>('link[rel="icon"]')?.href ||
document.querySelector<HTMLLinkElement>('link[rel="shortcut icon"]')?.href ||
document.querySelector<HTMLLinkElement>('link[rel="apple-touch-icon"]')?.href;
const urlWithCache = existingIcon || "/api/favicon";
Promise.resolve().then(() => {
if (isDisposed) {
return;
}
const managedSelector =
'link[rel="icon"],link[rel="shortcut icon"],link[rel="apple-touch-icon"]';
const existingLinks = document.querySelectorAll<HTMLLinkElement>(
managedSelector
);
existingLinks.forEach((link) => {
link.href = urlWithCache;
link.setAttribute("data-managed-favicon", "true");
if (link.rel === "icon") {
link.type = "image/x-icon";
link.setAttribute("sizes", "any");
}
});
const ensureLink = (rel: string, type?: string) => {
let link = document.querySelector(
`link[rel="${rel}"]`
) as HTMLLinkElement | null;
if (!link) {
link = document.createElement("link");
link.rel = rel;
document.head.appendChild(link);
}
link.href = urlWithCache;
link.setAttribute("data-managed-favicon", "true");
if (type) {
link.type = type;
}
if (rel === "icon") {
link.setAttribute("sizes", "any");
}
};
ensureLink("icon", "image/x-icon");
ensureLink("apple-touch-icon");
ensureLink("shortcut icon");
});
return () => {
isDisposed = true;
};
}, []);
return null;
}