nuxt / image

Plug-and-play image optimization for Nuxt applications.
https://image.nuxt.com
MIT License
1.34k stars 271 forks source link

Width issue on vercel #1490

Closed ejerskov closed 4 weeks ago

ejerskov commented 1 month ago

Im running @nuxt/image 1.8.0 and deploying to vercel.

I have this image:

  <NuxtImg
    src="logo.png"
    alt="Title"
    densities="x1 x2"
    preload
    format="webp"
    width="90px"
    height="121px"
    sizes="xs:90px sm:90px"
  />

Locally it generates this html correctly: <img onerror="this.setAttribute('data-error', 1)" width="90" height="121" alt="Fanside for Liverpool FC" data-nuxt-img="" sizes="(max-width: 640px) 90px, 90px" srcset="/_ipx/f_webp&amp;s_90x121/anfieldroad/logo.png 90w, /_ipx/f_webp&amp;s_180x242/anfieldroad/logo.png 180w" src="/_ipx/f_webp&amp;s_180x242/anfieldroad/logo.png" data-v-inspector="../node_modules/.pnpm/@nuxt+image@1.8.0_rollup@4.18.0/node_modules/@nuxt/image/dist/runtime/components/NuxtImg.vue:2:3">

However after its been deployed to vercel, the html is: <img onerror="this.setAttribute('data-error', 1)" width="90" height="121" alt="Fanside for Liverpool FC" data-nuxt-img="" sizes="(max-width: 640px) 90px, 90px" srcset="/_vercel/image?url=%2Fanfieldroad%2Flogo.png&amp;w=320&amp;q=100 90w, /_vercel/image?url=%2Fanfieldroad%2Flogo.png&amp;w=320&amp;q=100 180w" src="/_vercel/image?url=%2Fanfieldroad%2Flogo.png&amp;w=320&amp;q=100">

The width is now 320px.

ejerskov commented 4 weeks ago

Thanks @danielroe, although I dont exactly understand if this is fixed by the package or I need to change my sizes attribute?

Do I need to define the size for all my viewports?xs, md, lg ... etc? Is this not correct usage?

  <NuxtImg
    src="logo.png"
    alt="Title"
    densities="x1 x2"
    preload
    format="webp"
    width="90px"
    height="121px"
    sizes="xs:90px sm:90px"
  />
mathix420 commented 4 weeks ago

Hi @ejerskov! Docs are still not updated, but I added a section that you can check here https://8a4821c1.nuxt-image.pages.dev/providers/vercel

As you can see vercel provider requires you to list all the sizes you need in the config (included computed ones due to densities).

So for your picture to work properly on vercel, you'll need to add this in your nuxt config:

export default {
  image: {
    screens: {
      logo: 90,
      logo2x: 180
    }
  }
}

I did fixed the other issue linked to image format as well, nothing is needed from your part if you're using v1.8.1 (not published yet). If you don't add this in your nuxt config:

export default {
  nitro: {
    vercel: {
      config: {
        images: {
          formats: ["image/webp", "image/avif"],
        },
      },
    },
  }
}
ejerskov commented 4 weeks ago

Hi @mathix420

Sorry but I still don't understand what I should do.

image Shouldnt these be the same?

And what do you mean I have to add the sizes to the config - so everytime I need to use the vercel image I need to define the specific sizes for that image in the nuxt.config.ts?

I assume that this is only settings for one specify image, right? screens: { logo: 90, logo2x: 180 }

mathix420 commented 4 weeks ago

Actually presets doesn't matter in this case, but I should remove it in the example to avoid any misunderstanding!

You should check my updated link, It'll be clearer: https://8a4821c1.nuxt-image.pages.dev/providers/vercel

And what do you mean I have to add the sizes to the config - so everytime I need to use the vercel image I need to define the specific sizes for that image in the nuxt.config.ts?

Sadly yes... or at least try to define some rough over estimations. This is a limitation from Vercel. Best would be to list every NuxtImg widths at build time and define their sizes in the config automatically.

I assume that this is only settings for one specify image, right?

Yes.

Example for a small portfolio website I have:

  image: {
    screens: {
      avatar: 40,
      avatar2x: 80,
      normalImage: 301,
      normalImage2x: 602,
      biggestImage: 432,
      biggestImage2x: 864,
    },
  },
ejerskov commented 3 weeks ago

@mathix420, thanks I think I've got it now, however Im running into a new issue. I have a banner that takes the full width (width: 100%, height: 100%) of the parent but thats not supported by the vercel provider: If a width is not defined, image will fallback to the next bigger width.

So on smaller resolutions my banner ends up with the largest size defined in nuxtconfig which is 3000px (to support wide monitors) Do you have any suggestions on how to handle this scenario?

mathix420 commented 3 weeks ago

Yes, you just need to define the default breakpoints with your custom ones, https://image.nuxt.com/get-started/configuration#screens

ejerskov commented 3 weeks ago

I already have this:

    screens: {
      xs: 40,
      xs2x: 80,
      sm: 120,
      smx2: 240,
      md: 300,
      md2x: 600,
      lg: 450,
      lg2x: 900,
      xl: 600,
      xlx2: 1200,
      xxl: 900,
      xxlx2: 1800,
      banner: 1600,
      bannerx2: 3200,
    },

So using without width will give me 3200px on mobile width.

mathix420 commented 3 weeks ago

Ah yes, but you should use the NuxtPicture component that will generate a responsive image.

ejerskov commented 3 weeks ago

@mathix420, it seems to behave the same. It takes the largest width possible in a mobile viewport:

    <NuxtPicture
        :src="banner"
        :alt="title"
        class="mx-auto size-full max-w-[1792px] object-cover"
        format="webp"
        quality="80"
        sizes="500px sm:768px md:1024px lg:1280px xl:1536px"
      />