The fastest way to use the Convertly image CDN is the official client SDK. One prop replaces every manually-written URL in your codebase, and you get responsive srcset generation, format negotiation, and lazy loading for free.
npm install @convertly-sh/image
Prerequisites before CDN URLs work| Source | Required dashboard setup |
|---|
Repo public/ / deployed static assets | Origin source — slug + public HTTPS base URL (e.g. site → https://example.com) |
| S3/R2/GCS/public asset host | Origin source for that host |
| Convertly Storage file | Upload + delivery key only |
The SDK builds URLs; it does not upload files or read your local project folder. Wire the loader after the origin source exists. Full checklist: Image CDN setup guide.
The package ships six tree-shakeable entry points sharing one zero-dependency core. You only pay for the framework you actually use.
| Entry point | What it gives you |
|---|
@convertly-sh/image | Framework-agnostic URL builder. |
@convertly-sh/image/react | <ConvertlyImage> component + <ConvertlyCdnProvider>. |
@convertly-sh/image/nextjs | createConvertlyLoader() for next/image. |
@convertly-sh/image/vue | <ConvertlyImage> SFC + provideConvertlyCdn composable. |
@convertly-sh/image/solid | <ConvertlyImage> component + provider. |
@convertly-sh/image/svelte | convertlyImageProps() helper for .svelte files. |
Defaults are the same across every adapter: format=auto, gravity=auto, q=auto, loading="lazy", decoding="async", automatic responsive srcset.
Every adapter supports both source modes. Use Convertly Storage when you want managed file IDs; use origin sources when images already live on a public HTTPS site, bucket, CDN, or web folder. The SDK rewrites image URLs; it does not upload, scan, or sync files from your local project folder.
- Convertly Storage: pass
src="fileId".
- Source URLs / Origin Sources: pass
origin="products" and src="hero.jpg" after creating an origin source in Settings → Image CDN.
For repo images, the origin is your deployed public site. If a framework-served asset such as public/hero.jpg, static/hero.jpg, or another public asset path is served at https://example.com/hero.jpg, create an origin source with slug site and base URL https://example.com; then the SDK can rewrite /hero.jpg to a Convertly origin-backed CDN URL without uploading the source file to Convertly Storage.
What the SDK does (and does not do)
The SDK is a URL builder and framework adapter. It is not a sync tool.
| Does | Does not |
|---|
Build correct CDN URLs (format=auto, srcset, video params) | Upload public/ files to Convertly Storage |
Rewrite Next.js <Image src="/hero.jpg"> to origin-backed CDN URLs | Fetch or transform images during local next dev when localPassthrough is on |
Route UUID src values to Convertly Storage URLs | Accept arbitrary third-party URLs without a registered origin |
Compare to writing URLs by hand: same CDN behaviour, less error-prone query strings and responsive width lists.
Use @convertly-sh/image when you want on-the-fly delivery (resize, format negotiation, edge cache). Use @convertly-sh/sdk or direct API calls when you want to process and store files (convert, compress, trim, background removal). Many apps use both.
React
import { ConvertlyCdnProvider, ConvertlyImage } from "@convertly-sh/image/react";
function App() {
return (
<ConvertlyCdnProvider deliveryKey={process.env.NEXT_PUBLIC_CONVERTLY_DELIVERY_KEY!}>
<ConvertlyImage
origin="products"
src="hero.jpg"
width={1200}
height={800}
alt="Hero image"
sizes="(min-width: 768px) 50vw, 100vw"
/>
<ConvertlyImage
src="11111111-1111-1111-1111-111111111111"
width={1200}
height={800}
alt="Hero image"
sizes="(min-width: 768px) 50vw, 100vw"
/>
</ConvertlyCdnProvider>
);
}
The component renders a real <img> with src + srcSet + sizes built from your transform props. It accepts every standard <img> prop (className, alt, style, onLoad…) plus Convertly-specific ones:
| Prop | Type | Default |
|---|
src (required) | string | — (file id, or origin path when origin is set) |
origin | string | optional origin-source slug |
deliveryKey | string | inherited from <ConvertlyCdnProvider> |
baseUrl | string | inherited |
widths | number[] | derived from width |
responsive | boolean | true when width and sizes are both set |
w, h, q, fit, gravity, format, trim, preset | transform params | see Transforms |
text, textColor, textSize, textPosition, textFont, textBg | text overlay | see Transforms |
pixelate, blurFaces, faceBlur, pixelateFaces, facePixelate | privacy / pixelation | see Transforms |
Without the provider, pass deliveryKey directly on the component.
Next.js
The Next.js loader is the most direct path for Next apps: create an origin source for your deployed site’s public HTTPS URL, wire the loader once, and keep using normal paths like <Image src="/hero.jpg" />. Other frameworks use the same origin-source model through the React, Vue, Astro, Solid, Svelte, or plain URL-builder adapters.
The Next.js loader is the most powerful integration: wire it once and every compatible <Image> URL is rewritten to the CDN in production. Zero per-component changes, but the deployed image must still be publicly reachable from the configured origin.
// lib/convertly-loader.ts
import { createConvertlyLoader } from "@convertly-sh/image/nextjs";
export default createConvertlyLoader({
deliveryKey: process.env.NEXT_PUBLIC_CONVERTLY_DELIVERY_KEY!,
origin: "site",
localPassthrough: process.env.NODE_ENV === "development",
});
// next.config.ts
const nextConfig = {
images: {
loader: "custom",
loaderFile: "./lib/convertly-loader.ts",
},
};
export default nextConfig;
Create site as an origin source that points at your deployed app’s public HTTPS URL, such as https://example.com. In production, any normal public-folder image that resolves from that deployed app, for example <Image src="/hero.jpg" width={1200} height={800} alt="..." />, is rewritten to a Convertly origin-backed CDN URL with smart cropping and format negotiation. UUID-looking src values still route to Convertly Storage; set source: "origin" or source: "storage" when you want to force one behavior. Use the React component instead if you want preset / text-overlay props that next/image doesn’t pass through.
Local development
Convertly’s public CDN cannot fetch localhost, 127.0.0.1, or private-network origins. That is intentional: origin sources must be public HTTPS URLs so the CDN can fetch them safely and cache them globally.
Use localPassthrough: process.env.NODE_ENV === "development" for ordinary next dev work. Local public-folder images keep rendering as /hero.jpg, so the page behaves normally, but those local requests are not transformed by Convertly and are not uploaded to Convertly. To verify the actual optimized CDN URL before launch, use a public Vercel/Netlify preview deployment as the site origin, or expose your local app through an HTTPS tunnel and temporarily point the origin source at that tunnel URL.
Use NEXT_PUBLIC_CONVERTLY_DELIVERY_KEY (your cvly_pub_… token) — never a regular cvly_… API key. Delivery keys are publishable; API keys are not.
Vue
<script setup>
import { provideConvertlyCdn, ConvertlyImage } from "@convertly-sh/image/vue";
provideConvertlyCdn({
deliveryKey: import.meta.env.PUBLIC_CONVERTLY_DELIVERY_KEY,
});
</script>
<template>
<ConvertlyImage
src="11111111-1111-1111-1111-111111111111"
:width="1200"
:height="800"
sizes="(min-width: 768px) 50vw, 100vw"
alt="Hero image"
/>
</template>
Vue 3 only. Vue is registered as an optional peer dependency — non-Vue consumers don’t pull it in.
Astro
Astro’s component model already runs a TypeScript block per component — the URL builder fits right in without a dedicated .astro wrapper:
---
import { createConvertlyCdn } from "@convertly-sh/image";
const cdn = createConvertlyCdn({
deliveryKey: import.meta.env.PUBLIC_CONVERTLY_DELIVERY_KEY,
});
const { fileId, width, sizes, alt } = Astro.props;
const src = cdn.url(fileId, { w: width });
const srcset = cdn.srcset(fileId, { widths: [400, 800, 1200, 1600] });
---
<img {src} {srcset} {sizes} {alt} loading="lazy" decoding="async" />
Save this as components/ConvertlyImage.astro and use it across your project. The URL builder is fully framework-agnostic.
SolidJS
import { ConvertlyCdnProvider, ConvertlyImage } from "@convertly-sh/image/solid";
export default function App() {
return (
<ConvertlyCdnProvider deliveryKey={import.meta.env.PUBLIC_CONVERTLY_DELIVERY_KEY}>
<ConvertlyImage
src="11111111-1111-1111-1111-111111111111"
width={1200}
sizes="(min-width: 768px) 50vw, 100vw"
alt="Hero image"
/>
</ConvertlyCdnProvider>
);
}
The Solid adapter uses Solid’s reactive primitives (createMemo, splitProps) under the hood. Same prop surface as the React adapter.
Svelte
Svelte’s component format requires a compile step we don’t impose on the published package. The adapter instead exposes convertlyImageProps() — a tiny helper that returns the props an <img> needs:
<script lang="ts">
import { convertlyImageProps } from "@convertly-sh/image/svelte";
export let fileId: string;
export let width = 1200;
export let alt = "";
$: imgProps = convertlyImageProps({
deliveryKey: import.meta.env.PUBLIC_CONVERTLY_DELIVERY_KEY,
src: fileId,
width,
sizes: "(min-width: 768px) 50vw, 100vw",
});
</script>
<img {...imgProps} {alt} />
Works in Svelte 4 and Svelte 5. To avoid rebuilding the CDN instance on every reactive update, lift it out of the helper:
<script lang="ts">
import { createConvertlyCdn, convertlyImageProps } from "@convertly-sh/image/svelte";
const cdn = createConvertlyCdn({ deliveryKey: import.meta.env.PUBLIC_CONVERTLY_DELIVERY_KEY });
// ...
$: imgProps = convertlyImageProps({ cdn, src: fileId, width });
</script>
Plain HTML / any other framework
Use the framework-agnostic URL builder directly:
import { createConvertlyCdn } from "@convertly-sh/image";
const cdn = createConvertlyCdn({
deliveryKey: process.env.PUBLIC_CONVERTLY_DELIVERY_KEY!,
});
const heroUrl = cdn.url("fileId", { w: 1200, h: 800, fit: "cover" });
const heroSrcset = cdn.srcset("fileId", { widths: [400, 800, 1200, 1600] });
const originUrl = cdn.origin("products", "hero.jpg", { w: 1200, format: "auto" });
const originSrcset = cdn.originSrcset("products", "hero.jpg", { widths: [400, 800, 1200, 1600] });
<img src="https://cdn.convertly.sh/cvly_pub_.../{fileId}?w=1200&format=auto" alt="…" />
The builder works in Node, browser, edge runtimes, and any framework — it has no runtime dependencies.
defaultWidths()
The SDK exports defaultWidths(baseWidth) for building responsive width lists:
import { defaultWidths } from "@convertly-sh/image";
defaultWidths(1200);
// → [320, 480, 640, 768, 960, 1200, 1440, 1920, 2400]
The breakpoints match what most design systems converge on — capped at 4000 px and at 2× the base. Use it directly when you’re building srcset manually.