From 00613ebc9f4e0f0fc970504a6cc4c4a9863aec5e Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 29 Mar 2026 07:34:13 -0400 Subject: [PATCH] feat: add ProductImage component with onError fallback --- components/parts/ProductImage.tsx | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 components/parts/ProductImage.tsx diff --git a/components/parts/ProductImage.tsx b/components/parts/ProductImage.tsx new file mode 100644 index 0000000..5e522f2 --- /dev/null +++ b/components/parts/ProductImage.tsx @@ -0,0 +1,42 @@ +'use client'; + +import { useEffect, useRef } from 'react'; + +const PLACEHOLDER = '/images/product-placeholder.svg'; + +interface ProductImageProps { + src?: string | null; + alt: string; + className?: string; + width?: number; + height?: number; + loading?: 'lazy' | 'eager'; +} + +export function ProductImage({ src, alt, className, width, height, loading }: ProductImageProps) { + const hasErrored = useRef(false); + + // Reset the loop guard whenever src changes (e.g. navigating between products) + useEffect(() => { + hasErrored.current = false; + }, [src]); + + function handleError(e: React.SyntheticEvent) { + if (hasErrored.current) return; + hasErrored.current = true; + e.currentTarget.src = PLACEHOLDER; + } + + return ( + // eslint-disable-next-line @next/next/no-img-element + {alt} + ); +}