Open minovc3 opened 8 months ago
Hi @minovc3, thank you for the detailed feedback on the adapter, much appreciated!
What version of Ghost are you using? Also, which theme are you using?
Thank you for your patience and quick response 🙏🏻 Alright. Currently, I'm using Ghost version 5.71.2 on Docker. My setup includes the Tuuli theme, here is the documentation.
Below is the snippet of code from this theme that manages the images.
{{#if feature_image}}
<figure class="post-hero__figure m-b-lg">
<img
class="lazyload post-hero__img"
data-srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w,
{{img_url feature_image size="xl"}} 1500w"
srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
data-sizes="auto"
data-src="{{img_url feature_image size="s"}}"
src="{{img_url feature_image size="xs"}}"
alt="{{#if feature_image_alt}}{{feature_image_alt}}{{else}}{{title}}{{/if}}"/>
{{#if feature_image_caption}}
<figcaption>{{feature_image_caption}}</figcaption>
{{/if}}
</figure>
{{/if}}
Now, I believe I've made some progress. Look, I've noticed that If the URL that comes back is an r2 URL instead of a local {SITE_URL}/content/images URL, then unfortunately, responsive images won’t function.
So Here’s my approach:
I modified the GHOST_STORAGE_ADAPTER_R2_DOMAIN from https://cdn.example.com/ to the local {SITE_URL} blog.example.com.
Following that, I set up a redirect rule in Ghost as follows:
302:
^\/content\/images\/(.*)$: https://cdn.example.com/content/images/$1
I'm halfway there now.
All the featured images have been successfully redirected and are functioning, but I've hit a snag with the gallery images – none of them are redirecting.
So, as it stands, the featured images are optimized while using the redirect workaround, but the galleries and images within posts are not being redirected.
Here is an example:
This is a post card image with the R2 adapter:
<figure class="kg-card kg-image-card"><a data-no-swup="" data-fslightbox="" href="https://blog.example.com/content/images/2023/11/test.jpg" aria-label="Click for Lightbox"><img src="https://blog.example.com/content/images/2023/11/test.jpg" class="kg-image" alt="" loading="lazy" width="1500" height="1106"></a></figure>
This is a post card image with the local adapter:
<figure class="kg-card kg-image-card"><a data-no-swup="" data-fslightbox="" href="https://blog.example.com/content/images/2023/11/test.jpg" aria-label="Click for Lightbox"><img src="https://blog.example.com/content/images/2023/11/test.jpg" class="kg-image" alt="" loading="lazy" width="2000" height="1475" srcset="https://blog.example.com/content/images/size/w600/2023/11/test.jpg 600w, https://blog.example.com/content/images/size/w1000/2023/11/test.jpg 1000w, https://blog.example.com/content/images/size/w1600/2023/11/test.jpg 1600w, https://blog.example.com/content/images/size/w2400/2023/11/test.jpg 2400w" sizes="(min-width: 720px) 720px"></a></figure>
The redirect doesn't help on the image-card
Don't really know why!
Done a little digging into this. It seems as @minovc3 pointed out, Ghost will not correctly generate the srcset unless ghost detects the image source as being local.
See this thread on the forums https://forum.ghost.org/t/responsive-images-and-custom-storage-adapters/13183 the current codebase has changed since the thread but the logic still exists.
So in my case, I have changed my R2_DOMAIN from cdn.example.com
to www.example.com
to match the blog and in my cloudflare worker created a trigger route for www.example.com/content/images/
/content/media/
and /content/files
. This effectively accomplishes the same as your redirect but at the edge.
What interests me is that he seems to have used Ghost's transform code to generate the resizes. THAT is much wanted and I am looking to see if I can implement as it seems Ghost is now writing the resized files to a different path:
<img srcset="/content/images/size/w160/format/webp/2024/06/default-feature-image-1.jpg 160w,
/content/images/size/w320/format/webp/2024/06/default-feature-image-1.jpg 320w,
/content/images/size/w600/format/webp/2024/06/default-feature-image-1.jpg 600w,
/content/images/size/w960/format/webp/2024/06/default-feature-image-1.jpg 960w,
/content/images/size/w1200/format/webp/2024/06/default-feature-image-1.jpg 1200w,
/content/images/size/w2000/format/webp/2024/06/default-feature-image-1.jpg 2000w" sizes="320px"
src="/content/images/size/w600/2024/06/default-feature-image-1.jpg" alt="Coming soon" loading="lazy">
Relevant Line Here: https://github.com/TryGhost/Ghost/blob/81b46c53ccc40a3805334fdb4850dc6bff507a33/ghost/core/core/frontend/utils/images.js#L99
So it seems Ghost now is converting the images to optimize for the web! Awesome! Let's see if we can import/integrate their functions and make the backend be really invisible!
Seems the image-transform code has moved but I found it in the TryGhost/SDK repo.
Useful function here unsafeResizeFromBuffer might be an efficient way to generate the resized images that Ghost expects and then send to the s3 client. It can be called with resizeFromBuffer
. It can also transform the file type. So I know we can generate the right images... but I fear the difficult part is going to be getting them generated to the formats Ghost is specifying in the srcset. Somehow, Ghost is able to generate these on the fly so figuring out where/how that happens is my next step. But if that fails, we could just write some logic to convert to all supported formats... but that could make storage costs skyrocket potentially so I'd like to avoid
Just an update, I have a local branch I'm working on that successfully pulls the theme sizes and dynamically resizes and pushes via S3 to the correct paths for all formats (which is also dynamically grabbed from ghost's code). But unfortunately, it seems the image and gallery cards don't respect the theme sizes so I am looking now for where that is defined so that I can incorporate it. Once I have it all working right I'll send a pull request for review.
Hello,
Great adapter! I'm really impressed of the features it has, but at the same time I've got stuck on one of them.
Here's one aspect that I was unable to get functioning or comprehend.
When employing local storage, images set to lazy load typically come from this path example.com/content/images/size/.
However, if you switch to using the cloudflare-r2 storage provider, and enable the RESPONSIVE_IMAGES feature, the images are not delivered from cdn.example.com/content/images/size/ as expected.
Despite this, the URLs for these images still point to cdn.example.com/content/images, which serves up the full-sized images, instead of directing to the specific size path. Without a specific URL prefix for resized images in the configuration, it's not clear how the system differentiates URLs for resized images from the original ones.
On the other hand, at least the images get sized in the R2 bucket
This is the configuration I'm using
Here are two instances showcasing the same image: one using the adapter and the other using local storage.
Perhaps there's something I'm overlooking! I'd appreciate your feedback! Thank you. 🙏