Serve compressed WebP images - #1210
Merged
Merged
Conversation
marcbachmann
approved these changes
Aug 20, 2026
Markdown paths resolve against the page URL and shortcode paths against the source file, so the paths shift one level. Also replaces placeholder alt text with descriptions, including the architecture diagrams that had none. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolving the file as a resource is what publishes it, which plain markdown links do not do. Needs the content directory mounted into assets so resources.Get can reach files that sit next to a page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Originals are no longer published, so anything referencing an asset must go through .RelPermalink. That is why illu-teaser now resolves its SVGs through the partial instead of emitting a raw path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A render hook cannot fix llms.txt, which is built with .RenderShortcodes and never runs hooks, so a markdown image would look fine in HTML while staying broken there. Catches  only, not raw img tags. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Leftovers from earlier restructures and from reference pages deleted upstream. Seven were byte-identical duplicates of images still in use elsewhere. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The source is 539x522, so 320x320 described the wrong shape. Omitting it lets the shortcode scale the height from the width instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ajwild
force-pushed
the
image-webp-compression
branch
from
August 21, 2026 08:53
e2c8f2d to
8900ff9
Compare
Contributor
|
🎉 This PR is included in version 1.158.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The docs site serves every screenshot as its original PNG, straight from
content/. That is 78 MB of images, and pages routinely ship a 1.5 MB PNG into a 620px-wide column. Hugo can resize and re-encode these itself, but only for images it can resolve as resources — which means every image has to go through one code path first.So this is mostly plumbing, with the compression as the last step:
public/126 MB → 55 MB.quality: 80with Lanczos resampling, in two variants (800w+1600w, orW+2Wwhen a page setswidth=). The 2× variant is skipped when the source has no headroom for it.sizesencodes the real CSS caps fromarticle.scss: 620px at widescreen, 750px at ultrawide, and ~983px just below the 1024px breakpoint, which is the widest the column ever gets..page__tocisposition: fixedand hidden below widescreen, so a missing table of contents never widens the column.public/at all —cascadesetsbuild.publishResources: false, so a resource publishes only when something calls.RelPermalinkon it.Commits
Each one builds cleanly on its own, so the history is bisectable. That mattered: building them in isolation is how I found that the download shortcode needs the
content→assetsmount, which I had originally put one commit too late.chore(images): render images with the img shortcode{{< img >}}across 21 filesfix(release-notes): host the 2021 release note images in the repouser-images.githubusercontent.comfix(li-document-references): restore the missing UI screenshotfeat(shortcodes): add a download shortcode for file links.patchfiles 404feat(images): serve resized WebP variantsfeat(images): reject markdown images in favour of the img shortcodechore(images): remove orphaned imagesfix(assistants): drop the hardcoded image height320x320on a 539×522 sourcePaths are translated, not copied, in the first commit: a markdown destination resolves relative to the page URL, the shortcode relative to the source file, which is one level shallower for a non-bundle page. So
../images/li-enum-ui.pngbecomesimages/li-enum-ui.png.The markdown-image guard
render-image.htmlnow fails the build instead of rendering:A permissive render hook cannot actually fix a stray markdown image, because every
llms.txtlayout renders through.RenderShortcodes, which expands shortcodes but never runs Goldmark hooks. A hook would make the image look right in HTML while leaving it pointing at an unpublished original inllms.txt— broken with nothing to surface it. Failing at authoring time is the honest option.It caught 4 images my conversion script had missed, in
media-library-setup/index.md.Two limits worth knowing: it only catches
, not raw<img>HTML, which passes through untouched underunsafe: true; and the first offender aborts the build rather than collecting them all.Orphan removal
I used Hugo as the oracle rather than grep: under
publishResources: false, an image that never reachespublic/is unreferenced. Built with--buildDrafts --buildFutureso the 3 draft pages counted, then diffed source images against published output. After deleting all 21, the published file set is byte-for-byte identical — 412 files, 55 MB, same list.Grep alone would have got this wrong. 8 of the 21 have same-named twins that are referenced from other directories (
print-*.png,k-menu-assistants.png,image-editor*.png); I confirmed each twin exists and compared bytes. Seven are identical leftovers from doc moves, and fork-menu-assistants.pngthe referenced copy is the newer screenshot.Alt text
alt="image"is now at zero, and no{{< img >}}is missing analt. I wrote 25 descriptions by opening each image, including the 5 architecture diagrams that had noaltattribute at all.Verification
Full build: 0 warnings, 0 errors. 1017 image URLs resolve against published files, 0 broken; 267
llms.txtreferences, 0 broken; both.patchdownloads publish and resolve.mainfor comparison has 1 broken image and 1 brokenllms.txtreference, both fixed here.Not addressed
prettier --check— all of them already fail onmain. Reformatting them would bury the real diff in whitespace noise.<p><figure>nesting (invalid but harmless) went from 7 to 18 occurrences. It is a pre-existing artefact of the theme'sRenderStringpaths, not something these commits introduce.content/reference/document/metadata/plugins/li-list-reference.mdnow has no screenshot. Its image had been unreferenced since the main-nav restructure, so removing it was right, but the page may want a fresh one.