npm install @zawcloud/images
Keep next/image. A custom loader points it at the edge, which serves each width it asks for in AVIF or WebP, from images at your own origin.
Also for Nuxt and Astro . All integrations.
https://a3f9c21b.zwcld.net
This is an example. Your own is on the console dashboard: an opaque
<label>.zwcld.net, or a custom domain once it is verified.
Sign in
and the console shows this guide with your hostname filled in.
The hostname identifies the account, so no API key goes in your markup,
and the URLs are safe to build in the browser. Images come from your configured origin:
/photos/hero.jpg means <origin>/photos/hero.jpg.
One package, no dependencies. The framework writes the srcset;
the edge resizes, converts to AVIF or WebP and caches each size on its first request.
Nothing is processed at build time.
npm install @zawcloud/images
Point next/image at a loader file:
// next.config.js
module.exports = {
images: {
loader: 'custom',
loaderFile: './zawcloud-loader.js',
},
};
// zawcloud-loader.js
import { createLoader } from '@zawcloud/images/next';
export default createLoader({ baseUrl: 'https://a3f9c21b.zwcld.net' });
Then use <Image> as usual. Next asks the loader for one URL per width in its deviceSizes and imageSizes:
import Image from 'next/image';
<Image src="/photos/hero.jpg" width={1200} height={800} sizes="100vw" alt="" />
To keep the hostname in configuration instead, set it in the environment and re-export the default loader:
# .env.local
NEXT_PUBLIC_ZAWCLOUD_URL=https://a3f9c21b.zwcld.net
// zawcloud-loader.js
export { default } from '@zawcloud/images/next';
createLoader takes any option
except width and height, which Next chooses. A quality set on <Image> wins.
| Option | Edge parameter | Notes |
|---|---|---|
| width, height | w, h | Clamped to 5000 |
| quality | q | 1–100. The edge's default is 80 |
| format | f | auto (the default) picks AVIF or WebP per browser and is left out of the URL. jpg means jpeg |
| fit | fit | cover, contain, fill or pad. crop means cover. pad fills the box with params.bg |
| preset | preset | One of your named presets |
| params | as named | Any other parameter: { grayscale: true, watermark: '© Shop' } |
Options are written in a fixed order, so one image at one size is always the same URL, and every cache can reuse it. A value the edge would refuse, such as quality 0 or an unknown fit, throws in your build instead of becoming a broken image in production.
deviceSizes and
imageSizes, and Astro's widths, must then be
widths you allow. Set them to the same lists, or leave the account unrestricted.
preset. Set one in the loader or provider config.