Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/avifImageService.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,32 @@ import sharp from "sharp";

sharp.concurrency(1);

// Width of the Starlight content column: keep in sync with --sl-content-width in
// src/assets/css/variables.css. Images can never be displayed wider than this.
const CONTENT_WIDTH_REM = 47;
const CONTENT_WIDTH_PX = CONTENT_WIDTH_REM * 16;

export default {
...sharpService,

// Let SVGs skip validation entirely — sharp can't process them
validateOptions(options, config) {
if (options.src?.format !== "svg") {
options.format = "avif";

// Astro's "constrained" layout generates
// sizes="(min-width: <image width>px) <image width>px, 100vw"
// which tells the browser the image may fill the whole viewport. Here it
// never does (the content column is capped), so browsers pick huge
// srcset candidates: the 3840w file on a 1440px laptop at 2x, or the 2048w
// file on a 1080p monitor at 1x. Use the real maximum display width instead.
// Images narrower than the column keep Astro's value, which is already correct.
if (
options["data-astro-image"] === "constrained" &&
options.width > CONTENT_WIDTH_PX
) {
options.sizes = `(min-width: ${CONTENT_WIDTH_REM}rem) ${CONTENT_WIDTH_REM}rem, 100vw`;
}
}
return sharpService.validateOptions(options, config);
},
Expand Down
Loading