How to run a function onLoad of an image in NextJS Image component
Asked Answered
A

2

10

I want to show a skeleton while my image is loading. I tried to pass an onLoad prop in the new Image component provided by NextJS but the function fires off before the image is loaded.

Here is my code

const [loaded, setLoaded] = useState(false);

<Image
  src={src}
  alt={""}
  className={styles.image_tag}
  onLoad={(e) => setLoaded(true)}
  style={{ opacity: loaded ? "1" : "0" }}
  layout={"fill"}
/>

{!loaded && (
  <Skeleton
    className={styles.skeleton}
    variant={"rect"}
    animation={"wave"}
  />
)}
Alwyn answered 20/1, 2021 at 15:36 Comment(2)
Image should displayed only when loaded is true. Its displaying always in your codePiety
Is there any way that I can optimize images in the <img> tagAlwyn
S
6

As of 11.1 you can use onLoadingComplete

A callback function that is invoked once the image is completely loaded and the placeholder has been removed.

https://nextjs.org/docs/api-reference/next/image#onloadingcomplete

Subreption answered 14/8, 2021 at 13:47 Comment(3)
For me this fires immediately when emulating slow connection speedMohandis
Have you disabled your cache?Subreption
I refreshed the page using Ctrl + Shift + R, which forces the browser to refresh without caching. To my understanding that should sufficeMohandis
C
4

You could can use the onLoad prop like so:

Referenced from https://github.com/vercel/next.js/discussions/20155

const [isImageReady, setIsImageReady] = useState(false);

const onLoadCallBack = (e)=>{
   setIsImageReady(true)
   typeof onLoad === "function" && onLoad(e)
}

return(
  <div>
   {!isImageReady && 'loading image...'}
   <Image 
     onLoad={onLoadCallBack} 
     src={'/'+image} 
     alt={title} 
     width={260}  
     height={160} />
  </div>
)

******************************* UPDATE *****************************

Nextjs now provides a placeholer and blurDataURL prop with which you can show an image placeholder before the main image is loaded.

An example


<Image
 className="image"
 src={image.src}
 alt={image.alt}
 layout="fill"
 objectFit="cover"
 objectPosition="top center"
 placeholder="blur"
 blurDataURL="/images/blur.jpg"
/>

Comeau answered 16/4, 2021 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.