Image shortcode basics
Render a responsive image with one line of template code.
What comes back is more markup than you would want to write by hand, and the point of this guide is a feel for what the shortcode is doing on your behalf.
Baseline's image shortcode is a thin wrapper over Eleventy Image, and it's the only shortcode the plugin ships. A shortcode is just a template helper Eleventy invokes with {% image %} syntax.
Although you could place your media directory anywhere you'd like, Baseline's convention is src/media/. If you are used to have them under assets/img/, in Baseline that directory is reserved for global image assets.
What you will build
- A page rendering a
<picture>withavif,webpandjpegsources. - Multiple widths of the same image emitted to
/dist/media/.
Prerequisites
@11ty/eleventy-img. It is a peer dependency, so npm installs it alongside Baseline and you normally have it without asking. If it is missing, npm install @11ty/eleventy-img.
Add a sample image
Place any jpg or png image of your choice at src/media/. Rename it example.{jpg, png} for this tutorial. The format you start from matters less than what you put in alt.
Note that eleventy-img doesn't upscale your images; if your image is 640px only 320w + 640w of the default widths will be generated.
Use the shortcode in a page
Create src/content/pages/image-demo.md:
---
title: 'Image Shortcode Demo'
slug: 'image-demo'
description: 'Responsive image via Baseline shortcode.'
layout: 'layouts/base.njk'
---
This page displays an image using the {% raw %}`{% image {} %}`{% endraw %} shortcode.
{% image {
src: "/media/example.jpg",
alt: "A descriptive alt text for accessibility",
caption: "Example image rendered responsively with the image shortcode."
} %}
The shortcode brings a set of defaults so you don't have to think about responsive widths or modern formats unless you want to:
- Widths:
[320, 640, 960, 1280, 1920] - Formats:
["avif", "webp", "jpeg"], in negotiation order, withjpeglast as the one every client can read - Output:
./dist/media/, URL:/media/. In a build the files are written to.cache/media/first and copied across, so wipingdistdoes not cost you a re-encode. - Sizes:
"auto"on lazy images, so the browser uses the real layout width, with"(max-width: 768px) 100vw, 768px"behind it for browsers that cannot loading: "lazy",decodingauto-set, and a<figure>wrapper ifcaptionis provided. Width and height are set by default.
The defaults aim to be cheap and safe, so anything expensive is opt-in. That is why 'auto', the full-size re-encode, is not in the width list: add it to widths when you want it. And the auto in sizes lets the browser use the width the image is really laid out at instead of trusting a number written here about your layout; browsers without it fall through to the rest of the list.
If a set suits your whole project, set it once at registration with media: { image: { widths, formats, sizes } } rather than on every call. See Image shortcode.
Paths are resolved from the project's input directory automatically: a leading-slash path like /media/example.jpg maps to src/media/example.jpg. A fully qualified path works too if that suits the project better.
- Dot-relative paths (
./src/media/example.jpg,./example.jpg) will not resolve. Stick to a leading slash fromsrc/, like/media/example.jpg.
The defaults cover most pages. Reach into the options when a particular image needs different handling. See the image shortcode reference for the full option list.
Run and verify
npm start
- Open
/image-demo/and inspect the<picture>and<source>tags. - Check
/dist/media/for generated variants (named likeexample-a1b2c3-768w.avif; the hash is derived from the image content, which is what lets the build cache reuse them safely).
Production build
npm run build
Recheck /dist/media/ and the rendered HTML in dist/image-demo/index.html. A build pre-generates every variant up front, where npm start defers them to the first request.
Run it a second time and the images are not re-encoded: a build keeps its renditions in .cache/media/ and copies them over. See Caching for what that means on a deploy, and for the one case where you want to clear it by hand.
Notes
- Keep
altmeaningful. Captions are optional; alt text isn't. - Reasonably sized originals are kinder to the build. Very large inputs generate very large outputs.
- The shortcode emits site-root-relative paths (
/media/...). For an absolute image URL, e.g. to set as a page'sogImageshare card, combine the path withsettings.urlfrom_data/settings.js. - In dev (when
ELEVENTY_RUN_MODE=serve), the shortcode uses Eleventy Image'stransformOnRequestmode, which defers image processing to the first browser request and keeps server startup snappy. During the content-graph pre-pass it usesstatsOnlyinstead, which skips the same work but keeps the real image URLs, so your images are encoded once per build rather than twice. Builds pre-generate everything as usual. If either call fails, the shortcode retries without the flag.
Optional: use the Image Transform plugin
Prefer not to call a shortcode at all? Eleventy's Image Transform plugin processes every <img> and <picture> tag it finds. The trade-off is exactly that: it touches everything rather than the images you opt in to. Image transform is the recipe, and the Image plugin docs cover the configuration.
See also
- Image shortcode - every argument the shortcode takes.
- Image transform - the transform-plugin route, in full.
- Site settings -
settings.url, for turning a/media/path into an absolute share-card URL.