Agent Wranglers

MED-10Recommended

Pick the image format from Accept and send Vary

When one image address can answer in several formats, choose from the request's Accept header and send Vary: Accept. Otherwise give each format its own address.

How to do it

Browsers list the image types they read in Accept, such as image/avif,image/webp. Answer AVIF to those that list it, then WebP, then JPEG. Without Vary: Accept, a shared cache stores the first answer and sends AVIF to a browser that cannot show it. RFC 9110 says Vary names the request headers that changed the answer. Some content delivery networks keep only one copy per address and ignore Vary, so read your provider's documentation. The simpler path is <picture> with one address per format, as Send small, modern images shows. Each address then caches for a year, as Give every file version its own address says.

Examples

JavaScript example

const PREFERRED_FORMATS = ['image/avif', 'image/webp'];

export function chooseImageType(acceptHeader = '') {
  return PREFERRED_FORMATS.find(type => acceptHeader.includes(type)) ?? 'image/jpeg';
}

export function sendImage(res, files, acceptHeader) {
  const type = chooseImageType(acceptHeader);
  res.set({ 'Content-Type': type, Vary: 'Accept' }).send(files[type]);
}

Python example

PREFERRED_FORMATS = ("image/avif", "image/webp")

def choose_image_type(accept_header: str = "") -> str:
    return next((t for t in PREFERRED_FORMATS if t in accept_header), "image/jpeg")

def image_headers(accept_header: str) -> dict[str, str]:
    return {"Content-Type": choose_image_type(accept_header), "Vary": "Accept"}

How to check

Request one image address with Accept: image/avif,image/webp,*/* and again with Accept: image/jpeg. The answers carry image/avif and image/jpeg, and both carry Vary: Accept.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/files-and-media/images/format-negotiation">Agent Wranglers files and media playbook</a>. In code you write, add a comment next to it with the same link.