Image resizing
Every app has an /_img address that resizes its own images, or images from hosts you allow, to the size the page needs, crops them if asked, and converts them to WebP or AVIF. Each result is made once and kept; you pay only for making it.
Using it#
In a page, use /_img instead of the image's own address. url is a path of one of the app's files (e.g. /hero.jpg) or an https address on an allowed host, and w the width you want.
<img src="/_img?url=/hero.jpg&w=640" width="640" alt="">
<img srcset="/_img?url=/hero.jpg&w=640 640w, /_img?url=/hero.jpg&w=1080 1080w"
sizes="100vw" src="/_img?url=/hero.jpg&w=1080" alt="">| Parameter | Meaning |
|---|---|
url | A path of one of the app's static files, or https:// on an allowed host. Required. |
w | The width, 1 to 4096. Rounded up to the nearest allowed width. Required. |
h | The height; scaled with the width's rounding. |
q | Quality 1 to 100 (default 75), rounded to the nearest allowed quality. |
f | auto (default: AVIF or WebP when the browser takes it), webp, avif, jpeg or png. |
fit | inside (default: the whole image in the box) or cover (fills the box and crops; with h). |
pos | Where cover crops: center, top, bottom, left or right. |
An image is never made larger than its original. GIFs and other animations, and SVGs, are sent unchanged.
Next.js and Astro#
next/image works with no setting: its default loader asks for /_next/image and our servers answer it. If you set images.unoptimized or use a loader of your own, images are sent as they are.
In Astro, <Image> and getImage() are pointed at this address when we build your app, and no image is processed during the build. If you set your own image.service, it is kept.
Remote hosts listed in next.config or astro.config must also be allowed in the image settings; the build log names them.
Allowed sources#
The app's own files are always allowed and read without any network fetch. For an image from elsewhere, add its host in the settings: one name (img.example.com) or every name under a domain (*.example.com). https on port 443 only; IP addresses, internal network names, user names and other ports are refused.
Every address is checked again at connect time, redirects included, so no name can lead into a private network. A source is at most 20 MB.
cloudhost images hosts add images.example.com '*.cdn.example.org' --project my-site
cloudhost images set --formats webp,avif --project my-siteSettings#
| Setting | Default |
|---|---|
enabled | On. Off: /_img answers 404 and next/image sends the original. |
hosts | None (the app's own files only) |
widths | Next.js's and Astro's sizes, 16 to 3840 |
qualities | 50, 75, 90, 100 |
formats | WebP; add AVIF for smaller files (slower to make) |
ttl_seconds | 86400 (a day): how long a remote image's result is kept |
Rounding widths and qualities to these lists keeps the number of versions of each image small, whatever a visitor asks for.
Caching#
Each result is kept on the server that made it and in the team's storage, and sent at no cost next time. A result of one of the app's files is valid until that file changes; a remote image's result is made again after ttl_seconds. When the team's space is full, the least used go first. Clearing an app's cache makes all its results again.
cloudhost images usage --days 7 --project my-site
cloudhost images purge --yes --project my-siteMCP#
Tools: get_image_settings, set_image_settings, get_image_usage, purge_image_cache and get_team_images.
Prices and limits#
| Hobby | Pro | |
|---|---|---|
| Transformations | 5,000 a month; after that originals are sent and the site keeps working | Per 1,000 transformations, from the monthly credit |
| Team cache | 1 GB | 10 GB |
| Remote hosts per app | 10 | 50 |
A cache read is not a transformation; it counts as an edge request and data transfer like any other request. The price per unit is on the pricing page.