Image Lazy Load Component
Lazy load images with a blur-up placeholder effect using Intersection Observer and CSS transitions.
import { useState, useRef, useEffect } from 'react';
export function LazyImage({
src,
alt,
className = '',
}: {
src: string;
alt: string;
className?: string;
}) {
const [loaded, setLoaded] = useState(false);
const [inView, setInView] = useState(false);
const imgRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const node = imgRef.current;
if (!node) return;
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) { setInView(true); observer.disconnect(); } },
{ rootMargin: '200px' }
);
observer.observe(node);
return () => observer.disconnect();
}, []);
return (
<div ref={imgRef} className={className}>
{inView && (
<img
src={src}
alt={alt}
onLoad={() => setLoaded(true)}
style={{
opacity: loaded ? 1 : 0,
transition: 'opacity 0.3s ease-in',
}}
/>
)}
</div>
);
}Use Cases
- Image galleries
- Blog post images
- E-commerce product grids
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
Next.js Image Optimization Patterns
Use next/image with responsive sizes, blur placeholders, and priority loading for optimal Core Web Vitals.
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
Portal-Based Modal Component
Accessible modal component using React portals with focus trapping, Escape key close, and backdrop click.
Infinite Scroll with Intersection Observer
Load more items as the user scrolls using IntersectionObserver. No external libraries required.