Closed rjdusk closed 3 years ago
Just going to expand on this as I have a working solution, but oh boy is it a doozy! I'm sure there is a much more elegant way to achieving this, but instead on constantly slamming my head against a brick wall, I used the old gray matter to come up with "a solution". Again this is not good, but it works for now until I find something better:
async function imageShortcode(src, cls, alt, sizes = "100vw", widths) {
// Variables used for writing out Cloudinary fetch URL if site is in production
// falls back to local is in dev
const imageLocation =
process.env.CONTEXT === "production"
? "www.madebydusk.com"
: "";
const urlPrefix =
process.env.CONTEXT === "production"
? "res.cloudinary.com/rjdusk/image/fetch/q_auto,f_auto,w_auto,dpr_auto/"
: "";
if (alt === undefined) {
// You bet we throw an error on missing alt (alt="" works okay)
throw new Error(`Missing \`alt\` on responsiveimage from: ${src}`);
}
let metadata = await Image(src, {
widths: widths,
formats: ["jpeg"],
urlPath: "/images/",
outputDir: "./dist/images/",
filenameFormat: function (id, src, width, format, options) {
const extension = path.extname(src);
const name = path.basename(src, extension);
return `${name}-${width}w.${format}`;
},
});
let lowsrc = metadata.jpeg[0];
return process.env.CONTEXT === "production"
? `<img
src="https://${urlPrefix}https://${imageLocation}${lowsrc.url}"
${Object.values(metadata)
.map((imageFormat) => {
return ` srcset="https://${urlPrefix}https://${imageLocation}${imageFormat
.map((entry) => entry.srcset)
.join(`, https://${urlPrefix}https://${imageLocation}`)}" sizes="${sizes}" `;
})
.join("\n")}
width="${lowsrc.width}"
height="${lowsrc.height}"
alt="${alt}"
class="${cls}"
loading="lazy"
decoding="async">`
: `<img
src="${lowsrc.url}"
${Object.values(metadata)
.map((imageFormat) => {
return ` srcset="${imageFormat
.map((entry) => entry.srcset)
.join(", ")}" sizes="${sizes}" `;
})
.join("\n")}
width="${lowsrc.width}"
height="${lowsrc.height}"
alt="${alt}"
class="${cls}"
loading="lazy"
decoding="async">`;
}
I'm publishing this site to Netlify, hence the process.env.CONTEXT === "production"
stuff. You can see this working here - the first B&W image of me. I'm still yet to roll this out to the rest of the site, I want to get this perfect before doing so.
Again any insights on this would be most welcome. I was trying to pair this plugin with Netlify Dev and proxy the requests to Cloudinary through Netlify, but could never get the redirects working in my local development environment - like mentioned here. Save that one for another day.
Sorry for the late response here, you want the urlFormat
option to override with a hosted solution URL: https://github.com/11ty/eleventy-img/blob/956bbd9c90df3d5f96c0e2c30f59aef02264c87a/img.js#L314
Related: #113
This is an automated message to let you know that a helpful response was posted to your issue and for the health of the repository issue tracker the issue will be closed. This is to help alleviate issues hanging open waiting for a response from the original poster.
If the response works to solve your problem—great! But if you’re still having problems, do not let the issue’s closing deter you if you have additional questions! Post another comment and we will reopen the issue. Thanks!
If you’d like an example, you can find one here: https://github.com/11ty/11ty-website/blob/5fa98898403e9df867c7a71a37f48b3291dadfeb/.eleventy.js#L75
@zachleat The urlFormat
option worked great for a use case I had where I needed the image URL only, without the need for generating it once again.
But I have another use case where I'm failing to find a solution: RSS feeds!
See, the images are still hosted locally, there's no 3rd party service taking care of anything.
When I inject an image on a page, it works just fine, with a url something like /static_assets/images…
.
But on an RSS feed, the image URLs need to be absolute, so I would need to do something like:
urlPath: isRSS ? 'https://my-domain-name.com/static_assets/images/' : '/static_assets/images/',
Unfortunately, https://
becomes https:/
, which won't quite work.
Also, in this case, if I use the urlFormat
instead of urlPath
, I find that the images aren't written/transformed at all.
Is there a way to work around this?
As a quick and dirty (and hopefully temporary) workaround:
const imageHTML = Image.generateHTML(metadata, imageAttributes)
return isRSS ? he.escape(imageHTML).replaceAll('https:/domain.com', 'https://domain.com') : imageHTML;
Hiya gang, no doubt this is something with me not correctly escaping something somewhere, but it's driving me around the bend. What I'm trying to do is offload some of the compression work to Cloudinary by frankensteining a CSS Tricks solution with eleventy-img. See below:
From the code above, which has got some debugging code in it, like the URL being split at the double slashes
//
. But this is the problem, in the final image URL it ends up being a single/
vs a double//
. Why are my double//
becoming a single/
? Is something being escaped somewhere in this plugin? Thanks for any insights!