Omit empty srcset on content collection Markdown images - #17872
Conversation
The content layer's image renderer always wrote the srcset attribute, so an image without responsive candidates produced srcset="", which is invalid HTML. The older Markdown pipeline in vite-plugin-markdown only sets the attribute when there are candidates; mirror that here.
🦋 Changeset detectedLatest commit: 3b945b7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 423 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Merging this PR will degrade performance by 14.04%
Performance Changes
Comparing |
|
The CodSpeed regression looks like noise rather than a real effect of this change. The only benchmark that moved is The code this PR touches is inside The change itself is a conditional spread on an array length that replaces an unconditional property assignment, on a path that runs once per Markdown image. The benchmark runs 3 iterations of a full build measured in wall-clock time, so a 1.5s → 1.7s swing on a shared runner is well within run-to-run variance. Happy to re-run the benchmark job if that would help confirm it. |
Fixes #17871
Changes
srcsetattribute, so an image with no responsive candidates producedsrcset="", which is invalid HTML and is flagged by the W3C validator.packages/astro/src/content/runtime.tsnow only adds the attribute whenimage.srcSet.values.length > 0, which is the same guardpackages/astro/src/vite-plugin-markdown/images.tsalready applies. The<Image />component behaves this way too.value === ''branch is left alone, since it is what keeps an emptyaltfrom being dropped.Testing
Added
content collection images omit srcset when there are no candidatestopackages/astro/test/core-image.test.ts. It reuses the existingcore-image-ssgempty-altfixture and the same selector as the neighbouring empty-alttest, so the two assertions cover both directions of the serializer's empty-string handling.Verified against a standalone project on
astro@7.2.9(https://github.com/jx-grxf/astro-markdown-srcset-repro):<img ... src="/api/public/proxy/github.com/_astro/wide...webp" srcset="">, after: nosrcsetimage: { layout: 'constrained' }, after:srcset="/api/public/proxy/github.com/_astro/wide...webp 640w, ... 2000w"— still emitted when there are candidatessrc/pages/legacy.mdwas already rendering without the attribute, before and afterDocs
No docs change. This aligns the content layer output with the documented behaviour of the other image paths; nothing user-facing gains or loses an option.