475

useFavicon

Hook that manages the favicon

browserlowtest coverage

Choose tab icon

Click any tile to update the browser tab favicon.

Current faviconhttps://reactuse.org/favicon.ico
import { useFavicon } from '@siberiacancode/reactuse';
import { CheckIcon } from 'lucide-react';

import { cn } from '@/utils/lib';

const FAVICONS = [
  { id: 'reactuse', label: 'reactuse', url: 'https://reactuse.org/favicon.ico' },
  { id: 'gitlab', label: 'GitLab', url: 'https://cdn.simpleicons.org/gitlab' },
  { id: 'vercel', label: 'Vercel', url: 'https://cdn.simpleicons.org/vercel/000000/ffffff' },
  { id: 'google', label: 'Google', url: 'https://cdn.simpleicons.org/google' },
  { id: 'discord', label: 'Discord', url: 'https://cdn.simpleicons.org/discord' }
];

const Demo = () => {
  const favicon = useFavicon(FAVICONS[0].url);

  return (
    <section className='demo-ui flex w-full max-w-md flex-col gap-3 p-4'>
      <div className='flex flex-col gap-1'>
        <h2 className='text-foreground text-sm font-semibold'>Choose tab icon</h2>
        <p className='text-muted-foreground text-xs'>
          Click any tile to update the browser tab favicon.
        </p>
      </div>

      <div className='grid grid-cols-5 gap-2'>
        {FAVICONS.map((item) => {
          const isActive = favicon.href === item.url;
          return (
            <button
              key={item.id}
              className={cn(
                'border-border bg-card hover:bg-accent/30 group relative flex aspect-square flex-col items-center justify-center gap-1.5 rounded-xl border p-2 transition-colors',
                isActive && 'border-foreground bg-accent/30'
              )}
              aria-label={item.label}
              aria-pressed={isActive}
              type='button'
              onClick={() => favicon.set(item.url)}
            >
              <img alt={item.label} className='size-7 object-contain' src={item.url} />
              <span className='text-muted-foreground text-[10px] font-medium'>{item.label}</span>

              {isActive && (
                <span className='bg-foreground text-background absolute top-1.5 right-1.5 flex size-3.5 items-center justify-center rounded-full'>
                  <CheckIcon className='size-2.5' strokeWidth={3} />
                </span>
              )}
            </button>
          );
        })}
      </div>

      <div className='border-border bg-muted/30 flex items-center gap-2 rounded-lg border px-3 py-2'>
        <img
          alt='Current favicon'
          className='size-4 shrink-0 object-contain'
          src={favicon.href ?? FAVICONS[0].url}
        />
        <span className='text-muted-foreground truncate font-mono text-[10px]'>
          {favicon.href ?? 'default'}
        </span>
      </div>
    </section>
  );
};

export default Demo;

Installation

pnpm add @siberiacancode/reactuse

Usage

const { href, set } = useFavicon('https://siberiacancode.github.io/reactuse/favicon.ico');

Type Declarations

import type { Dispatch, SetStateAction } from 'react';

export type UseFaviconReturn = [string, Dispatch<SetStateAction<string>>];

API

Parameters

NameTypeDefaultNote
initialFaviconstring-The initial favicon. If not provided, the current favicon will be used

Returns

UseFaviconReturn

Contributors

ddebabinhhywax

Last updated on