Replaces the document favicon with the provided URL. On first run, existing icon links are removed and a dedicated favicon link is inserted into <head>. The link type is inferred from the file extension.
Usage
import { useFavicon } from '@kuzenbo/hooks';
function Demo() {
useFavicon('/new-favicon.ico');
return <div>Check the browser tab icon</div>;
}
Function Signature
function useFavicon(url: string): void
Parameters
Favicon URL to apply. The MIME type is automatically inferred from the file extension (.ico, .png, .svg, .gif).
Return Value
This hook does not return a value.
Examples
Basic Favicon Update
import { useFavicon } from '@kuzenbo/hooks';
function BrandedPage() {
useFavicon('/brand-favicon.png');
return (
<div>
<h1>Branded Page</h1>
</div>
);
}
Dynamic Favicon Based on Theme
import { useFavicon } from '@kuzenbo/hooks';
import { useColorScheme } from '@kuzenbo/hooks';
function ThemedApp() {
const colorScheme = useColorScheme();
useFavicon(
colorScheme === 'dark' ? '/favicon-dark.svg' : '/favicon-light.svg'
);
return <div>App content</div>;
}
Notification Badge Favicon
import { useFavicon } from '@kuzenbo/hooks';
import { useState, useEffect } from 'react';
function InboxApp() {
const [unreadCount, setUnreadCount] = useState(0);
useFavicon(
unreadCount > 0 ? '/favicon-notification.png' : '/favicon.png'
);
return (
<div>
<h1>Inbox ({unreadCount})</h1>
</div>
);
}
Status Indicator Favicon
import { useFavicon } from '@kuzenbo/hooks';
import { useState } from 'react';
type Status = 'online' | 'away' | 'offline';
function StatusApp() {
const [status, setStatus] = useState<Status>('online');
const faviconMap: Record<Status, string> = {
online: '/favicon-online.svg',
away: '/favicon-away.svg',
offline: '/favicon-offline.svg',
};
useFavicon(faviconMap[status]);
return (
<div>
<select value={status} onChange={(e) => setStatus(e.target.value as Status)}>
<option value="online">Online</option>
<option value="away">Away</option>
<option value="offline">Offline</option>
</select>
</div>
);
}
Different Favicons Per Route
import { useFavicon } from '@kuzenbo/hooks';
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
const faviconMap: Record<string, string> = {
'/': '/favicon.ico',
'/admin': '/favicon-admin.png',
'/settings': '/favicon-settings.png',
};
useFavicon(faviconMap[location.pathname] || '/favicon.ico');
return <div>{/* App routes */}</div>;
}
Loading State Favicon
import { useFavicon } from '@kuzenbo/hooks';
import { useState, useEffect } from 'react';
function DataLoader() {
const [isLoading, setIsLoading] = useState(true);
useFavicon(isLoading ? '/favicon-loading.gif' : '/favicon.png');
useEffect(() => {
// Simulate data loading
setTimeout(() => setIsLoading(false), 3000);
}, []);
return <div>{isLoading ? 'Loading...' : 'Data loaded'}</div>;
}
Environment-Based Favicon
import { useFavicon } from '@kuzenbo/hooks';
function EnvironmentApp() {
const env = process.env.NODE_ENV;
const faviconUrl =
env === 'production'
? '/favicon.ico'
: env === 'staging'
? '/favicon-staging.png'
: '/favicon-dev.png';
useFavicon(faviconUrl);
return <div>Environment: {env}</div>;
}
Supported File Types
The hook automatically sets the correct MIME type based on file extension:
.ico - image/x-icon
.png - image/png
.svg - image/svg+xml
.gif - image/gif
If the extension is not recognized, it defaults to image/x-icon.
Notes
- On first run, removes all existing favicon link elements
- Creates a new
<link rel="shortcut icon"> element in the document head
- The favicon updates whenever the
url parameter changes
- Works isomorphically (safe for SSR)
- If no
<head> element exists, the hook does nothing