How-to library · Developer docs

How-to library

Task-shaped pages: a title that starts with a verb, the situation in a few lines, the steps, the working code in both engines, and why this way rather than another. Found from a search, done, and left.

How-to Images

Turn on picture tags and understand what changed in your markup

One setting, and every getHtml() and every richtext image becomes a picture element: a WebP source, an original-format source, an img fallback, 2x versions when the original is large enough. Your attributes land on the img.

Context

Context. The switch is a site setting, not a template change, so turning it on changes markup you did not touch. Knowing the exact shape saves an afternoon of CSS surprises.

Steps

  1. Turn on Generate picture tag under the image settings; keep Offer hq image on.
  2. Reload a page and inspect an image: an <img> became a <picture> with sources in a fixed order. Your class, alt and loading attributes are on the inner <img>.
  3. Check selectors that assumed the image was a direct child (.card > img): they now need .card > picture > img or a class on the image.
  4. Check scripts that swap src: with a picture element the sources win over src, so swap the srcset of the sources or replace the whole element.
  5. Check hand-written picture elements: use getPath() inside them, never getHtml(), or you get a picture inside a picture.

Code

HTML
<!-- before, and still what an SVG renders -->
<img src="/files/images/pages/1/logo.png" alt="Logo" class="img-fluid">

<!-- after: a WebP source, the original format, the img fallback; 2x when resized and the original is large enough -->
<picture>
  <source srcset="/files/images/pages/1/logo.webp?f=png 1x, /files/images/pages/1/logo.webp?f=png&w=960 2x" type="image/webp">
  <source srcset="/files/images/pages/1/logo.png 1x" type="image/png">
  <img src="/files/images/pages/1/logo.png" alt="Logo" class="img-fluid">
</picture>
Template code
{* the template call is unchanged in either engine *}
{$image->getResized(480, 480, 'fit')->getHtml(['class' => 'img-fluid', 'alt' => $image->getName()|escape])}
{{ image.getResized(480, 480, 'fit').getHtml({'class': 'img-fluid', 'alt': image.getName()|e}) }}

Why this and not that

Not a per-template opt-in: it does not exist; the setting is site-wide, which is the point, since rich-text images get it too. Not turning it off because one selector broke: fix the selector; the setting is the cheapest performance win on the platform. An image already converted in the template still works with the setting on; it simply has no separate WebP source to add.

Go deeper

Was this page helpful?

Your answer goes to the docs team.