Images in Stati Markdown and layouts

Where image paths point, what Stati adds to the images, and stati.image() for covers.

SNP 144 #A34 Filed stati markdown

markdown
![The harbour at dawn](/images/harbour.jpg)
![Map of the route](./route.png)
![A 16 × 16 sprite](/images/sprite.png?raw)
  • /images/harbour.jpg is read from public/, and ./route.png from next to the Markdown file, which Stati copies to /_img/route-<hash>.png.
  • Both get their width and height from the file, plus loading="lazy" and decoding="async". A page's first image near the top loads eagerly with fetchpriority="high" instead.
  • ?raw leaves an image exactly as written, and is removed from the path. It's for pixel art and anything else to keep away from processing. Remote URLs, SVGs and <img> tags are never touched.
  • Those sizes need img { max-width: 100%; height: auto; } in the CSS, or a narrowed image keeps its full height.

In a layout, stati.image() does the same for an image from front matter, such as a cover:

eta
<%~ stati.image(stati.page.cover, { alt: stati.page.coverAlt ?? '', priority: true }) %>

It returns HTML, hence <%~. It returns nothing when cover is empty and warns when there's no alt, and priority: true is for the one image at the top of the page.

With the @stati/images package installed, images: { responsive: true } turns all of these into <picture>s with AVIF and WebP in several widths. The default sizes is 100vw, so tell it how wide your column really is, or a desktop browser downloads an image as wide as the window:

typescript
images: {
  responsive: { sizes: '(min-width: 800px) 720px, calc(100vw - 40px)' },
},

In the Stati docs: Images, Images in templates and Responsive images.