"use client"; import { useEffect } from "react"; export function FaviconUpdater() { useEffect(() => { let isDisposed = false; const getFaviconUrl = () => "/api/favicon"; const updateFavicon = () => { if (isDisposed) return; const urlWithTheme = getFaviconUrl(); const href = `${urlWithTheme}${urlWithTheme.includes("?") ? "&" : "?"}v=${Date.now()}`; const managedSelector = 'link[rel="icon"],link[rel="shortcut icon"],link[rel="apple-touch-icon"]'; const existingLinks = document.querySelectorAll( managedSelector ); existingLinks.forEach((link) => { link.href = href; link.setAttribute("data-managed-favicon", "true"); if (link.rel === "icon" || link.rel === "shortcut icon") { link.removeAttribute("type"); link.setAttribute("sizes", "any"); } }); const ensureLink = (rel: 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 = href; link.setAttribute("data-managed-favicon", "true"); link.removeAttribute("type"); if (rel === "icon") { link.setAttribute("sizes", "any"); } }; ensureLink("icon"); ensureLink("apple-touch-icon"); ensureLink("shortcut icon"); }; const observer = new MutationObserver(updateFavicon); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], }); Promise.resolve().then(() => { updateFavicon(); }); return () => { isDisposed = true; observer.disconnect(); }; }, []); return null; }