UNPKG

eleventy-plugin-img2picture

Version:

Eleventy plugin to replace <img> using <picture> with resized and optimized images.

249 lines (201 loc) 17.2 kB
# eleventy-plugin-img2picture Eleventy plugin to replace `<img>` using `<picture>` with resized and optimized images. This plugin is inspired by [eleventy-plugin-local-respimg](https://github.com/chromeos/static-site-scaffold-modules/tree/main/modules/eleventy-plugin-local-respimg) by [Sam Richard](https://twitter.com/Snugug/). Requires **Node v18.17+**. <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> ## Table of Contents - [Features](#features) - [Supported Image Formats](#supported-image-formats) - [Usage](#usage) - [Basic Usage](#basic-usage) - [Recommended Usage](#recommended-usage) - [Options](#options) - [Remote images](#remote-images) - [Attributes on `<img>`](#attributes-on-img) - [Ignore Images](#ignore-images) - [Specify widths on `<img>`](#specify-widths-on-img) - [Specify `class` for enclosing `<picture>` tags through `<img>`](#specify-class-for-enclosing-picture-tags-through-img) - [Disk Cache](#disk-cache) - [Example](#example) - [FAQs](#faqs) - [How to pick the right `sizes`?](#how-to-pick-the-right-sizes) - [How is this plugin different from others?](#how-is-this-plugin-different-from-others) <!-- END doctoc generated TOC please keep comment here to allow auto update --> ## Features - Drop-in plugin to replace all `<img>` in your website without shortcodes. - [Ignore image using data attribute](#ignore-images). - Download, cache, and optimize [remote images](#remote-images). - Skip processing unchanged and already existing images in the output directory. See [disk cache](#disk-cache). ## Supported Image Formats This plugin uses [`eleventy-img`](https://www.11ty.dev/docs/plugins/image/) to optimize, and generate different sizes and formats of images. All [formats supported](https://www.11ty.dev/docs/plugins/image/#output-formats) by `eleventy-img` are supported by `eleventy-plugin-img2picture`. ## Usage ### Basic Usage ```js const img2picture = require("eleventy-plugin-img2picture"); module.exports = function (eleventyConfig) { eleventyConfig.addPlugin(img2picture, { // Should be same as Eleventy input folder set using `dir.input`. eleventyInputDir: ".", // Output folder for optimized images. imagesOutputDir: "_site", // URL prefix for images src URLS. // It should match with path suffix in `imagesOutputDir`. // Eg: imagesOutputDir with `_site/images` likely need urlPath as `/images/` urlPath: "", }); }; ``` ### Recommended Usage 👋 It's recommended to use the plugin only on production builds (E.g.: `$ ELEVENTY_ENV=production eleventy`). The plugin works fine with [basic usage](#basic-usage). Just that, your Eleventy builds will be quite slow. ```js module.exports = function (eleventyConfig) { if (process.env.ELEVENTY_ENV === "production") { eleventyConfig.addPlugin(img2picture, { // Should be same as Eleventy input folder set using `dir.input`. eleventyInputDir: ".", // Output folder for optimized images. imagesOutputDir: "_site", // URL prefix for images src URLS. // It should match with path suffix in `imagesOutputDir`. // Eg: imagesOutputDir with `_site/images` likely need urlPath as `/images/` urlPath: "", }); } else { // During development, copy the files to Eleventy's `dir.output` eleventyConfig.addPassthroughCopy("./images"); } }; ``` ### Options | Name | Type | Default | Description | | ------------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | eleventyInputDir | `string` | | 🚨 Required<br><br>Eleventy input directory. Should be same as Eleventy’s `dir.input`. | | imagesOutputDir | `string` | | 🚨 Required<br><br>Output folder for optimized images. | | urlPath | `string` | | 🚨 Required<br><br>URL prefix for images src URLS. It should match with path suffix in `imagesOutputDir`. Eg: imagesOutputDir with `_site/images` likely need urlPath as `/images/` | | extensions | `array` | `["jpg", "png", "jpeg", "svg"]` | File extensions to optmize. | | formats | `array` | `["avif", "webp", "svg", "jpeg"]` | Formats to be generated.<br><br>⚠️ The <source> tags are ordered based on the order of formats in this array. Keep most compatible format at the end. | | sizes | `string` | `"100vw"` | Default image [`sizes`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#sizes) attribute | | minWidth | `number` | `150` | Minimum image width to be generated | | maxWidth | `number` | `1500` | Maximum image width to be generated | | hoistImgClass | `boolean` | `false` | Move `class` attribute on `<img>` element to enclosing `<picture>` element. | | pictureClass | `string` | `""` | Class attribute for the newly created `<picture>` elements | | widthStep | `number` | `150` | Width increments between each generated image | | fetchRemote | `boolean` | `false` | Fetch, cache, and optimize remote images. | | dryRun | `boolean` | `false` | Don't generate image files. Only HTML tags are generated. | | svgShortCircuit | `boolean \| "size"` | `"size"` | See [Eleventy Image Documentation](https://www.11ty.dev/docs/plugins/image/#skip-raster-formats-for-svg)<br><br> ℹ️ [What is SVG short circuiting?](https://www.zachleat.com/web/svg-short-circuit/) | | svgCompressionSize | `undefined \| "br"` | `undefined` | See [Eleventy Image Documentation](https://www.11ty.dev/docs/plugins/image/#skip-raster-formats-for-svg) | | filenameFormat | `function` | [`filenameFormatter()`](https://github.com/saneef/eleventy-plugin-img2picture/blob/b56ff9c3785700e68e37f2a1ed1a9ea12744ad73/lib/img2picture.js#L85) | Function used by [`eleventy-img`](https://www.11ty.dev/docs/plugins/image/) to generate image filenames. | | cacheOptions | `object` | `{}` | Cache options passed to [`eleventy-cache-assets`](https://www.11ty.dev/docs/plugins/cache/). | | sharpOptions | `object` | `{}` | Options passed to [Sharp constructor](https://sharp.pixelplumbing.com/api-constructor#parameters). | | sharpWebpOptions | `object` | `{}` | Options passed to [Sharp image format converter] for webp(https://sharp.pixelplumbing.com/api-output#webp). | | sharpPngOptions | `object` | `{}` | Options passed to [Sharp image format converter for png](https://sharp.pixelplumbing.com/api-output#png). | | sharpJpegOptions | `object` | `{}` | Options passed to [Sharp image format converter for jpeg](https://sharp.pixelplumbing.com/api-output#jpeg). | | sharpAvifOptions | `object` | `{}` | Options passed to [Sharp image format converter for avif](https://sharp.pixelplumbing.com/api-output#avif). | ### Remote images Set `fetchRemote: true` in options to download, cache, and optimize remote images. `fetchRemote` is `false` by default. Use [`cacheOptions` passed to `eleventy-cache-assets`](https://www.11ty.dev/docs/plugins/cache/#options) to change cache settings like, cache duration, and path. ### Attributes on `<img>` - `sizes` will be hoisted on `<source>` elements. - `src`, `width`, and `height` attributes will be replaced with corresponding values based on the optimized image. - All other attributes on `<img>` will be retained. #### Ignore Images Images with `data-img2picture-ignore="true"` or `data-img2picture-ignore` will be ignored by the plugin. ```html <img data-img2picture-ignore="true" src="/images/sunset-by-bruno-scramgnon.jpg" alt="Sunset" /> ``` #### Specify widths on `<img>` You can provide a comma separated list of widths using `data-img2picture-widths`. This will override default widths computed from config (`minWidth`, `maxWidth`, and `widthStep`) for a particular `<img>`. ```html <img data-img2picture-widths="200,400,600,800" src="/images/sunset-by-bruno-scramgnon.jpg" alt="Sunset" /> ``` #### Specify `class` for enclosing `<picture>` tags through `<img>` You can provide class attribute for the enclosing `<picture>` using `data-img2picture-picture-class` data attribute. This will override the class provided using `pictureClass` option. ```html <img data-img2picture-picture-class="w-full" src="/images/sunset-by-bruno-scramgnon.jpg" alt="Sunset" /> ``` ### Disk Cache Disk cache is a feature provided by the [`eleventy-img` plugin](https://www.11ty.dev/docs/plugins/image/). This plugin will skip unchanged, and already existing images in the output path. If you don't delete generated image between builds, you'll get faster builds. [This sample project](https://github.com/11ty/demo-eleventy-img-netlify-cache) shows how to persist disk cache across Netlify builds. ### Example ```html <img class="w-full" src="shapes.png" alt="Shapes" data-variant="bleed" loading="eager" decoding="auto" /> ``` ...will generate: ```html <picture class="w-full" ><source type="image/avif" srcset=" shapes-150w.avif 150w, shapes-300w.avif 300w, shapes-450w.avif 450w, shapes-600w.avif 600w, shapes-750w.avif 750w, shapes-900w.avif 900w, shapes-1050w.avif 1050w, shapes-1200w.avif 1200w, shapes-1350w.avif 1350w " sizes="100vw" /> <source type="image/webp" srcset=" shapes-150w.webp 150w, shapes-300w.webp 300w, shapes-450w.webp 450w, shapes-600w.webp 600w, shapes-750w.webp 750w, shapes-900w.webp 900w, shapes-1050w.webp 1050w, shapes-1200w.webp 1200w, shapes-1350w.webp 1350w " sizes="100vw" /> <source type="image/jpeg" srcset=" shapes-150w.jpeg 150w, shapes-300w.jpeg 300w, shapes-450w.jpeg 450w, shapes-600w.jpeg 600w, shapes-750w.jpeg 750w, shapes-900w.jpeg 900w, shapes-1050w.jpeg 1050w, shapes-1200w.jpeg 1200w, shapes-1350w.jpeg 1350w " sizes="100vw" /> <img src="shapes-150w.jpeg" width="1350" height="1350" alt="Shapes" data-variant="bleed" sizes="100vw" loading="eager" decoding="auto" /></picture> ``` ## FAQs ### How to pick the right [`sizes`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes)? I highly recommend to use the magical [respimagelint - Linter for Responsive Images](https://ausi.github.io/respimagelint/) by [Martin Auswöger](https://twitter.com/ausi). ### How is this plugin different from others? Plugins like [`eleventy-plugin-respimg`](https://www.npmjs.com/package/eleventy-plugin-respimg), and [`eleventy-plugin-images-responsiver`](https://github.com/nhoizey/images-responsiver/tree/main/packages/eleventy-plugin-images-responsiver/) utilizes shortcodes or attributes to optimize images. The `eleventy-plugin-img2picture` doesn't rely on shortcode. It optimizes all `<img>` matching the file extensions. You can exclude `<img>` using data attribute `data-img2picture-ignore`.