11'use client' ;
22
33import { GlobeIcon } from '@phosphor-icons/react' ;
4+ import Image from 'next/image' ;
45import { useState } from 'react' ;
56
67interface FaviconImageProps {
@@ -10,6 +11,9 @@ interface FaviconImageProps {
1011 className ?: string ;
1112}
1213
14+ const hostnameRegex = / ^ h t t p s ? : \/ \/ / ;
15+ const wwwRegex = / ^ w w w \. / ;
16+
1317export function FaviconImage ( {
1418 domain,
1519 altText,
@@ -19,8 +23,8 @@ export function FaviconImage({
1923 const [ error , setError ] = useState ( false ) ;
2024
2125 const hostname = domain
22- . replace ( / ^ h t t p s ? : \/ \/ / , '' )
23- . replace ( / ^ w w w \. / , '' )
26+ . replace ( hostnameRegex , '' )
27+ . replace ( wwwRegex , '' )
2428 . split ( '/' ) [ 0 ]
2529 . split ( '?' ) [ 0 ]
2630 . split ( '#' ) [ 0 ] ;
@@ -34,15 +38,15 @@ export function FaviconImage({
3438 hostname . includes ( 'localhost' ) ||
3539 hostname . includes ( '127.0.0.1' ) ;
3640
37- if ( error || invalid ) {
41+ if ( invalid || error ) {
3842 return (
3943 < div
4044 className = { `${ className } flex items-center justify-center rounded-sm` }
4145 style = { { width : size , height : size } }
4246 >
4347 < GlobeIcon
4448 aria-label = { altText || 'Website icon' }
45- className = "text-muted-foreground"
49+ className = "not-dark:text-primary text-muted-foreground"
4650 size = { size }
4751 weight = "duotone"
4852 />
@@ -51,19 +55,12 @@ export function FaviconImage({
5155 }
5256
5357 return (
54- < img
58+ < Image
5559 alt = { altText || `${ domain } favicon` }
5660 className = { className }
5761 height = { size }
5862 onError = { ( ) => setError ( true ) }
5963 src = { `https://icons.duckduckgo.com/ip3/${ hostname } .ico` }
60- style = { {
61- width : size ,
62- height : size ,
63- objectFit : 'contain' ,
64- imageRendering : '-webkit-optimize-contrast' ,
65- filter : 'contrast(1.1) saturate(1.1)' ,
66- } }
6764 width = { size }
6865 />
6966 ) ;
0 commit comments