typescriptintermediate

Responsive Image Component

Image component with lazy loading, blur placeholder, error fallback, and srcset support.

typescript
import { useState, ImgHTMLAttributes } from 'react';

interface ResponsiveImageProps extends ImgHTMLAttributes<HTMLImageElement> {
  fallback?: string;
  blurDataUrl?: string;
}

export function ResponsiveImage({ fallback, blurDataUrl, className = '', style, ...props }: ResponsiveImageProps) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState(false);

  if (error && fallback) {
    return <img {...props} src={fallback} className={className} alt={props.alt || ''} />;
  }

  return (
    <div className={`relative overflow-hidden ${className}`} style={style}>
      {blurDataUrl && !loaded && (
        <img
          src={blurDataUrl}
          className="absolute inset-0 w-full h-full object-cover scale-110 blur-lg"
          alt=""
          aria-hidden
        />
      )}
      <img
        {...props}
        loading="lazy"
        onLoad={() => setLoaded(true)}
        onError={() => setError(true)}
        className={`w-full h-full object-cover transition-opacity duration-300 ${loaded ? 'opacity-100' : 'opacity-0'}`}
        alt={props.alt || ''}
      />
    </div>
  );
}

Use Cases

  • Image galleries
  • Blog post images

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.