
Quick Start: Eleventy Shortcodes for Responsive Images & Inline SVG
Quick start to production-ready Eleventy shortcodes: responsive images with @11ty/eleventy-img and inline SVG helpers you can copy-paste and use immediately.
This guide shows how to add two production-ready shortcodes to Eleventy (ESM): a responsive image helper using @11ty/eleventy-img and an inline SVG helper that lets you inject CSS classes.

Quick Start
Follow these steps to get ready-to-use shortcodes in minutes:
-
Install dependency
Terminal window npm i @11ty/eleventy-img -
Create the shortcodes module at
eleventy/shortcodes/media.js(see below) -
Register it in
eleventy.config.jsand rebuild -
Use
{% image %}for responsive images and{% svg %}for inline SVG in your Nunjucks templates
What you get
The {% image %} shortcode outputs a <picture> element with AVIF/WebP sources, responsive widths, lazy loading, and decoding hints—all preconfigured for production use.
Prerequisites
- Eleventy v2+ or v3 with ESM config.
- Nunjucks templates (examples use
{% %}tags). - Project layout with assets under
src/.
Example folders:
src/ assets/ images/ icons/Install
npm i @11ty/eleventy-imgShortcodes module
Create eleventy/shortcodes/media.js:
import path from "node:path";import fs from "node:fs";import Image from "@11ty/eleventy-img";
/** Responsive image (async) */async function imageShortcode(src, alt, sizes = "100vw") { if (!alt) throw new Error(`Missing alt for ${src}`);
// Normalize to src/assets/images/ const normalized = src.replace(/^\/?src\/assets\/images\/?/, ""); const resolved = path.resolve("src/assets/images", normalized);
const metadata = await Image(resolved, { widths: [320, 640, 960, 1280, null], // null => original width formats: ["avif", "webp"], // add "jpeg" if you want a fallback outputDir: "./_site/img/", urlPath: "/img/", });
return `<figure>${Image.generateHTML(metadata, { alt, sizes, loading: "lazy", decoding: "async", })}</figure>`;}
/** Inline SVG with optional class */function svgShortcode(svgPath, className = "") { const rel = svgPath.replace(/^\/?src\/?/, ""); // keep paths under src/ const fullPath = path.join(process.cwd(), "src", rel); const svg = fs.readFileSync(fullPath, "utf8");
if (!className) return svg;
// Append or set class on the opening <svg ...> const hasClass = /<svg([^>]*?)\sclass="([^"]*)"/i.test(svg); if (hasClass) { return svg.replace( /<svg([^>]*?)\sclass="([^"]*)"([^>]*)>/i, (_m, pre, cls, post) => `<svg${pre} class="${cls} ${className}"${post}>` ); } return svg.replace(/<svg([^>]*)>/i, `<svg$1 class="${className}">`);}
export default (cfg) => { cfg.addNunjucksAsyncShortcode("image", imageShortcode); cfg.addNunjucksShortcode("svg", svgShortcode);};Register in Eleventy config
In eleventy.config.js (ESM):
import mediaShortcodes from "./eleventy/shortcodes/media.js";
export default function(eleventyConfig) { eleventyConfig.addPlugin(mediaShortcodes);}Usage in Nunjucks
Responsive image (async shortcode):
{% image "hero/cover.jpg", "Site cover image", "(min-width: 768px) 75vw, 100vw" %}Inline SVG with a custom class:
{% svg "assets/icons/github.svg", "icon-lg text-neutral-700" %}Alternative: expression style
If you prefer {{ ... }} output for SVG, also register:
// in the plugin functioncfg.addShortcode("svg", svgShortcode);Then:
{{ svg("assets/icons/github.svg", "icon-lg") | safe }}Troubleshooting and notes
- “Unable to call ‘svg’…” means you registered with
addShortcodebut used{% svg %}. UseaddNunjucksShortcodefor tag syntax. - Paths: keep inputs relative to
src/…. The module normalizessrc/assets/images/...automatically for images andsrc/...for SVGs. - Accessibility:
altis required. Use emptyaltonly for decorative images. - Fallbacks: if you need a bitmap fallback, add
"jpeg"toformats. - Caching:
@11ty/eleventy-imgcaches processed assets. Commit the cache if you want stable builds in CI.
Additional tips:
- ESM vs CJS configs: This example assumes ESM. If you are on CommonJS, adapt imports/exports accordingly.
- Windows paths: Prefer
path.resolveand avoid hardcoded backslashes. The provided code handles normalization. - External URLs: The shortcode expects local files. For remote images, download them during build or provide a local copy.
Next steps
Want automatic optimization for standard Markdown images (no shortcode required)? Continue with the advanced guide:
Minimal CSS example
.icon-lg { width: 1.5rem; height: 1.5rem; display: inline-block; }Commit message template
feat(shortcodes): add responsive image and inline SVG helpers (Nunjucks, ESM)