Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudinary (CDN) support for images #46

Open
arossmann opened this issue Mar 19, 2024 · 13 comments
Open

Cloudinary (CDN) support for images #46

arossmann opened this issue Mar 19, 2024 · 13 comments

Comments

@arossmann
Copy link

Would it be possible to support external CDN (like Cloudinary) for the image storage? this would keep the GitHub repo clean and the page could leverage CDNs.
At least Cloudinary also has a Vue.JS integration: https://cloudinary.com/documentation/vue_integration#landingpage

@hunvreus
Copy link
Member

Yes, I plan on adding support for S3-compatible services (Cloudflare R2, Dropbox Spaces, ...), Cloudinary and others.

However, this requires a backend to do so beyond what's possible with Cloudflare Workers, and as such will likely be part of the "Pro" plan (same as inviting users by email, commenting etc).

@isaachinman
Copy link

I'm also interested in something similar. However, I'd like specifically to host image files within GitHub, but use a CDN layer on top of that to handle things like on-the-fly resize, optimisation, etc.

Cloudinary handles this: https://cloudinary.com/documentation/fetch_remote_images#fetch_url_with_on_the_fly_image_and_video_transformation

Example URL:

https://res.cloudinary.com/demo/image/fetch/h_200,w_200/r_max/f_auto/https://upload.wikimedia.org/wikipedia/commons/1/13/Benedict_Cumberbatch_2011.png

@hunvreus Any thoughts? Obviously I could rewrite/edit URLs in the CMS myself, but first-class support for this would make a huge difference.

@hunvreus
Copy link
Member

Also part of the roadmap to offer image manipulation features (cropping, resizing, blurring, converting formats, changing colors etc).

I was planning on adding Cloudflare Images first, since that's what I use for my own sites, but open to see how that would look like with Cloudfinary as well.

Right now I have a repo where I've started the work on adding S3-compatible services (S3, R2, DO Spaces), but it requires some backend work. I'm doing a PoC with Hono. I think I would likely build on that to add image manipulation for S3-compatible services and Cloudinary.

Thoughts?

@isaachinman
Copy link

@hunvreus With Cloudflare images, were you planning on using CF storage?

In general that also sounds fine to me, but I just want to know exactly what you are trying to monetise out of this project, and what you will leave as FOSS.

In my opinion, a CMS is not really a CMS unless it can at least handle images. And there's no point in a modern CMS handling images unless you have query param manipulation.

In other words, this kind of feature is required just to reach parity with any other basic option.

@hunvreus
Copy link
Member

I'm not sure yet what exactly goes in the Pro plan, but anything that requires sensible amount of backend compute will likely be. I don't think image manipulation would meet that criteria, but I need to look closer at the use case.

Other features like scheduled changes or invite by email are pretty clearly Pro because they do require a fair amount of additional backend work (and a GitHub App separate from the current OAuth login).

I want users to be able to rely on Pages CMS for all their use cases, and Pro to be added convenience for professionals or teams.

@hunvreus
Copy link
Member

By the way @isaachinman , it'd be tremendously helpful if you could either describe me how you think the feature should work (maybe as a simple step-by-step user story), or point me at a CMS that you think does it "right".

@isaachinman
Copy link

OK, understood @hunvreus. The distinction you made between "all use cases" and "added convenience" is reassuring.

I will avoid your question about what CMS does it "right", as I think that's beside the point. To my knowledge, there are no decent version-control-based CMS options, and I think you are building something very promising.

The core problem I see with all major CMS options is that your content is misaligned/unversioned when compared to your source code. If your CMS goes offline, it takes your prod services offline. Moreover, content can break on the fly, builds are not reproducible, conflicts can occur between devs... The list goes on. I am a firm believer that CMS content should live inside your version control.

After interacting with many CMS options over many years, I have presently arrived at a very custom solution of using Prismic, but writing all content to repos via GH actions. The GH actions write content into JSON via the Prismic REST API. I use content webhooks to automatically trigger actions, and open PRs when content changes upstream. Developers only ever interact with local JSON files inside the repo.

How I think an image CDN feature should work for pages-cms:

  1. Image master files should always live within the repo. This seems like the core ethos of a git-based CMS. To do anything else would be a departure from the exact problem pages-cms is solving
  2. Users with the most basic use cases and public repos can opt to serve image content directly out of GitHub, I guess
  3. Most users with a real-world use case will require a CDN. Options are either:
    • Use a service like Cloudinary Fetch. Users would just need to input their base URL, like https://res.cloudinary.com/demo/image/fetch. I'm not sure what the security concerns are here, or how you would/could limit origin access to a specific GitHub repo. Also not sure how you'd handle private repos.
    • Use CF image storage. Assuming there was a cms-content/images directory in every pages-cms repo, maintain an identical directory in CF image storage. Add or remove images in CF based on merged commits. Now we can use CF images in all its glory

I would strongly prefer the CF option. I assume that all you'd need from a user is a CF API key. The "backend compute" requirements, as you call it, would be minimal – just need to upload or remove based on the incoming git diff. You could then write image entries with two fields: repoURI and cdnURI, or something like that.

@hunvreus
Copy link
Member

The core problem I see with all major CMS options is that your content is misaligned/unversioned when compared to your source code. If your CMS goes offline, it takes your prod services offline. Moreover, content can break on the fly, builds are not reproducible, conflicts can occur between devs... The list goes on. I am a firm believer that CMS content should live inside your version control.

There are use case for headless CMS when you're dealing with very large teams and content set, but that's a tiny fraction of the market. And this come at a cost since you're adding another dependency that needs to be integrated in your build/app/website.

I understand why people came to using these solutions. But I think they're misguided into thinking they NEED it, same as GraphQL for example.

Managing content in a repo, especially for website, is actually quite elegant, especially when it comes to staging, testing and releasing. And if you still want to access the content via an API, just use the GitHub API or add a simple serverless function in front of it.

After interacting with many CMS options over many years, I have presently arrived at a very custom solution of using Prismic, but writing all content to repos via GH actions. The GH actions write content into JSON via the Prismic REST API. I use content webhooks to automatically trigger actions, and open PRs when content changes upstream. Developers only ever interact with local JSON files inside the repo.

Interesting. Hopefully Pages CMS helps you remove a lot of that complexity.

I would strongly prefer the CF option. I assume that all you'd need from a user is a CF API key. The "backend compute" requirements, as you call it, would be minimal – just need to upload or remove based on the incoming git diff. You could then write image entries with two fields: repoURI and cdnURI, or something like that.

Right. To keep things secure I will likely need to save all 3rd party storage keys on the server side and send pre-signed URLs to the client when requested by allowed users. Not the most complex piece of software but it needs to be secure. I've already drafted the proof of concept for S3-compatible services, I hope to test it out in the next week with Cloudflare.

Interestingly, I usually do most of my image manipulation directly in the web/app. I don't let users defines what are the rules for optimizing assets or resizing/cropping/modifying images, so this rarely is an issue. But I can see how you may want to edit an image you're inserting in the body of an article for example.

@isaachinman
Copy link

On the fly image manipulation is a must. The proper workflow is to save as high-res a master image as you possibly can, and then manipulate based on placement in your app. For example, you might want thumbnails of a book cover on your landing page – just apply image-url?w=100. Then on a book-specific landing page, serve the full image: image-url?w=2000.

@hunvreus
Copy link
Member

I get that, that's what I do. But the content (what you're managing in the CMS) is usually just the high-res version of the image. I apply transformation in my app/website (e.g. in Hugo/Jekyll/React) depending on where it is in the layout.

Like for example on the landing page of my blog, I would have 120x120 thumbnails from the cover image, and on the full page I would have a much larger format (still cropped to match my layout).

So that's my question; do you manage the image presets in your CMS or do you do that in the website code?

@isaachinman
Copy link

In the website code. The CMS just needs to return a URL which can be manipulated via params.

@phaylali
Copy link

@hunvreus can you also please add support for webp? it's the most optimized for the web, I think it is one of the most needed features

@isaachinman
Copy link

An image CDN would also handle any format concerns. Should be able to reformat on the fly as well 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants