CDN Adapters
vue-image-kit/cdn provides URL builders for popular image CDNs — no dependencies, pure functions.
import {
cloudinary,
imgix,
bunny,
sanity,
storyblok,
contentful,
vercel,
cloudflare,
imagekit,
twicpics,
netlify,
gumlet,
} from 'vue-image-kit/cdn'All adapters share the same interface:
adapter.url(path, options?) // → single URL string
adapter.srcset(path, widths, options?) // → ready srcset stringCloudinary:
const cdn = cloudinary({ cloudName: 'my-cloud' })
cdn.url('photo.jpg', { width: 800, format: 'webp' })
// → https://res.cloudinary.com/my-cloud/w_800,q_auto,f_webp/image/upload/photo.jpg
cdn.srcset('photo.jpg', [400, 800, 1200])
// → 'https://res.cloudinary.com/my-cloud/w_400,... 400w, ...'imgix:
const cdn = imgix('https://mysite.imgix.net')
cdn.url('photo.jpg', { width: 800, dpr: 2 })
// → https://mysite.imgix.net/photo.jpg?w=800&dpr=2&auto=format
cdn.srcset('photo.jpg', [400, 800, 1200])Bunny CDN:
const cdn = bunny('https://myzone.b-cdn.net')
cdn.url('photo.jpg', { width: 800, format: 'webp', quality: 85 })Sanity:
const cdn = sanity({ projectId: 'abc123', dataset: 'production' })
cdn.url('image-abc123-800x600-jpg', { width: 400 })Storyblok:
const cdn = storyblok()
cdn.url('https://a.storyblok.com/f/12345/photo.jpg', { width: 800 })Contentful:
const cdn = contentful()
cdn.url('https://images.ctfassets.net/space/token/photo.jpg', { width: 800 })Vercel Image Optimization:
const cdn = vercel({ origin: 'https://myapp.vercel.app' })
cdn.url('/photo.jpg', { width: 800, quality: 75 })
// → https://myapp.vercel.app/_vercel/image?url=%2Fphoto.jpg&w=800&q=75Cloudflare Images:
const cdn = cloudflare('https://example.com')
cdn.url('/photo.jpg', { width: 800, format: 'webp' })
// → https://example.com/cdn-cgi/image/width=800,format=webp/photo.jpgImageKit.io:
const cdn = imagekit('https://ik.imagekit.io/your_id')
cdn.url('photo.jpg', { width: 800, format: 'webp' })
// → https://ik.imagekit.io/your_id/photo.jpg?tr=w-800,f-webpTwicPics:
const cdn = twicpics('https://demo.twic.pics')
cdn.url('photo.jpg', { width: 800, format: 'webp' })
// → https://demo.twic.pics/photo.jpg?twic=v1/resize=800/output=webpNetlify Image CDN:
const cdn = netlify({ origin: 'https://myapp.netlify.app' })
cdn.url('/photo.jpg', { width: 800, format: 'webp', quality: 75 })
// → https://myapp.netlify.app/.netlify/images?url=%2Fphoto.jpg&w=800&fm=webp&q=75Gumlet:
const cdn = gumlet('https://demo.gumlet.io')
cdn.url('photo.jpg', { width: 800, format: 'webp' })
// → https://demo.gumlet.io/photo.jpg?w=800&format=webpUse with VImage:
<script setup lang="ts">
import { cloudinary } from 'vue-image-kit/cdn'
const cdn = cloudinary({ cloudName: 'my-cloud' })
</script>
<template>
<VImage
src="/photo.jpg"
alt="Photo"
:srcset="cdn.srcset('/photo.jpg', [400, 800, 1200])"
sizes="(max-width: 768px) 100vw, 50vw"
/>
</template>Auto CDN detection
autoLoader() looks at a URL's hostname and picks the right adapter for you — no per-provider wiring when the asset is already served from a recognizable CDN host. It fingerprints 8 of the 12 adapters this way: Cloudinary, imgix, Bunny, ImageKit, Sanity, Storyblok, Contentful, Gumlet. Returns the URL unchanged when nothing matches, so it's safe to run over every src unconditionally — a local /images/photo.jpg just passes through.
import { autoLoader } from 'vue-image-kit/cdn'
autoLoader('https://res.cloudinary.com/demo/image/upload/photo.jpg', { width: 800 })
// → https://res.cloudinary.com/demo/w_800,q_auto,f_auto/image/upload/photo.jpg
autoLoader('/local/photo.jpg', { width: 800 })
// → '/local/photo.jpg' — no recognized CDN host, unchangedThe other 4 adapters (Netlify, Vercel, Cloudflare, TwicPics) run on your own domain rather than a distinctive one, so there's no hostname to fingerprint — pass them explicitly via config.hosts, keyed by your actual domain:
import { autoLoader, netlify } from 'vue-image-kit/cdn'
autoLoader(
src,
{ width: 800 },
{
hosts: { 'myapp.netlify.app': netlify({ origin: 'https://myapp.netlify.app' }) },
},
)autoSrcset() is the same detection, building a real per-width srcset (one distinct URL per width, via the adapter's own .srcset()) instead of a single URL — unlike autoLoader, it returns undefined rather than the input unchanged when nothing is detected, since there's no sensible "unchanged srcset" to fall back to:
import { autoSrcset } from 'vue-image-kit/cdn'
autoSrcset('https://mysite.imgix.net/photo.jpg', [400, 800, 1200])
// → 'https://mysite.imgix.net/photo.jpg?w=400&auto=format 400w, ...'Auto CDN detection with VImage
VImage's cdn prop wires autoLoader()/autoSrcset() straight into the component — no manual detection, no manual src rewriting:
<VImage src="https://res.cloudinary.com/demo/image/upload/photo.jpg" alt="Photo" cdn />Combined with widths, each candidate gets a real CDN-transformed URL via the adapter's .srcset() instead of widths' usual "same URL, different w descriptor" behavior (generateSrcset — see Network-aware loading for why that limitation exists for the non-CDN case):
<VImage src="https://mysite.imgix.net/photo.jpg" alt="Photo" cdn :widths="[400, 800, 1200]" />Pass an AutoLoaderConfig object instead of true to cover the "your own domain" providers (Netlify/Vercel/Cloudflare/TwicPics) via hosts, same as autoLoader() itself:
<script setup lang="ts">
import { netlify } from 'vue-image-kit/cdn'
const cdnConfig = {
hosts: { 'myapp.netlify.app': netlify({ origin: 'https://myapp.netlify.app' }) },
}
</script>
<template>
<VImage src="https://myapp.netlify.app/photo.jpg" alt="Photo" :cdn="cdnConfig" />
</template>Has no effect on an unrecognized host (passthrough, same as autoLoader), or on an explicit SrcSet object / densities — those are already format/resolution choices you made by hand.