Favicon Search
unlumen-ui/favicon-searchFreeComponent
A search input that fetches and smoothly animates the site favicon into the search bar as you type a URL.
Live preview
live · rendered by the registry
Rendered by Unlumen Ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.unlumen.com/r/favicon-search.jsonSource
1"use client";23import * as React from "react";4import { motion, AnimatePresence } from "motion/react";5import { Globe, Search, X } from "lucide-react";6import { cn } from "@/lib/utils";78function extractDomain(input: string): string | null {9 if (!input.trim()) return null;10 try {11 const raw = input.includes("://") ? input : `https://${input}`;12 const url = new URL(raw);13 const host = url.hostname.replace(/^www\./, "");14 if (host.includes(".") && host.split(".").every(Boolean)) return host;15 return null;16 } catch {17 const cleaned = input.trim().replace(/^www\./, "");18 if (cleaned.includes(".") && cleaned.split(".").every(Boolean))19 return cleaned;20 return null;21 }22}2324function getFaviconUrl(domain: string, size = 64): string {25 return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size}`;26}2728export interface FaviconSearchProps {29 /** Controlled value */30 value?: string;31 defaultValue?: string;32 onChange?: (value: string) => void;33 onSearch?: (value: string, domain: string | null) => void;34 placeholder?: string;35 clearable?: boolean;36 /** @default 64 */37 faviconSize?: 16 | 32 | 64 | 128;38 /** @default 350 */39 debounce?: number;40 className?: string;41 inputClassName?: string;42}4344const FaviconSearch = React.forwardRef<HTMLInputElement, FaviconSearchProps>(45 (46 {47 value: controlledValue,48 defaultValue = "",49 onChange,50 onSearch,51 placeholder = "Enter a website URL…",52 clearable = true,53 faviconSize = 64,54 debounce = 350,55 className,56 inputClassName,57 },58 ref,59 ) => {60 const isControlled = controlledValue !== undefined;61 const [internalValue, setInternalValue] = React.useState(defaultValue);62 const value = isControlled ? controlledValue : internalValue;6364 const [domain, setDomain] = React.useState<string | null>(null);65 const [faviconReady, setFaviconReady] = React.useState(false);66 const [faviconError, setFaviconError] = React.useState(false);67 const prevDomainRef = React.useRef<string | null>(null);6869 React.useEffect(() => {70 const id = setTimeout(() => {71 const d = extractDomain(value);72 if (d !== prevDomainRef.current) {73 prevDomainRef.current = d;74 setFaviconReady(false);75 setFaviconError(false);76 setDomain(d);77 }78 }, debounce);79 return () => clearTimeout(id);80 }, [value, debounce]);8182// … truncated
What it pulls in
npm packages
Files it writes
More from Unlumen Ui
All 233 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Chatai-chat | Unlumen Ui | Components | Paid | 2 deps | |
| Vercel Animate Countanimate-count | Unlumen Ui | Components | Free | 1 dep | |
| Animate Digitsanimate-digits | Unlumen Ui | Components | Free | 1 dep | |
| Animated Inputanimate-text-input-typing | Unlumen Ui | Components | Paid | 1 dep | |
| Animated Listanimated-list | Unlumen Ui | Components | Free | 1 dep | |
| Apple Switchapple-switch | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Barsaurora-bars | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Bluraurora-blur | Unlumen Ui | Components | Free | 2 deps |
