react ~3 KB 0 deps v0.1.0 ↗ GitHub ↗

@mshafiqyajid/react-image

Headless hook + styled wrapper for images. Native lazy loading, skeleton shimmer, blur-up placeholder, graceful error fallback with custom content, aspect ratio, object-fit, and radius variants.

Playground #

Coastal view
Forest
City
Demo image
Props
TSX
import { ImageStyled } from "@mshafiqyajid/react-image/styled";
import "@mshafiqyajid/react-image/styles.css";

<ImageStyled />

Install #

npm install @mshafiqyajid/react-image

Quick start #

import { ImageStyled } from "@mshafiqyajid/react-image/styled";
import "@mshafiqyajid/react-image/styles.css";

<ImageStyled
  src="https://picsum.photos/800/600"
  alt="A scenic photo"
  aspectRatio="4/3"
  radius="md"
  placeholder="skeleton"
/>

Blur-up placeholder #

Pass a tiny base64 data URL as blurDataURL. It renders blurred behind the main image until the full image loads.

<ImageStyled
  src="https://picsum.photos/800/600"
  alt="Landscape"
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,/9j/4AA..."
  aspectRatio="16/9"
/>

Fallback on error #

// Auto-retry with fallback URL
<ImageStyled
  src="/uploads/photo.jpg"
  alt="User photo"
  fallbackSrc="/images/placeholder.jpg"
/>

// Custom error content
<ImageStyled
  src="/uploads/photo.jpg"
  alt="User photo"
  fallback={<div className="error-state">Image unavailable</div>}
/>

Headless #

import { useImage } from "@mshafiqyajid/react-image";

const { imgProps, isLoading, isLoaded, isError } = useImage({
  src: "https://example.com/photo.jpg",
  alt: "A photo",
  fallbackSrc: "https://example.com/fallback.jpg",
  lazy: true,
  onLoad: () => console.log("loaded"),
  onError: () => console.error("failed"),
});

return (
  <div style={{ position: "relative", width: 400, height: 300 }}>
    {isLoading && <div className="my-skeleton" />}
    {!isError && <img {...imgProps} style={{ width: "100%", height: "100%", objectFit: "cover" }} />}
    {isError && <div>Could not load image</div>}
  </div>
);

Decorative images #

Pass an empty alt="" for purely decorative images. The hook automatically adds aria-hidden="true".

<ImageStyled src="/decorative-bg.jpg" alt="" />

API #

PropTypeDefaultDescription
srcstringImage source URL
altstringAlt text. Empty string marks image as decorative (aria-hidden)
fallbackSrcstringURL to try if src fails to load
fallbackReactNodeCustom content shown in error state
placeholder"blur" | "skeleton" | "color" | "none""skeleton"Loading placeholder strategy
blurDataURLstringTiny base64 image for blur placeholder
placeholderColorstringBackground color for "color" placeholder
lazybooleantrueUse native lazy loading attribute
aspectRatiostring | numberCSS aspect-ratio (e.g. "4/3", "16/9")
objectFit"cover" | "contain" | "fill" | "none" | "scale-down""cover"CSS object-fit
objectPositionstring"center"CSS object-position
widthnumber | stringExplicit width on the wrapper element
heightnumber | stringExplicit height on the wrapper element
crossOrigin"anonymous" | "use-credentials"Sets the crossorigin attribute on the img element
radius"none" | "xs" | "sm" | "md" | "lg" | "full""none"Border radius
onLoad() => voidCallback when image successfully loads
onError() => voidCallback when all load attempts fail
classNamestringExtra class on the root wrapper element
styleCSSPropertiesInline style override
Edit this page on GitHub