nuxt / image

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

Cloudlfare Images doesn't work #891

Open NeroN7F opened 1 year ago

NeroN7F commented 1 year ago

Is there a way to use cloudflare provider with Cloudflare Images? Seems like it makes the image request to the

https://imagedelivery.net/<my-id>/cdn-cgi/image/w=1536,f=webp/ ,

which is the format of the Cloudflare Image Resizing, while the actual Cloudflare Images using url like below

https://imagedelivery.net/<my-id>/<img-id>/public

The custom provider solves the problem, however you are losing the features of the Nuxt-Picture srcset attributes, for the different screen sizes

Hiratake commented 1 year ago

I am in the same situation. Setting cloudflare as the provider does not work with Cloudflare Images.

Are there any plans to support Cloudflare Images in Nuxt Image? The output URLs appear to support Cloudflare Image Resizing, not Cloudflare Images.

If you support Cloudflare Images, the Cloudflare documentation indicates that the URL should look like this

https://example.com/cdn-cgi/imagedelivery/<ACCOUNT_HASH>/<IMAGE_ID>/<VARIANT_NAME>

The /cdn-cgi/image/ must be changed to /cdn-cgi/imagedelivery/.

Also, the location of the parameters seems to be different.

When using flexible variations, it appears that the parameters must be given after the <IMAGE_ID>, but currently they are given before.

NeroN7F commented 1 year ago

As a workaround solution for now, custom provider works fine, which allows to use nuxt-picture and CloudFlare Images, preserving the image optimization

import { joinURL } from 'ufo'

export function getImage(src, { modifiers, baseURL } = {}, { options, $img }) {

const { width, height, format, fit, quality, ...providerModifiers } = modifiers
const operations = [`quality=${quality}`, `width=${width}`, `height=${height}`, `format=${format}`, `fit=${fit}`]

const operationsString = operations.join(',')
return {
    url: joinURL(baseURL, src, operationsString)
}

}

velidonmez commented 6 months ago

I customized cloudflare provider like below and implemented it as custom provider, it solved my problem.

import { encodeQueryItem, joinURL } from 'ufo'
import type { ProviderGetImage } from '@nuxt/image'
import { createOperationsGenerator } from '#image'

const operationsGenerator = createOperationsGenerator({
  keyMap: {
    width: 'w',
    blur: 'blur',
    height: 'h',
    dpr: 'dpr',
    fit: 'fit',
    gravity: 'g',
    quality: 'q',
    format: 'f',
    sharpen: 'sharpen',
  },
  valueMap: {
    fit: {
      cover: 'cover',
      contain: 'contain',
      fill: 'scale-down',
      outside: 'crop',
      inside: 'pad',
    },
    gravity: {
      auto: 'auto',
      side: 'side',
    },
  },
  joinWith: ',',
  formatter: (key, val) => encodeQueryItem(key, val),
})

const defaultModifiers = {}

// https://developers.cloudflare.com/images/image-resizing/url-format/
export const getImage: ProviderGetImage = (src, {
  modifiers = {},
  baseURL = '/',
} = {}) => {
  const mergeModifiers = { ...defaultModifiers, ...modifiers }
  const operations = operationsGenerator(mergeModifiers as any)
  // https://example.com/cdn-cgi/imagedelivery/<ACCOUNT_HASH>/<IMAGE_ID>/<VARIANT_NAME>
  const url = operations ? joinURL(baseURL, src, operations) : joinURL(baseURL, src, 'public')

  return {
    url,
  }
}
<div>
    <NuxtImg
      provider="customProvider"
      src="/637c5bb6-6842-4cc5-ca9b-0f57715e3000"
      width="600"
    />
    <NuxtImg
      quality="50"
      provider="customProvider"
      src="/637c5bb6-6842-4cc5-ca9b-0f57715e3000"
      width="400"
      :modifiers="{ blur: '50' }"
    />
    <NuxtImg
      quality="50"
      provider="customProvider"
      src="/637c5bb6-6842-4cc5-ca9b-0f57715e3000"
      width="200"
      height="200"
    />
  </div>

image