- Stable
3.0.0
- Canary
3.0.1-alpha.1
Toggle Menu
5.81s
43.36s
Image
Utility to perform build-time image transformations for both vector and raster images: output multiple image sizes, multiple formats, and cache remote images locally. Uses the sharp image processor.
- Easily add
width
andheight
attributes for proper aspect ratio to reduce layout shift. - Accepts a wide variety of input image types:
jpeg
,png
,webp
,gif
,tiff
,avif
, andsvg
. Does not rely on file extensions (e.g..png
or.jpg
), which may be missing or inaccurate. - Output multiple sizes, maintaining the original aspect ratio. Does not upscale raster images larger than original size. Intelligently generates
srcset
attributes. - Output multiple formats:
jpeg
,png
,webp
,avif
+1
Build Cost, andsvg
. Intelligently generates the most efficient markup with zero server-dependencies, using<img>
or<picture>
. - Fast: de-duplicates with both an in-memory and disk cache. During local development, images are processed on request for even faster build performance.
- Robust and works offline: save remote images to prevent broken image URLs later (via
eleventy-fetch
).
Installation
Published as @11ty/eleventy-img
on npm. Source code on GitHub.
Image v6.0.0 requires Node 18+.
npm install @11ty/eleventy-img
Usage
There are a few different ways to use Eleventy image:
- Image HTML Transform: Recommendedβstart with this one! Itβs the easiest to configure and is compatible with all template syntax.
- Image Data Files: Use images to populate data in the Data Cascade.
- Image JavaScript API: Low-level JavaScript API works independent of Eleventy.
- Image Shortcodes: Use universal shortcodes in Nunjucks, Liquid, or 11ty.js templates.
- Image WebC: Use a WebC component for WebC templates.
HTML Transform
Added in v3.0.0 Added in Image v4.0.1This is the easiest method to configure. Eleventy will transform any <img>
or <picture>
tags in HTML files as a post-processing step in your build.
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin);
};
const { eleventyImageTransformPlugin } = require("@11ty/eleventy-img");
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin);
};
Thatβs it! All <img>
and <picture>
elements will be processed for you by Eleventy Image.
Resolving image sources
- Relative image sources (
<img src="./possum.png">
) will be co-located to your output directory with the template they are used in. If the same source image is used in multiple templates, it will be written to two different output locations! - Absolute image sources (
<img src="/possum.png">
) will be normalized relative to your input/content directory and written to your output directory with the default directory (e.g._site/img/
).
If you explicitly define the urlPath
option, the urlPath
is used to determine the output location instead.
Attribute Overrides
You can configure individual <img>
elements with per-instance overrides:
<img width>
is aliased toeleventy:widths
when it is valid HTML (a singleinteger
value) Added in Image v6.0.0 Related #234.<img eleventy:widths="200,600">
comma separated string to override the default widths.<img eleventy:formats="webp">
comma separated string to override the default formats.<img eleventy:ignore>
skips this image.<img eleventy:optional>
Added in Image v6.0.0controls what happens when processing this image throws an Error (good for remote images), seefailOnError
option. Default behavior removes thesrc
attribute from the<img>
node.<img eleventy:optional="keep">
: leave as-is, which would likely result in an error when a user visits your page.<img eleventy:optional="placeholder">
: replace thesrc
attribute with a transparent PNG Data URI.
<img eleventy:output>
overrides the output directory. Similar tourlPath
, absolute paths (e.g.<img eleventy:output="/mydirectory/">
) are relative to the Eleventy output directory and relative paths are relative to the templateβs URL (e.g.<img eleventy:output="./mydirectory/">
).<img eleventy:pictureattr:NAME="VALUE">
Added in Image v6.0.0 attributes are hoisted as<picture NAME="VALUE">
(if<picture>
is in use)
More configuration options
Any of the configuration options can be defined when you add the plugin:
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
// output image formats
formats: ["avif", "webp", "jpeg"],
// output image widths
widths: ["auto"],
// optional, attributes assigned on <img> nodes override these values
htmlOptions: {
imgAttributes: {
loading: "lazy",
decoding: "async",
},
pictureAttributes: {}
},
});
};
const { eleventyImageTransformPlugin } = require("@11ty/eleventy-img");
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
// output image formats
formats: ["avif", "webp", "jpeg"],
// output image widths
widths: ["auto"],
// optional, attributes assigned on <img> nodes override these values
htmlOptions: {
imgAttributes: {
loading: "lazy",
decoding: "async",
},
pictureAttributes: {}
},
});
};
- Added in v3.0.0Added in Image v5.0.0During local development (when using
--serve
), images are optimized when requested in the browser. Read more abouttransformOnRequest
. - The
sizes
attribute must be present ifwidths
has more than one entry (MDN). TheeleventyImageTransformPlugin
does not provide a default value forsizes
, so it must be explicitly included in the HTML attribute or withhtmlOptions.imgAttributes
.- Added in Image v6.0.0When using
loading="lazy"
andsizes
is not supplied in markupβββweβll usesizes="auto"
automatically. Related #207.
- Added in Image v6.0.0When using
Build Performance
Image optimization is likely one of the costlier pieces of your Eleventy build. The total build cost of this utility is dependent on a few things (in order of priority):
- Number of unique images optimized (not page count)
- Optimizing a lot of remote images (image content must be fetched from a remote server and is subsequently cached via
eleventy-fetch
). - Number of
formats
you generate for each source image:avif
is more costly than other image formats.+1
Build Cost - Number of
widths
you generate for each source image. - File size of images being optimized (larger source images are more expensive).
Optimize Images on Request
Added in v3.0.0Added in Image v5.0.0When using the Image HTML transform or the Image WebC component during local development, image processing is removed from the build for extra performance. Instead, they are processed when requested by the browser using a special middleware built-in to the Eleventy Dev Server. This is enabled or disabled using the transformOnRequest
option.
In-Memory Cache
To prevent duplicate work and improve build performance, repeated calls to the same source image (remote or local) with the same options will return a cached results object. If a request in-progress, the pending promise will be returned. This in-memory cache is maintained across builds in watch/serve mode. If you quit Eleventy, the in-memory cache will be discarded.
Images will be regenerated (and the cache bypassed) if:
- The source image file size changes (on local image files)
- The cache asset duration expires (for remote images).
You can disable this behavior by using the useCache
option.
Example of in-memory cache reuse (returns the same promise)
import Image from "@11ty/eleventy-img";
let stats1 = Image("./test/bio-2017.jpg");
let stats2 = Image("./test/bio-2017.jpg");
console.assert(stats1 === stats2, "The same promise");
Example of in-memory cache (returns a new promise with different options)
import Image from "@11ty/eleventy-img";
let stats1 = Image("./test/bio-2017.jpg");
let stats2 = Image("./test/bio-2017.jpg", { widths: [300] });
console.assert(stats1 !== stats2, "A different promise");
Disk Cache
Added in Image v1.0.0 Eleventy will skip processing files that are unchanged and already exist in the output directory. This requires the built-in hashing algorithm and is not supported with custom filenames. More background at Issue #51.
You can use this to speed up builds on your build server.
Options
Output File Extensions
Comma separated list of file extensions used in the Image HTML Transform to determine which template output files to process.
extensions: "html"
(default)
Output Widths
Controls how many output images will be created for each image format. Aspect ratio is preserved.
widths: ["auto"]
(default, keep original width)widths: [200]
(output one 200px width)widths: [200, "auto"]
(output 200px and original width)
Output Formats
Use almost any combination of webp
, jpeg
, png
, svg
, avif
, gif
, and auto
:
formats: ["webp", "jpeg"]
(default)formats: ["png"]
formats: ["auto"]
(keep original format)formats: ["svg"]
(requires SVG input)formats: ["avif"]
+1
Build Cost
Skip raster formats for SVG
If using SVG output (the input format is SVG and svg
is added to your formats
array), we will skip all of the raster formats even if theyβre in formats
. This may be useful in a CMS-driven workflow when the input could be vector or raster.
svgShortCircuit: false
(default)svgShortCircuit: true
svgShortCircuit: "size"
Added in Image v3.1.8
Using svgShortCircuit: "size"
means that raster image format entries will only be thrown out if the optimized raster size is larger than the SVG. This helps with large SVG images that compress to smaller raster sizes at smaller widths and will prefer the SVG over raster formats when the SVG file size is smaller.
To use Brotli compressed SVG sizes when making file size comparisons, use the svgCompressionSize: "br"
option Added in Image v3.1.8.
Related:
Allow SVG to upscale
While we do prevent raster images from upscaling (and filter upscaling widths
from the output), you can optionally enable SVG input to upscale to larger sizes when converting to raster format.
svgAllowUpscale: true
(default)svgAllowUpscale: false
Transparent Images
Transparency friendly formats: avif
, png
, webp
, gif
, and svg
.
Added in Image v6.0.0We will filter out any non-transparency-friendly output formats from your formats
list automatically (as long as at least one of them is png
, gif
, or svg
).
Animated Images
Added in Image v1.1.0 To process and output animated gif
or webp
images, use sharpOptions
to pass in an animated
option.
import Image from "@11ty/eleventy-img";
await Image("./test/bio-2017.jpg", {
formats: ["webp", "gif"],
sharpOptions: {
animated: true,
},
});
Added in Image v6.0.0We will filter out any non-animation-friendly output formats from your formats
list automatically (as long as at least one of them supports animation).
Transform on Request
Development build performance improvement to optimize images when they are requested in the browser.
transformOnRequest: false
(default)transformOnRequest: process.env.ELEVENTY_RUN_MODE === "serve"
(default for HTML Transform and WebC component)
You can use transformOnRequest
with Shortcodes too.
returnType
and htmlOptions
By default, Eleventy Image will return a metadata JavaScript object. To return HTML instead, use returnType: "html"
. This is useful for the Image JavaScript API and Image Shortcode types.
returnType: "object"
(default) or"html"
Added in Image v6.0.0
Further customize the markup with htmlOptions
Added in Image v6.0.0:
{
// β¦
returnType: "html",
htmlOptions: {
imgAttributes: {
alt : "", // required
loading: "lazy",
decoding: "async",
},
// HTML attributes added to `<picture>` (omitted when <img> used)
pictureAttributes: {},
// Which source to use for `<img width height src>` attributes
fallback: "largest", // or "smallest"
}
}
Fix Orientation
Added in Image v4.0.0Rotates the image to enforce the correct orientation set in EXIF metadata.
fixOrientation: false
(default)fixOrientation: true
Custom Filenames
Donβt like the hashes used in output file names? Make your own!
{
// β¦
filenameFormat: function (id, src, width, format, options) {
// Define custom filenames for generated images
// id: hash of the original image
// src: original image path
// width: current width in px
// format: current file format
// options: set of options passed to the Image call
return `${id}-${width}.${format}`;
}
}
Custom Filename Example: Use the original file slug
import path from "node:path";
import Image from "@11ty/eleventy-img";
await Image("./test/bio-2017.jpg", {
widths: [300],
formats: ["auto"],
filenameFormat: function (id, src, width, format, options) {
const extension = path.extname(src);
const name = path.basename(src, extension);
return `${name}-${width}w.${format}`;
},
});
// Writes: "test/img/bio-2017-300w.jpeg"
Dry-Run
If you want to try the utility out and not write any files (useful for testing), use the dryRun
option. Will include a buffer
property in your return object.
dryRun: false
(default)dryRun: true
Advanced Options
Fail on Error
Added in Image v6.0.0What happens when processing an image encounters an error? Useful for remote images.
failOnError: true
(default)failOnError: false
no error is thrown (warning output is logged)
See also the eleventy:optional
attribute. Related #225
Format Filtering
Added in Image v6.0.0When using animated images or images with transparency, we will automatically filter your output formats
list to formats that support those features. If there are no valid formats
left after filtering, the original formats
list is used as-is. You can enable or disable this feature using the formatFiltering
option.
formatFiltering: ["transparent", "animated"]
Output Directory
Where to write the new images to disk. Project-relative path to the output image directory. Maybe you want to write these to your output directory directly (e.g. ./_site/img/
)?
outputDir: "./img/"
(default)
If youβre using the Image HTML Transform, we recommended not to define outputDir
.
URL Path
A path-prefix-esque directory for the <img src>
attribute. e.g. /img/
for <img src="/img/MY_IMAGE.jpeg">
:
urlPath: "/img/"
(default)
Added in Image v6.0.0Full URLs are now supported, e.g. urlPath: "https://example.com/img/"
. Related #239.
If youβre using the Image HTML Transform, we recommended not to define urlPath
.
Use Cache
(Boolean) Controls whether to use the disk cache and memory cache.
useCache: true
(default)useCache: false
to bypass the cache and generate a new image every time.
Advanced control of Sharp image processor
Extra options to pass to the Sharp constructor or the Sharp image format converter for webp, png, jpeg, or avif.
sharpOptions: {}
sharpWebpOptions: {}
sharpPngOptions: {}
sharpJpegOptions: {}
sharpAvifOptions: {}
Added in Image v6.0.0ICC Profiles are preserved by default (when available) for better colors when images have srgb
, p3
, or cmyk
color profiles. Related #244.
Full Sharp API Access
Use the transform
callback to access anything in the Sharp API. Related #52. This runs before Eleventy Image processing (keep EXIF metadata, rotation, cropping, et al).
{
// β¦
transform: (sharp) => {
sharp.keepExif();
}
}
Change Global Plugin Concurrency
import Image from "@11ty/eleventy-img";
Image.concurrency = 4; // default is between 8 and 16 based on os.availableParallelism()
Change the default Hash length
You can customize the length of the default filename format hash by using the hashLength
property.
{
// β¦
hashLength: 8, // careful, donβt make it _too_ short!
}
Advanced Caching Options for Remote Images
For any full URL first argument to this plugin, the full-size remote image will be downloaded and cached locally. See all relevant eleventy-fetch
options.
{
// β¦
cacheOptions: {
// if a remote image URL, this is the amount of time before it fetches a fresh copy
duration: "1d",
// project-relative path to the cache directory
directory: ".cache",
removeUrlQueryParams: false,
},
}
When caching remote images, you may want to check the processed image output into your git
(et al) repository to avoid refetches in the future. If remote images are not checked in, they may be refetched every time on your CI server unless you preserve the .cache
folder between builds.
Using a Hosted Image Service
Custom URLs
Want to use a hosted image service instead? You can override the entire URL. Takes precedence over filenameFormat
option. Useful with statsSync
or statsByDimensionsSync
.
The metadata object returned will not include filename
or outputPath
properties.
{
// β¦
urlFormat: function ({
hash, // not included for `statsOnly` images
src,
width,
format,
}) {
return `https://example.com/${encodeURIComponent(src)}/${width}/${format}/`;
}
}
Stats Only
Added in Image v1.1.0 Skips all image processing to return metadata. Doesnβt write files. Use this as an alternative to the separate statsSync*
functionsβthis will use in-memory cache and de-duplicate requests.
statsOnly: false
(default)statsOnly: true
From the Community
Γ99 resources via 11tybundle.dev curated by Bob Monsour.