These options set the download file name, pick a page or frame of the original, bust cached copies, limit how long a URL works, lower a request's priority, and ask for debug headers. Each one applies once to the whole request, wherever it appears in the URL.

Downloads

filename and attachment apply to cached responses too, and don't change the stored image or its ETag. A 304 Not Modified response has no Content-Disposition header.

filename

Accepts ASCII letters, digits, ., _, and -, at least one character. Default: none.

filename names the file a browser saves. ImagePipe adds the extension of the actual response: .jpg, .webp, and so on for images, .txt for output=blurhash and output=lqip-css, and .json for output=info. With filename=beach, a WebP response has the header Content-Disposition: inline; filename="beach.webp".

URL

/w=1200/filename=beach/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(filename: "beach")
|> ImagePipe.URL.group(resize: [width: 1200])

attachment

A boolean: attachment or attachment=false. Default: false.

attachment makes the browser download the response instead of displaying it, using Content-Disposition: attachment. attachment=false turns off an attachment set by a preset.

URL

/w=1200/format=jpeg/filename=beach/attachment/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(filename: "beach", attachment: true)
|> ImagePipe.URL.group(resize: [width: 1200])
|> ImagePipe.URL.output(format: :jpeg)

Pages and frames

page

Accepts a whole number of 0 or more. Default: the original's default image. That is the primary image of a HEIF or AVIF collection, the default image of an animated PNG, and the first page or frame of anything else.

page picks one page or frame of a multi-page or animated original, such as a TIFF, a GIF, or an animated WebP, counting from 0 in file order. The result is a single still image. For HEIF and AVIF collections, page=0 is the first image in the file, which can differ from the primary image.

  • A page past the last one fails with 422 and the body requested page does not exist in the source image. A still image has only page=0.
  • Frame N of an animation is built from all the frames before it, so the server's image size limit counts N + 1 frames. A late frame of a long animation can fail as too large where the first frame doesn't.
  • page also applies to output=info, which then describes that page. Its pages field gives the number of pages or frames.

URL

/w=400/page=2/src/scans/report.tiff

Elixir

ImagePipe.URL.new(page: 2)
|> ImagePipe.URL.group(resize: [width: 400])

Cache busting and expiry

cb

Accepts ASCII letters, digits, ., _, and -, at least one character. Default: none.

cb makes ImagePipe process the image again and store a separate copy, instead of serving a copy it stored for the same URL without cb. Because the URL changes, browsers and CDNs fetch it as a new URL. cb doesn't change the ETag, so a client that already has the image gets 304 Not Modified. Caching and freshness explains when stored copies are refreshed, and ETag covers the validators.

URL

/w=800/cb=release-2/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(cachebuster: "release-2")
|> ImagePipe.URL.group(resize: [width: 800])

expires

Accepts a positive whole number: a Unix time in seconds. Default: none.

The URL works up to and including that second. After it, the request fails with 410 and the body expired, before the image is fetched or a cached copy is served. Browsers and CDNs are never told to cache the response past that time (see expiring URLs).

Anyone can edit expires in an unsigned URL. When ImagePipe requires signed URLs, the signature covers expires, and you get it as part of the signed URL.

URL

/w=800/expires=2000000000/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(expires: 2_000_000_000)
|> ImagePipe.URL.group(resize: [width: 800])

Priority

priority

Accepts normal or low. Default: normal.

The server processes a limited number of images at once and queues the rest (see Limiting concurrent processing). Use priority=low for work that can wait and retry, such as fetching placeholders for a whole library or warming the cache with HEAD requests. Requests that users are waiting for then go first.

  • A low-priority request starts only when no normal request is waiting, and only while the server is processing fewer low-priority requests than its low-priority limit.
  • When the queue is full, a normal request takes the place of the newest waiting low-priority request. That request gets a 503.
  • While normal requests keep the queue busy, a low-priority request waits its full queue time and then gets a 503.

A 503 for a full or slow queue has a Retry-After header, set to how long the server lets a request wait for its turn, in whole seconds.

priority doesn't change the stored image or its ETag, so low-priority and normal requests share cached copies. A cached copy is served right away, whatever the priority. priority=normal turns off a priority=low set by a preset.

URL

/output=lqip-css/priority=low/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(priority: :low)
|> ImagePipe.URL.output(terminal: :lqip_css)

Debugging

debug

A boolean: debug or debug=false. Default: false.

debug adds X-ImagePipe-* and Server-Timing response headers that describe the original, the chosen output, the cache status, and the time each stage took. It never changes the image, the stored copy, or the ETag. Debug headers lists each header.

URL

/w=400/debug/src/photos/beach.jpg

Elixir

ImagePipe.URL.new(debug: true)
|> ImagePipe.URL.group(resize: [width: 400])