Niels-IO / next-image-export-optimizer

Use Next.js advanced <Image/> component with the static export functionality. Optimizes all static images in an additional step after the Next.js static export.
MIT License
439 stars 52 forks source link

Next.js 14 dev mode error #191

Closed temp4422 closed 9 months ago

temp4422 commented 9 months ago

When running next dev give output:

Unhandled Runtime Error
Error: Image with src "/images/main.jpg" is missing required "width" property.

My image code:

<ExportedImage
    src="/images/main.jpg"
    alt="Main image"
    priority
 />

If run next build - everything work as expected.

Further details

BUT!

If I put width and height attributes on image it brakes responsiveness by not loading all srcset values.

Example. Run next build and inspect <img/> in Chrome DevTools, without width and height set (it give expected output, everything works):

<img alt="My image" fetchpriority="high" decoding="async" data-nimg="1" style="color: transparent;" 
sizes="100vw" 
srcset="
    /images/nextImageExportOptimizer/main-opt-640.WEBP 640w, 
    /images/nextImageExportOptimizer/main-opt-750.WEBP 750w, 
    /images/nextImageExportOptimizer/main-opt-828.WEBP 828w, 
    /images/nextImageExportOptimizer/main-opt-1080.WEBP 1080w, 
    /images/nextImageExportOptimizer/main-opt-1200.WEBP 1200w, 
    /images/nextImageExportOptimizer/main-opt-1920.WEBP 1920w, 
    /images/nextImageExportOptimizer/main-opt-2048.WEBP 2048w, 
    /images/nextImageExportOptimizer/main-opt-3840.WEBP 3840w" 
src="http://localhost:3000/images/nextImageExportOptimizer/main-opt-3840.WEBP">

Now set: width={640} and height={480}, run next build, inspect DevTools, got output (not expected, broken?):

<img alt="My image" fetchpriority="high" width="640" height="480" decoding="async" data-nimg="1" style="color: transparent;" 
srcset="
    /images/nextImageExportOptimizer/main-opt-640.WEBP 1x, 
    /images/nextImageExportOptimizer/main-opt-1920.WEBP 2x" 
src="http://localhost:3000/images/nextImageExportOptimizer/main-opt-1920.WEBP">
temp4422 commented 9 months ago

Explicitly setting sizes="100vw" solve this issue. Now it's work in both build and dev modes.

I end up with this code that's working for me:

<ExportedImage
  alt="Main hero image that optimized for LCP on first load"
  src="/images/main.jpg"
  fetchPriority="high"
  loading="eager"
  width={640}
  height={480}
  sizes="100vw"
/>
Niels-IO commented 9 months ago

HI @webdev4422,

I checked your examples, and the behavior you observed is intended by Next.js and this library.

Let's go through your remarks:

When running next dev give output:

Unhandled Runtime Error Error: Image with src "/images/main.jpg" is missing required "width" property. My image code:

 <ExportedImage
     src="/images/main.jpg"
     alt="Main image"
     priority
  />

If run next build - everything work as expected.

This is the exact same behavior you get with a normal Next.js app:

image

You have to specify some kind of size related behavior. See for your reference: https://nextjs.org/docs/pages/api-reference/components/image#required-props

And specifically this section:

The width property represents the rendered width in pixels, so it will affect how large the image appears.

Required, except for statically imported images or images with the fill property.

Now for the second point:

Now set: width={640} and height={480}, run next build, inspect DevTools, got output (not expected, broken?):

<img alt="My image" fetchpriority="high" width="640" height="480" decoding="async" data-nimg="1" style="color: transparent;" 
srcset="
  /images/nextImageExportOptimizer/main-opt-640.WEBP 1x, 
  /images/nextImageExportOptimizer/main-opt-1920.WEBP 2x" 
src="http://localhost:3000/images/nextImageExportOptimizer/main-opt-1920.WEBP">

This is also working as expected. As you are setting a specific width in pixel, the srcscet only includes variants of the sizes array for the next largest width and the 2x width. Higher or lower resolutions are not required, as they will never be rendered.

I would recommend you to read the documentation for responsive image here: https://nextjs.org/docs/pages/api-reference/components/image#responsive-images