Skip to content
lazymage
Esc
↑↓navigate↵open⌘Jpreview
On this page

Hooks

Build your own lazy components with useLazyLoad and useImageStatus.

Use the hooks when the components do not fit your markup. LazyLoadImage and LazyLoadComponent use the same hooks.

useLazyLoad

useLazyLoad tells you when an element comes near the viewport.

import { useLazyLoad } from "lazymage";

export const LazyVideo = ({ src }: { src: string }) => {
  const { ref, isVisible } = useLazyLoad<HTMLDivElement>({ threshold: 200 });

  return (
    <div ref={ref} style={{ aspectRatio: "16 / 9" }}>
      {isVisible ? <video controls src={src} /> : null}
    </div>
  );
};

Attach ref to the element to observe. isVisible becomes true when the element comes near the viewport. It does not go back to false.

On the server and on the first client render, isVisible is false. Set visibleByDefault to make it true at once.

Options

Option Type Default Description
threshold number 100 Distance in px from the viewport at which the element becomes visible.
root Element | Document | null null Scroll container for the IntersectionObserver. null is the viewport.
scrollMargin number | string — Margin for nested scroll containers, in px or as a CSS length.
visibleByDefault boolean false Make the element visible at once, without observing it.
useIntersectionObserver boolean true Use an IntersectionObserver when the browser supports it.
scrollPosition ScrollPosition | null — Scroll position from trackWindowScroll.
delayMethod "throttle" | "debounce" "throttle" How to limit the scroll and resize checks without IntersectionObserver.
delayTime number 300 Time in ms for delayMethod.
onVisible () => void — Called one time, right before the element becomes visible.

Result

Field Type Description
ref RefCallback<T> Attach this ref to the element to observe.
isVisible boolean true after the element came near the viewport.

useImageStatus

useImageStatus tracks the load of an <img>. It waits for decode() before the state is loaded. It also finds images that loaded before the ref attached, like cached images and images loaded before hydration.

import { useImageStatus } from "lazymage";

export const Avatar = ({ src }: { src: string }) => {
  const {
    ref,
    state,
    src: currentSrc,
    onLoad,
    onError,
    retry,
  } = useImageStatus({
    fallbackSrc: "/avatar-default.png",
    src,
  });

  return (
    <figure data-state={state}>
      <img
        alt=""
        onError={onError}
        onLoad={onLoad}
        ref={ref}
        src={currentSrc}
      />
      {state === "error" ? (
        <button onClick={retry} type="button">
          Try again
        </button>
      ) : null}
    </figure>
  );
};

Give ref, src, onLoad, and onError from the result to the <img>.

Options

Option Type Description
src string The image source. A new value resets the state to loading.
fallbackSrc string Source to use one time, when src fails to load.
onReady (image: HTMLImageElement) => void Called when the image is loaded and decoded.

Result

Field Type Description
ref RefCallback<HTMLImageElement> Attach this ref to the <img>.
state "loading" | "loaded" | "error" The load state of the image.
src string | undefined The source for the <img>: src, or fallbackSrc after an error.
retry () => void Load the original src again.
onLoad (event) => void Give this handler to the onLoad prop of the <img>.
onError (event) => void Give this handler to the onError prop of the <img>.

Was this page helpful?