Shopify CDN automatically converts WebP Images to PNG/Jpeg in Safari

I’ve been trying for several days to figure this one out, but I can’t seem to find anything.

I am developing a custom website using Hydrogen, and for my product page I have numerous images I want to display. These images are saved as WebP inside the Shopify CDN and are loaded through GraphQL. So inside the product details page I am loading the product and necessary images through the query:

images(first: 10) {
      edges {
        node {
          id
          url
          altText
          width
          height
        }
      }
    }

This works as expected. It contains all images and the necessary data. I am then loading these images inside a custom component called ProductImage that contains a slider. It is loaded inside a tag. Looking at the Network traffic using Firefox, everything is fine. image/webp is accepted, the image received in a .webp file and the type metatag also shows image/webp.

The problem arises when using Safari. Here are parts of the request header:

:path: [REDACTED].webp?v=[REDACTED]&width=1400&height=1400&crop=center
Accept: image/webp,image/avif,image/jxl,image/heic,image/heic-sequence,video/*;q=0.8,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5

As you can see, the path clearly states it’s a .webp image and the Accept header also specifies that image/webp is acceptable. However, the following response was sent:

Content-Type: image/png
Link: <[REDACTED].webp>; rel="canonical"
source-type: image/webp

For whatever reason, it automatically served the content type as PNG. If the image does not offer any transparency, it gets converted to a Jpeg. How can I prevent this? The image size that needs to be loaded increases from 150kb to 1.1mb, which is a heavy hit for Safari users. Has anyone dealt with a similar issue? I am using the newest version of Safari and webp images are loaded correctly when I upload them myself and serve them inside the public folder.

Hi @Michael_K_CC this usually happens because Shopify’s CDN does its own user-agent sniffing and image format negotiation. Even if Safari does support WebP (and correctly advertises it in the Accept header), Shopify may still be defaulting to a fallback image format (PNG or JPEG) for certain Safari user agents.

Have you tried to leverage GraphQL transform arguments (preferredContentType: WEBP) to explicitly request WebP:

query productByHandle($handle: String!) {
  product(handle: $handle) {
    title
    images(first: 10) {
      edges {
        node {
          # the "transformed" URL
          transformedSrc(
            maxWidth: 1400
            maxHeight: 1400
            crop: CENTER
            preferredContentType: WEBP
          )
          
          # You can still fetch the original fields if you need them
          id
          altText
          width
          height
          url  # the original URL
        }
      }
    }
  }
}

Sorry, I just double checked and transformedSrc was deprecated. Use transform argument for url instead:

I’ve noticed, at least for hydrogen, that it’s not necessary tied to the user agent, as some images can be served as .webp and others as .jpg on the same load.

Not sure why. Happens for all browsers in my case.

1 Like