eleventy-img
eleventy-img copied to clipboard
Image: using statsByDimensionsSync produces invalid HTML
Operating system
macOS Catalina 10.15.7
Eleventy
2.0
Describe the bug
I'm trying to create a syncronous shortcode to generate a banner image. The image is a remote URL (from Sanity) so instead of statsSync
it says to use statsByDimenionsSync
. This results in invalid HTML when using the Image.generateHTML
method:
<picture>
<source type="image/webp" srcset="/img/FnYZGJrra8-[object Object].webp [object Object]w" sizes="(max-width: 0px) 100vw">
<img alt="Surly Wednesday" loading="lazy" decoding="async" fetchpriority="high" class="w-full h-full object-cover" src="/img/FnYZGJrra8-[object Object].jpeg" width="[object Object]" height="NaN">
</picture>
The structure of the metadata
widths is different than produced with statsSync
.
Should we be able to use statsByDimensionsSync
with Image
?
Reproduction steps
- Add a shortcode file containing
const Image = require('@11ty/eleventy-img')
const bannerImageShortcode = (
src,
alt = ''
) => {
if (alt === undefined) {
// You bet we throw an error on missing alt (alt="" works okay)
throw new Error(`Missing \`alt\` on myImage from: ${src}`)
}
const options = {
widths: [700, 1200, 2000],
formats: ['avif', 'jpeg'],
outputDir: './_site/img/',
urlPath: '/img/',
cacheOptions: {
duration: '1d',
},
}
Image(src, options)
let metadata
try {
const isURL = new URL(src)
metadata = Image.statsByDimensionsSync(src, options)
} catch (_) {
metadata = Image.statsSync(src, options)
}
const imageAttributes = {
alt,
sizes: '(max-width: 0px) 100vw',
loading: 'lazy',
decoding: 'async',
fetchPriority: 'high',
class: 'w-full h-full object-cover',
}
console.log(Object.values(metadata).map(formats => formats[0]))
return Image.generateHTML(metadata, imageAttributes)
}
module.exports = bannerImageShortcode
- Add the shortcode to your Eleventy config
const bannerImageShortcode = require('./src/utils/shortcodes/shortcodeBannerImage')
module.exports = function (eleventyConfig) {
...
eleventyConfig.addNunjucksShortcode('bannerImage', bannerImageShortcode)
}
- Use the shortcode in template
{% bannerImage '[some remote image URL], 'Brands' %}
- See the invalid HTML output
Expected behavior
A valid picture
element
Reproduction URL
No response
Screenshots
No response
Sorry to ask a semi-unrelated question here but do you need to use the synchronous method here? The async method is recommended: https://www.11ty.dev/docs/plugins/image/#asynchronous-shortcode