Favicon Search

A search input that fetches and smoothly animates the site favicon into the search bar as you type a URL.

Installation

File Structure

favicon-search.tsx

Usage

import { FaviconSearch } from "@/components/unlumen-ui/favicon-search";

<FaviconSearch
  placeholder="Enter a website URL…"
  onSearch={(value, domain) => console.log(value, domain)}
/>;

Controlled

import * as React from "react";
import { FaviconSearch } from "@/components/unlumen-ui/favicon-search";

const [value, setValue] = React.useState("");

<FaviconSearch
  value={value}
  onChange={setValue}
  onSearch={(val, domain) => {
    if (domain) window.open(`https://${domain}`, "_blank");
  }}
/>;

API Reference

FaviconSearch

value?
string

Controlled input value.

defaultValue?
string
""

Default value for uncontrolled mode.

onChange?
(value: string) => void

Called on every keystroke with the current input value.

onSearch?
(value: string, domain: string | null) => void

Called when the user presses Enter.

placeholder?
string
"Enter a website URL…"

Input placeholder text.

clearable?
boolean
true

Show a clear (×) button when the input has content.

faviconSize?
16 | 32 | 64 | 128
64

Favicon resolution requested from the Google favicon API.

debounce?
number
350

Milliseconds to wait after typing before resolving the domain.

className?
string

Extra className on the wrapper element.

inputClassName?
string

Extra className on the <input> element.

Notes

  • Favicon source: uses the Google favicon API (https://www.google.com/s2/favicons?domain=…&sz=…). No API key required but subject to Google's availability.
  • Domain parsing: handles bare domains (stripe.com), full URLs (https://stripe.com/pricing), and www. prefixes — all resolve to the same favicon.
  • Fallback: while the favicon is loading a Globe icon is shown; if the fetch errors or the input is empty a Search icon is shown instead.
  • Animation: uses Motion AnimatePresence with a spring transition — scale + blur in/out so the icon swap feels organic.

Credits

Built by leo.

Keep in mind

Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.