Dive into All Things Digital Media
Explore our podcast programs: DevJams and MX Matters, each with its own take on what it means to build, manage and deliver the modern web.
Image and Video-Rich Digital Signage with Cloudinary and IntuifaceDevelopers-centric projects using Cloudinary in innovative ways.
SUBSCRIBESubscribe to our Podcasts on YouTube
All Things Media Experience and the Trends Shaping Today's Visual Economy.
SUBSCRIBESubscribe to our Podcasts on YouTube
Podcasts
2024-04-01
Image and Video-Rich Digital Signage with Cloudinary and Intuiface
In this episode of Cloudinary DevJams, we host Seb Meunier – Customer Success Manager at Intuiface! He will share how their interactive signage platform uses Cloudinary to deliver images and videos across various projects, thanks to a .NET plugin he developed. Further demonstrating how the platforms interlink, Seb will walk through how their system can use many other well-known platforms. This includes Airtable and OpenAI’s DALL-E for AI image generation, in conjunction with Cloudinary. Seb plans to show these integrations through various operations, such as dictating prompts, uploading images to Cloudinary, and displaying the images on large screens. This episode shows how you can use Cloudinary as a single source of truth for all your digital projects, including signage for shared spaces such as museums and galleries. So, check it out and see how it is possible, thanks to the great work Seb has done for Intuiface!
Sam Brace: [00:00:00] Welcome to DevJams. This is where we talk with developers who are doing interesting, inspiring, innovative things when it comes to images and videos inside of their projects, and many of the times using Cloudinary for that image and video delivery and overall management. My name is Sam Brace, and I’m the Senior Director of Customer Education and Community at Cloudinary.
And in this episode, we’re gonna be talking with Seb who works for Intuiface. And Intuiface is doing amazing things when it comes to being able to have lots of ways to have displays and bring those into places like museums and galleries and just places that you’re walking through to be able to show off lots of different functionality that is gonna help you to better understand the various spaces that you happen to be in.
And interestingly enough, they happen to be utilizing Cloudinary in some of those [00:01:00] projects. So we’re gonna be walking that today with Seb. Joining me for this episode, and also many other episodes of this overall DevJams program is Jen Brissman. She is a technical curriculum engineer here at Cloudinary, and we are always so happy to have her expertise and intelligence inside of these efforts.
So Jen, welcome to the program.
Jen Brissman: Hey Sam, happy to be here.
Sam Brace: Happy to have you here. So tell me why are you particularly excited to talk with Seb and also the overall efforts around Intuit phase today?
Jen Brissman: I’m excited to talk to Seb personally because he’s been working with Cloudinary for I believe, eight years, maybe more at this point.
And I think that’s incredible to have that sort of tenure and to be able to go back and see how it all started back in the day. But I’m also excited because what they’re doing at Intuiface is so cool. Just connecting audiences to physical spaces and I think we need a lot more of that, in these times.
And I’m really excited to hear [00:02:00] more about what he built for these conferences and what they built in Dubai. So really excited to have him on.
Sam Brace: Absolutely, and I think that’s a kind of a neat thing is that Intuiface seems to be doing a lot and there’s, it is one of those areas where when you see things that you know that you’ve worked on, it’s always exciting.
And I think Intuiface seems to be in a lot of places from what I gather. So I think that’ll be something, as you’re pointing out, being able to bring it into spaces, the audiences, and all those different things. It’ll be, interesting to see what we uncover here with Seb today. Before we do get bring our guest on, I do wanna make sure that it’s clear that there have been many episodes that we have done with our overall DevJams efforts, and you can easily find those at cloudinary.com/podcasts as you can see on the screen here, we have it where we have plenty of content that we have been doing, where we’re walking with other developers that have done projects with Cloudinary, [00:03:00] or frankly, just showing off images and videos that they’re working with in really cool ways, and being able to help you understand how you can do many of these same steps in your next projects.
So make sure to check that out at cloudinary.com/podcasts. And similarly, Seb and other community members are inside of our Cloudinary community, so make sure that you are actively going inside of here to continue some of the conversations that we start in this episode. And that’s gonna be at community.cloudinary.com.
Now, one thing that we’re gonna point out in this overall episode as well is that the way that we found Seb, the great work that they’re doing, is inside of this blog post. And you can easily find this at community.intuiface.com, and they have lots of details about this event that they did in Dubai, the COP28 event for their client, Microsoft, a cool client, and there’s lots of different things that they’re able to do for this.
But inside of here, we started to see that Cloudinary is being actively used inside of this overall [00:04:00] post. And this is something that we are very excited to learn more about. So, a nice segue to be able to bring on what we’re gonna have as an amazing guest with Seb. So Seb, welcome to the program.
Seb Meunier: Hello. Hi Sam. Hi Jen. Thanks for having me today. it’s a pleasure for after eight years of working with Cloudinary, finally meet someone at Cloudinary.
Sam Brace: I completely agree. So Seb, tell us a little bit about yourself. obviously we’ve told people your name, Seb, we told you people that you work in Intuitface, but there’s a lot more detail there. So, who are you?
Seb Meunier: Sure. So I’m Seb Meunier, Sebastien Meunier. I’ve been working with Intuitface, formerly known as Intuilab for 17 years. This is actually my first job. The first company I’ve worked for after getting my engineering degree. I’m a computer software engineer, specializing in vision, image, multimedia, so back in the days. [00:05:00] And with Intuiface, we’ll talk more about the company and the platform, I’m sure. But basically I went from being a developer in the product team to helping customers managing projects, and now being the customer success manager, mainly for North and South America. Do not trust the accent.
I am based in the US.
Sam Brace: this is great, and gimme a little bit of context here because I feel like me and Jen have mentioned a few different things about what Intuiface is and what Intuiface does, but obviously we don’t work there, and you probably know it way better than us, especially since you’ve been there for quite a while.
So what is Intuiface?
Seb Meunier: Sure. So first of all, I apologize. This is a DevJam for devs and Interface is a no-code platform. So it is a no-code platform for creative, interactive digital signage, mainly. So basically any kind of signage where you want the users to interact with it, whether it’s a touch screen, it’s a sensor, it’s an RFID, it’s scanning a QR code and controlling [00:06:00] something with your mobile phone.
So any physical places where you want to engage with the visitors. That being said, this platform, you can create any kind of apps for small tablets to large touch screens, to tables, to video walls. We we don’t really care about the form factor. We work on seven different, operating systems and you can find us in a lot of places, and by us I mean the projects being built by our customers.
It can be museums, it can be point of sales, retail, real estate, hospitality, anywhere where you want a screen to not be just a screen playing a video, but be more than that. That’s the gist of it.
Jen Brissman: So how did you get into this line of work? You said this is your first job, but were you always interested in interacting physically with a machine or a screen, or was this something that you learned about for the first time with Intuitface?
Seb Meunier: This is because of Tom Cruise, Minority [00:07:00] Report. 1997, ’98, I think. And I don’t know all of you who remember that movie, but Tom Cruise was basically controlling images with his fingers, having some kind of funky gloves on it with gestures, 3-D gestures. And this was my project in 2005, working with $15 webcams.
Sport gloves with LEDs, 20 cents each, and doing that before iPhone one. Before the Wii. Before Kinect. So 2005, 2006, that was the projects I was working on, and I’ve always wanted to become like a video game developer, something like that. The industry brought me to meet someone from Intuilab in a user experience, user interaction course. I did my internship at IntuiLab before it became Intuiface, and I was hired and that was the beginning of the journey. [00:08:00]
Jen Brissman: Awesome. yeah, I guess the rest is history. I remember the Nintendo Wii and just thinking wow, we’re officially in the future, we can interact with the screen with our gestures and holding the remote.
And now we’ve just come so far and I’m sure there’s so much to come in the future in this space as well.
Seb Meunier: The Apple Vision Pro just was released and now we get ads everywhere about this. So spatial design, I guess, is the next thing. We were just trying to do that 15 years ago.
Jen Brissman: Yeah. Yeah.
Sam Brace: So think So let’s talk. No, go. Go ahead. Go ahead.
Jen Brissman: Yeah, I was just gonna say, so the reason we have you here is because you built something really cool with Intuiface, and we wanna get into that, talk about that a little bit. So could we talk about, at a high level, what you built and then do a bit of a demo?
Seb Meunier: Sure. And I guess this all comes from the use case, and why we’ve been searched for a tool or a platform like Cloudinary. Again, our platform enables people to create interactive applications for public places. [00:09:00] One of the use cases from one of our customers eight years ago was we want to create a cool photo booth where people can take a photo with a webcam and then upload it to the social media.
Facebook, Twitter, for example. And so,, there were a couple of issues. The first being this is a public facing device. I’m not gonna ask somebody to enter his login and password of Facebook on the kiosk itself. That’s not gonna happen. So we needed to find a way to, from the kiosk, use the webcam, take the snapshot, and that we do already upload that image somewhere, so that the user could retrieve that image on his personal phone, personal device where he’s logged in, he has this credential that’s private domain and then he can do the post on his phone.
So, okay, where can we upload an image to? Google… found Cloudinary. Eight years ago. And we probably found a couple of options. It’s [00:10:00] rough, it’s tough to remember what happened eight years ago, but I would say because I’m the one who wrote the integration, I do remember it being super easy, super straightforward, and the documentation being just one of the best.
And the other thing I can say is what I wrote eight years ago still works today and is being used today.
Sam Brace: So it’s stable. That’s pretty cool. Yeah. That’s really cool. And so and that’s what’s neat is like because you had this project, and of course now that you’ve developed this integration where it’s now easy for people to take images that have been uploaded from Cloudinary and get those into Intuiface, as you said, no code.
So it’s easy for them to be able to do drag and drop and move them around and place them in different places of display. They now have their images stored in a single space, but then they can easily manage those and deliver those as needed inside of their Intuiface projects. So that’s…
Seb Meunier: Yes. So, eight years ago,
basically what we were doing was to upload that image from the Intuiface experience, the [00:11:00] snapshot being taken by the webcam, and from Cloudinary, getting back a public URL. Eight years ago, we were sending that to a Facebook kind of thing to make the post. Another use case we’ve had is we’ve been also working a lot with Airtable, as a kind of third party CMS.
And a funny thing about Airtable, and that was true eight years ago, and it is still true today, in their API, you cannot upload a photo. You have to give a public URL to Airtable so that a photo can be added in the Airtable base. So again, we upload to Cloudinary, get the URL, give it to Airtable to store these images.
And that’s a use case we’ve seen more recently. Earlier in 2023, with the, appearance of chat, GPT and DALL-E. And, we talk about generative AI a little bit more today, I believe. A customer for a show event, wanted to have the visitors generate a lot of phone [00:12:00] images, through DALL-E and Chat GPT, and then display an art gallery of all these images.
So we need to store the images and to transfer them from one device to another. Cloudinary, Airtable, same chain, same process, and zero code developed because we already had this plugin road back in the days.
Sam Brace: Incredible, So I think we’ve talked about this plugin a little bit, and obviously eight years ago is, eight years ago.
But let’s take a look at it. Let’s let’s see, like exactly how you were able to get these two systems to be able to connect with each other.
Seb Meunier: Sure.
Sam Brace: So on my screen, I should be showing you a help center document that has been developed for Intuiface, basically breaking down the steps that someone needs to do to be able to upload images to Cloudinary from the Intuiface platform. So yeah, let’s, dive into this.
Seb Meunier: Yeah. So the first thing is on the Intuiface website, we obviously have a support section with more than 500 articles. [00:13:00] If you search for Cloudinary, you will find this one single article. If you go through that, it’ll also have the link to GitHub, and I will jump to that in a minute. All our plugin source code is public, so anytime we develop a plugin, what we call an Interface Asset, we try to make the code public because anybody could build such a plugin.
We did it for Cloudinary because we had the need to, but there are a lot of our Intuiface users that build their own plugins. So now I’m talking to the devs here today. We are a no-code platform, but you can code. And you can create all these plugins, whether it’s in .NET for a player for Windows, or in TypeScript for the player for the other platforms that we have.
So, scrolling down in the page, we also have a link to this Facebook example I was talking about, and that’s the one I will show in Intuiface Composer, our editing tool.
Sam Brace: Okay.
Seb Meunier: I guess, Sam, you’re wanting me to have a look at the code a little bit?
Sam Brace: Yeah, let’s dive into it just so that people can [00:14:00] understand it.
One thing I think I’ll you’ll point out is that the code is actually very clean, simple, understandable. So it’s not like you have to dive into too many, “oh, it’s gonna be hard.” No, there’s a lot of simplicity here, but this is wonderful how you guys did this.
Seb Meunier: Yeah. it is, or at least we, tried to keep it as simple as possible. And, the first thing I would say again is if you want to use Cloudinary within Intuiface, you don’t need to go in that page. This is for those who want to get the code, have a look at it, maybe modify it if they want to. Add more features, maybe, from Cloudinary? But that’s, again, this is more for reference than for usage.
So that code here basically explains how it works. We use the Cloudinary, SDK in .NET. And basically all you need to use Cloudinary in Intuiface are these three pieces of information.: Your Cloud Name, your API Key, and your API Secret from, sorry for the old [00:15:00] screenshot. That’s what we have in GitHub.
Sam Brace: Eight years ago, it’s fine.
Jen Brissman: It’s vintage. Vintage.
Seb Meunier: That was eight years ago. So you need these three values and then in composer, our authoring tool, you enter these three values and you’re good to go. So you can just get the build from this GitHub repository. You don’t have to rebuild it again, today, to be able to use it.
So let me jump into the code so I can show you a little bit how it works, and you will really see it is simple. First thing is we are in C#, .NET in Visual Studio. And to be able to build this integration, we relied on Cloudinary .NET Library. That’s what made it easy eight years ago to build this integration.
We do have a couple of properties and I will explain what it means in, Intuiface lingo, what these properties are and how they are used in the platform. But you will find the Cloud Name, the API [00:16:00] Key and the API Secret I just mentioned. We have a constructor here, which doesn’t do much besides trying to update these credentials.
And we need the three of them be to be able to do something. When we have the three of them, then we create this Cloudinary object. That’s what comes from the.NET library from Cloudinary. So, far one useful line of code. The second thing we have is one action, one method, UploadImage, which uses a file path as a parameter.
Again, we check if the credentials are okay. If they’re not, please verify your credentials. If they are, we check what the path looks like. We do have a little thing that’s really an Intuiface stuff to remove this weird path format. And then we create these upload parameters, if I remember well. This is also an object coming from your library.
There’s one parameter, the file, which is the file path, [00:17:00] and we start an asynchronous task to make sure that we do not block the UI thread, the graphic thread. In this asynchronous method, the only thing we do is called the upload action from the Cloudinary object. So that’s the second useful line in this code.
We create the object from Cloudinary’s library, we call the Upload action. That’s it. The result is what we care about. That is what will contain the URL as the result of that upload. And that’s the one we’ll use to send to Facebook to send to Airtable. So that’s really this URL from the result that matters to us.
That’s it. That’s all the code we have.
Sam Brace: And this is clean because it like what you’re ultimately doing is you’re bringing through original images with no transformations, no optimizations from Cloudinary, but that’s fine for what it is because, this is where you’re doing this for. You’re not putting this stuff on the web, you’re putting this on to high [00:18:00] interactive signage, so you’re trying to make sure that it, is at its highest resolution.
It is in its original state. So it makes sense why when you’re doing this, you’re just basically trying to get what’s the biggest file version that you have in Cloudinary. Suck it in so that way you can work with it at Intuiface, from what I can see.
Seb Meunier: That’s correct. And that’s where we did publish the source code in case somebody else wanted to use more than just 1% of what Cloudinary offers, in terms of features like resizing, image processing, cropping, round edges.
I don’t even remember all the features you have. And it’s almost shameful to say that no, we only just use you to as a cloud storage.
That’s fine, It shows that’s what we did.
Yeah, exactly, This is, and that’s, it makes tons of sense of why, based on what, how your customers would end up using it.
So this is, good. This is really, good. So to, to explain how this is used, what I would like to do now is to [00:19:00] show what, how this upload image action. These three properties, how do we actually use them in interface without writing any code? So I’m gonna switch to Interface Composer, and by the way, this post to Facebook, that’s the sample you can download from our website.
So that’s exactly the same. Maybe just made a few texts a bit bigger for today. That’s it. And so among the interface assets here, if you search for Cloudinary, you will find this Cloudinary Image Uploader. That’s the plugin. That’s the, build of this GitHub repository as a library with we call Interface Assets.
Once you add it to your Intuiface project, you will find three properties on the side: Cloud Name, API Key, API Secret. These are cropped so you cannot use them. So that’s the properties you need to fill in to be able to use this uploader. The next thing is [00:20:00] we will have some buttons at some point in this demo, and the button can call an action.
So all the dynamic aspect of an Intuiface project, what we call an Intuiface experience, is based on properties, triggers, and actions. You don’t write code but you can program things to happen. So when I press and release this upload button, I have my button “Is Released” trigger. And on the action side I have my Cloudinary Intuiface Asset, and I have this one single upload image action, which we defined in the C# code.
It has one single parameter, the file path, the image URI. So that’s what is seen by the Intuiface users without having to know what happens in the C# code behind the scene.
Sam Brace: Incredible.
Seb Meunier: I might just play that demo just to, see live how it works. Yeah. Yeah. so [00:21:00] I’m running on Play for Windows. I’m gonna hit play here. I did not put the webcam on because I’m already using the webcam, so that would become fixed. So just the basic image here. I’m using my touchscreen. I will just show my amazing drawing skills here. All right. Little smiley. Taking a screenshot. So let’s say this is the file on my local drive, which I want to upload to Cloudinary to post on my Facebook account.
Can see here the local file path. That’s what I retrieved from Intuiface. When I call this, I click this upload button. That’s the path I’m giving to Cloudinary. Cloudinary replies pretty quickly with this part here. Res.cloudinary.com, sebmeunier, that’s my account, that’s my image. And what we did in that sample, we added that to a specific Facebook URL.
So now if I grab my phone, as a user in front of a kiosk, remember this is public facing.
Sam Brace: Right.
Seb Meunier: I [00:22:00] can scan this code, and on my phone, trying to show that here…
Sam Brace: There it is.
Seb Meunier: This is my Facebook account and I’m ready to publish this image on my private Facebook account. I didn’t have to give any credentials to the kiosk.
I just retrieved the image on the phone thanks to CloudInnery being the proxy to host that image for us.
Sam Brace: This is cool, and I can see why someone from like a, signage standpoint would really want this. Because, let’s say that you go to see some beautiful landmark and you’re trying to get a picture of your family all together.
You’re like, great, how do I do that? And be able to share that quickly to social media? This is something that is probably a common thing that people want to be able to do is share their images on social media. And then because you’ve been able to link Intuiface of Cloudinary together, you’re able to now point this to different places. That’s, really good. And it definitely answers something that I think a common signage user would wanna do. So [00:23:00] this is awesome.
Seb Meunier: Yeah. So this was really the use case eight years ago. And again, nowadays this module is available and can be used in any ways when you need to upload an image, you have locally on that public facing device, kiosk, table, wall.
And do something with it online.
Jen Brissman: Do you have any moderation concerns or, I, suppose it’s in public. Nobody’s doing anything inappropriate, but, or just say someone were to like, hold up some sort of symbol that you deemed inappropriate. Has that ever been something that you’ve thought of or, have had to combat?
Seb Meunier: Yes. Yes it is. And actually if we talk about the, the second use case, which is more uploading an image to a kind of a collection, which was then displayed on the public facing gallery, then there is this moderation proxy or moderation step in between that can be done depending on where we store that image.[00:24:00]
So in, in another example, we have, once we have uploaded image to Cloudinary, then we upload it to Airtable, to a base, in which we can have something as simple as this. We add a second column, is this validated, yes or no? Then when we upload the image to Airtable, we send an email to the moderators.
They know if they have something new here, and they can just check it in Airtable. And so when we display that list of images, we only display the ones which have been validated. So that’s a pretty common case. And that’s actually one which is being used this week in a new project we are working on with the lobby of a residence.
Jen Brissman: Yeah, I can imagine that if it’s in the lobby, you would wanna make sure that all the images are appropriate. And now, even Cloudinary offers AI capabilities to Moderate, images and videos, any assets that come in. And so I just, I wondered how you were doing that. So you’re doing it through Airtable and so what you send it off to, what is this, Airtable’s moderation, or how long does that all [00:25:00] take?
Seb Meunier: No. That would be more on the end customer, Moderation.
Jen Brissman: Oh, I see.
Seb Meunier: So human, moderation, for now. And again, that’s not how we do it, generally speaking. That’s one example of how it can be done.
Jen Brissman: How you could do it. Cool.
Seb Meunier: Yes. In the end, what is also important to see is that, if there is a rest, API to integrate with the system, you don’t even need to write the code I was showing for Cloudinary. We do have a tool, which is called the API Explorer, which can enable to integrate these web services without having to write any code. We’ve been talking about AI a little bit. I do have an example of a scenario that I could show you if we have five minutes, five to ten minutes.
Sam Brace: We have plenty of time. you, show everything. Absolutely.
Seb Meunier: Alright, so we’re gonna go into a blank project, so you know I’ll really start this from scratch.
Sam Brace: Okay.
Seb Meunier: The, one of the scenarios that we’ve had recently was we want to use AI to [00:26:00] generate some cool images. And to display them in a public gallery.
So to do that, we need a couple of components. The first one will be, we need a prompt to send to the AI, we need something like DALL-E to generate an image. We need to upload the image somewhere — that’s where Cloudinary comes in. And we need something to list these images. That’s where we could use Cloudinary.
We use Airtable, for these examples.
Sam Brace: Okay.
Seb Meunier: So all these modules here, basically are all these plugins of Composer. So if I search for OpenAI, I do have my ChatGPT. I should not need that here today. I’m gonna use Whisper. That’s the speech to text components. So we’re gonna use this one. I will definitely need Cloudinary and for DALL-E… .
DALL-E is one which has a very simple REST-based API. So that’s where we don’t have it off the shelf, at least right now. We will actually [00:27:00] have it next week to make things even simpler for our users. But we do have a, this tool, the API Explorer. So I’m gonna show you how this one works. If I go to the OpenAI reference documentation, this is how you create an image using DALL-E 3, at the moment here. So it’s a simple post, that has an API key in the header, and a couple of properties in the body of that post request. Okay, so let’s say I’m not a developer, I don’t understand what that means. The only thing I need to do is to get the curl sentence and copy that. That’s all I need. I’m gonna go into the API Explorer and in here,
paste this curl. The only thing I will do is I need to add my credential key in [00:28:00] here,or else this is not gonna like it, and hit enter. I believe there’s one parameter I need to modify maybe, but what’s behind the scenes here is our API Explorer, which is an AI-based engine. There’s one parameter wrong here because the documentation is not really up to date, and this is analyzing that curl request, building the host, the endpoint, all the parameters of his header parameters or body parameters, and it is trying to see, okay, that’s what the API from DALL-E is replying. I don’t know if this is JSON or XML, I don’t need to know. This is towards non-developers.
Sam Brace: Right.
Seb Meunier: So this revised prompt, that’s the way this was, as a cute baby sea otter, that was my default prompt. I’m gonna keep that and say this is my DALL-E Create Image component.
And I will have this here in the scene.[00:29:00]
So let’s try to, for now, this is empty because I need to send a request to actually get the result. We did say we want a prompt, so I’m gonna add a text input. So we could either type our prompt using the virtual keyboard, or because we have speech to text, I’m actually just gonna use Whisper to dictate my prompt.
Sam Brace: Okay.
Seb Meunier: So I will add the button here. My button will do two things, and that’s how we use these plugins without writing the code, without having to do the API calls. On Whisper, when I actually, when I press the button, I want to start the recording, and I’m adding a second one. When I release the button, I will stop the recording.
So push to talk, kind of scenario.
Sam Brace: Okay.
Seb Meunier: So Whisper, stop recording and transcribe. These are the [00:30:00] actions. From Whisper, when this is processed by the API, we get a trigger, the transcription has been received, I can use that value, and I will just feed my text input. In case they don’t like my accent, I can fix it.
I’ve done that before and I know that sometimes OpenAI doesn’t like French. So we have our first step here. The next step is to actually create the image.
So again, we’re gonna use a, button to call the second step, DALL-E. We have a credential key, we have a model, we have the size. I don’t want a cute baby sea otter this time. That’s not what I want. I want to use as a prompt the content of my text input.
Sam Brace: Right.
Seb Meunier: [00:31:00] And I’m going fast here because I know you can replay that.
And we have a lot of webinars and videos explaining how this works. This is called a binding to do some kind of data flow, if you will.
Sam Brace: Okay.
Seb Meunier: So we get that image, that image is gonna be created, and it’ll be displayed here. We have the prompt, which is empty at the moment, and the image is gonna be somewhere here.
Our last step. I’m using buttons here, but we could obviously automate that and had some indicators, graphics, that’s why I’m the dev and not the graphic designer. Upload to Cloudinary. That’s the step which matters to us here. When we get that image locally on the device, like the response from DALL-E, I want to call the Cloudinary Image Uploader the this Upload Image action, which we saw earlier. And the file path,
I’m actually gonna grab it from the image asset I have on my scene. [00:32:00]
That’s it.
Sam Brace: Okay.
Seb Meunier: The last thing for the video, for the demo, to explain exactly what’s going on. I will add a second text input here in which I will use the Cloudinary trigger. The image has been uploaded, just to make sure it worked, and we are gonna fill in that text.
Set text with the result coming from our trigger, Image uploaded, that’s actually the URL that you guys are giving us back.
Sam Brace: Okay.
Seb Meunier: So then I can use this URL to post on Facebook, to post to Airtable to whatever I want. Before I hit play. You see these fields are empty, so this is not gonna work. I need to go to my Cloudinary account and copy these values from my account.
That’s what you need to do with your Cloudinary account to make sure that it goes to your cloud and not to mine. So this is what I loved about [00:33:00] Cloudinary. It’s super simple. You have three copy buttons. And the last one is, no, that’s not the one.
Sam Brace: There you go. Yep. Yeah.
Seb Meunier: All right. And I need to do same thing for Whisper. Open AI key.
And I hope I didn’t forget anything. So it’s demo mode. Let see.
Sam Brace: Alright, let’s see.
Seb Meunier: Imagine a joint logo between Intuiface and Cloudinary.
Sounds good.
Sam Brace: It’s pretty good. It knew the words. I like that.
Seb Meunier: Create image. That’s where you want to show something like it’s a spinning wheel, that, because open AI is not the fastest one to apply with an image, but here is the process. Here is the logo.
Sam Brace: Incredible.
Seb Meunier: Okay, why not? And then I can just upload this to Cloudinary.
I get the link and if I open that in the browser, now we have a public image, [00:34:00] which is our new merge logo.
Sam Brace: Incredible.
Seb Meunier: There you go. That was, I think I was in the five minutes, more or less.
Sam Brace: Yeah, absolutely. Absolutely. Walk me through how Airtable is used in this process. Or maybe I misunderstood.
Seb Meunier: Yes, that’s because I didn’t go through that part yet.
Sam Brace: Okay.
Seb Meunier: But it’s a good point. So let’s assume, I want now to upload this image into this particular table.
Sam Brace: Okay.
Seb Meunier: Because I want this list to be displayed maybe on a second screen, maybe on another scene in our experience. So I need two things. I need, one, to be able to display this list of images. Two, to be able to post a new record, a new record here, with the link Cloudinary gives me, gave me back.
Sam Brace: Okay.
Seb Meunier: And that’s where Cloudinary and Airtable for us were good tools to work with because of the quality of the documentation. So if I want to display this list of pictures, I can go into: [00:35:00] Help, API documentation. I. I have my list, my table here, and I want to list the records.
So if I had to write some code, I would need to make that request. That’s the kind of response I would get, and I would need to parse it and process it and pick the fill I want and write some JavaScript to handle that. But we have the API Explorer.
Sam Brace: Ah.
Seb Meunier: So all I need to do here is actually to copy these curl requests, go back into Composer and use again the API Explorer. So let’s bring it in. I’m gonna copy my request. Again, I do need my Airtable API key. I do have it on my second screen here. I
send. If you remember that big piece of JSON that we were getting. This is what an Intuiface user will [00:36:00] see.
Sam Brace: Okay.
Seb Meunier: And sorry for the test pictures.
Sam Brace: Okay. Yeah.
Seb Meunier: I’m gonna just remove the max records because I want more than three recalls, and I can say among these big JSON, I’m only interested into the main photo URL.
That’s all I care about.
Sam Brace: Okay.
Seb Meunier: So I can select that and say, here, this is my uploaded photos from Airtable. Good. Now I can display that list. That’s a previous logo, joint logo, I tried to make earlier.
Sam Brace: Mhmm.
Seb Meunier: And so that’s the list to which we want to add our new picture. I’m gonna put this a little bit smaller here.
There we go.
Lemme just fix this one. I went a bit fast here. Photo URL. We have our images.
Sam Brace: Wonderful.
Seb Meunier: So that’s to display the [00:37:00] list of pictures we have uploaded to Airtable. The step we are missing is to send the Cloudinary URL to Airtable. So going back to our documentation here, we don’t want to list the records. We want to create the records, and we want to create a single record.
That’s what the curl looks like. Again, if you had to do that in JavaScript, a good developer can do it, in a few minutes probably. We just copy and paste this in the API Explorer again and go with the same process. Do you want me to go through that or does that explain the I idea and the process?
Sam Brace: Yeah, absolutely. This is great.
Seb Meunier: Okay. Okay, so let’s go again in the API. Explorer, we’re gonna … I still need my credential key.
So API token goes here. Now [00:38:00] this one here, I believe, yeah, this is the one that can be messed up a little bit because there’s a Boolean and we only send strings. So there is one limitation with the API Explorer.
Sam Brace: Okay.
Seb Meunier: And I need to remove that, so let me just, that’s where sometimes you do need to know what the current request is.
Sam Brace: Yeah.
Seb Meunier: A little bit. And to let’s update it before using it in API Explorer. No, let me go back to here. That’s our request. Okay. we will just remove this one field here. So this one doesn’t bother us. Go back in here. Now it misses the credential key, which I will add here.
Sam Brace: Okay.
Seb Meunier: And [00:39:00] what am I missing?
Photo for the URL should be
good.
Maybe I did not give the right permission on my base for that token. That’s probably what happened because usually I do read-only demos, and now with the new tokens of the table, they have strict permissions. So I guess that’s what’s going on. But you get the idea, you would have the same kind of method. You’ve just passed the URL coming back from Cloudinary here as the parameter, as this field, and that’s it. Then you, it’ll add the image to the Airtable base, and then you can refresh what is being displayed on the wall, and you can keep adding this media with or without the validation step, depending if you want it or not.
With the images generated by [00:40:00] AI, there was no need for validation because OpenAI already generates…
Jen Brissman: Appropriate images.
Seb Meunier: Appropriate stuff… appropriate images, for selfies and photo booth, definitely we would put some moderation steps.
Jen Brissman: Wow.
Sam Brace: I can see where, when you were talking about the project, where you’re talking about we wanna show images, for like a, let’s say like a neighborhood wall for an apartment building or something like that, then it makes sense why you’d wanna see, like a collage or a gallery, like what you’re able to show with this.
And the fact that then they go to this repository, which basically that’s what Airtable acting as, and then you’re able to keep displaying those dynamically through Intuiface. This is slick, but the nice thing that I like about this is that you’ve taken all this work that you’ve done from developing code, working with various APIs, such as Cloudinary’s, but you’ve made this super easy for your users to do. They don’t have to necessarily know a lot about any of the underlying elements that are here other than maybe API [00:41:00] keys, API secrets. It’s all done through just simple actions and buttons. So this is really cool because of that.
Seb Meunier: Yes, we’ve tried to keep everything, whether it’s an image asset or text input, something visual on the scene, or a plugin like these Interface Assets, relying on the same three concepts: properties, triggers, and actions. So even when you add a new plugin, we have this X-ray panel, which shows you the list of all these PTAs, these properties, triggers, and actions. So it’s super easy, to see what’s available in Read-Write or in Read-Only. What are the actions I can call, and what result I’m getting back?
Because when you write some code, when you write a method in C# or in JavaScript, you have a return value or you can have a return value. When you call an action here, you don’t really have a return value. That’s why we need the triggers, which will be events, in common coding [00:42:00] languages.
Jen Brissman: Yeah, I love looking at this composer because, every programmer knows these concepts like an on-click event listener, and a button, and what that all happens, what happens behind the scenes.
But a regular user or maybe someone who shows up to a kiosk or museum, or even somebody who’s building their own, using the plugins and using this composer, they might know what a button does. We all know when click on a button, something happens, but you don’t need to understand what happens behind the scenes because it’s all just in Composer, laid out, this graphical user interface way that, is really, inclusive of, every type of technical level.
But it’s cool if you do know what happens conceptually behind the scenes, because I think then you can dig in the way that we’ve watched you demo, how you can dig in and, remove certain parameters or anything, really customize it more.
Seb Meunier: Yes.
Jen Brissman: But it seems like, would you say, Seb, that your users of this Composer are mostly not technical, or is it really a mix?[00:43:00]
Seb Meunier: 99% percent are non-technical.
Jen Brissman: Wow.
Seb Meunier: I would say, I like to see Compose, and I’m obviously biased because I’ve been using the tool since we created ourselves about 10 years ago, 2012 was the year we released the version one of Composer. I like to see it as Excel or Photoshop. And I’m completely making up these numbers, but 80% of the users of Excel and Photoshop use less than 10% of the features. Probably.
Sam Brace: Yeah, I agree with that.
Seb Meunier: Same thing with Intuiface. We have a lot of users that will not even use Interface Assets. They will just go on a folder, grab a bunch of pictures, lay them out on the scene, hit play. They can build a couple of scenes with a couple of buttons to navigate between these scenes, and put that on the kiosk and that’s in the new museum, which is [00:44:00] way better than a looping video because people can decide what content they want to consume. And that’s probably most of our customers. And most of our projects might be small to medium museums with couple of screens, maybe couple of dozen screens.
Like the MoPOP Museum in Seattle, the Museum of Pop Culture. We have 50+ screens running Intuiface, and I had no idea they were customers until I visited the museum myself. And I kinda recognized the navigation between the objects and… that looks familiar. And I had no idea. And now I know the guy who did that. He doesn’t know how to write a line of code. There you go.
Jen Brissman: There you go. Yeah.
Sam Brace: I think the cool thing that you’ve done as well is like the fact that you are pushing things to Cloudinary so that basically in Intuiface and Cloudinary are being able to work together on a side of things. Because it is in Cloudinary, if someone said, I wanna use that same image on my website or my mobile app, or something that’s gonna be like that, it’s there and it already has a URL [00:45:00] for it. So it’s easy enough for them to then weave it into a content management system or to deliver that to a developer that’s managing the web presence. So it’s all right there in library showing.
Seb Meunier: You’re right. It is. And honestly, right now we’ve been using Airtable as this proxy to list the media files, probably because I didn’t even look at the other APIs you had, because I’m guessing I can query my media library and see, this merge logo, which we just uploaded together.
It’s here. So I can probably list it and get the list and use just Cloudinary without Airtable in here, most likely.
Sam Brace: Yes.
Seb Meunier: But definitely the image is here and, that’s where there are many more things we could probably do. Like all the advanced editing you offer, all these AI-based features that you have, which I don’t even know about, to be honest.
Sam Brace: Exactly. and I think why it’s still cool that you did show the Airtable side of things is because Airtable is a big factor when it comes to a lot of the ways that developers are working. So it is to show that’s a [00:46:00] realistic scenario where you’re trying to use something where you already probably highly invested into it, like Airtable, but now you’re trying to find way to work with the imagery, and you’re like, how do I make this all connect?
So it makes total sense why you showed what you showed. But yes, of course there, there’s ways to, if you wanted to have one vendor , you could just use Cloudinary for some of this only, too. But that’s not for this episode. Your example is excellent. This is good. And I, think that goes back to the point of, you have a single source of truth for now your images and videos is Cloud-based. So that way if I say I wanna use it for my kiosk and my signage, but I wanna use it for other purposes, you have it and it’s all right there. So this is wonderful.
Seb Meunier: Yes, and it’s really useful for us or for our customers when we have a multi-device setup, like…
Sam Brace: Yep.
Seb Meunier: An entrance little tablet and a large, super large video wall 4K, super high resolution on the backend running during the show, during the event. Or when we have this public device versus private device, we [00:47:00] need to make this connection without being able to do anything on the phone because on the phone they don’t have an Intuiface app running. So that’s another thing also, which is, with our latest player technology, Intuiface player– software player, we can build Intuiface experiences using the same composer tool and run them either in venue, on the player, installed locally on the device, or on the web.
And that’s new. We released that in last September. And that opens in a whole new world of possibilities, because now I can build an experience in Composer, publish it on the web, send that URL, put it in a QR code, and have somebody with an iPhone take a picture and upload that picture to Cloudinary.
Scenarios are just starting to explode with that possibility. And to, loop the circle here, the [00:48:00] project you mentioned the Dubai COP28.
Jen Brissman: Yeah.
Seb Meunier: Was not built by us. it was built by Tossolini Productions, who was one of our customers, creative experts, based in Seattle. And they are the ones
who’ve been pushing the edges of Intuiface for years. Probably one of our first customers. And they are experimenting with VR, AR, AI, all these two letters acronyms, and trying to get the videos or photos from an iPhone, using Intuiface on the iPhone, and do things with that. Right now, Paolo, the guy you have the picture on your screen, he’s building a project for Microsoft again, for trade shows. Like wayfinding on a trade show because Microsoft booths are almost a whole size.
And, so they need wayfinding to know which partner is where on the booth. And he’s just building that on the phone using Intuiface as [00:49:00] well, and thinking about, okay, we can take a selfie and send that to the social media team of Microsoft, so we can show it on the wall. Brainstorming about these new scenarios where the mobile and the larger in-venue screens work together even more than before.
Jen Brissman: Wow. That’s exciting..
Sam Brace: Absolutely.
Jen Brissman: Yeah, it seems like there’s a lot being developed for the future, and this is really just the beginning. So thank you so much for coming onto to DevJams, Seb, and sharing all that you shared with us. I hope that people really are inspired by a lot of the demos that you did. I know, I definitely was.
Seb Meunier: Thank you for, thank you again for having me today. Again, I know this is DevJam. I know Intuiface is a no-code platform. I hope you can see that plugins can be developed, especially with this new player, next-gen platform we have on the web with TypeScript, Interface Assets.
So if you have any questions about the platform, definitely you can reach out to me. I believe you’re probably [00:50:00] gonna show about that. Reach out to us. We have a free version on the website, all the good things. We have community where most of our users are sharing what we build with Intuiface.
So that’s the website. We do have a free trial for a month, and you can also share my direct email address for sure. No problem.
Sam Brace: Absolutely. And I think that’s what’s wonderful about this is that you’re showing that this no-code platform you have is very flexible to extend. Like you can basically say I need to maybe hook up to this or that.
And the fact that you’re able to show how you’re able to work with, pretty API centric things. Cloudinary, Airtable, DALL-E, it’s where if you want it to be able to be used by your no-code users, just go ahead and be able to get it to work with your system, and this is pretty incredible how you even make it that easy for them to create digital content. So Seb, great work by you.
Seb Meunier: It’s taken a few years, but…
Jen Brissman: Yeah, no, I, totally agree too because the way [00:51:00] I think of it, Seb, as you were saying, “oh, this is for developers,” but really developers these days are having to do what you’ve done, which is, I think of you as a connector. You know, imagine a puzzle, but instead of only one way that the puzzle goes together, these pieces can connect in all different ways, and it’s up to the user or the developer or whoever to put these pieces together, the ways that they want, and they can use only, 1% of the capabilities that Intuiface offers or that Cloudinary offers or Excel or, everything that we were talking about. I think even as humans, we use only a small percent of our brains. But really we’re, putting together things in, different unique ways. And you are the enabler because you as the developer and the people listening or watching DevJams as the developer, are thinking like, how do I connect these softwares together so that people can use them easier?
And even people being non-technical people. So there’s, so much for very technical people to listen to this type of conversation and glean from it, for sure. [00:52:00]
Seb Meunier: That’s actually the word I was gonna use. Enabler.
Jen Brissman: Yes.
Seb Meunier: That’s one we use a lot because we want to enable our users to use what they don’t know how to use.
Jen Brissman: Yeah.
Seb Meunier: Without having to acquire these skills that they might miss or they don’t have the resources, we don’t have the time to acquire. Another thing which might be interesting, and it’s, that’s right now that’s happening right now is, some of these plugins, these Interface Assets, like the one with Whisper, that I used in the demo. I’m ashamed, but I didn’t write the code for that. GPT did. Because we have an Intuiface coding assistant as our own GPT, which is released now publicly on the store, on the, I don’t know how they call it, on GPT, but if you search Intuiface in ChatGPT Plus, you can find our coding assistant, still a tech preview because it’s still AI, it’s not perfect, but I was able to have 80% of that code written by GPT and just fix [00:53:00] little last thing. So we also save time now even for the developing part of the plugins thanks to AI and that’s definitely going a big change in ’24.
Sam Brace: Incredible. Incredible. and I have a hunch, Seb, this is probably not the last episode that you’ll be on of us.
I have a hunch that there’s gonna be a lot of things that we’re gonna be able to show how developers can be able to develop plugins, extensions, be able to use your platform, our platform, and other ways to be able to make it easy for all users to be able to do great things with digital content. So, Seb, keep it up. This is great stuff.
Seb Meunier: Yeah. I agree. And, I think we’ve used 10% of Intuiface to use less than 1% of Cloudinary, so there’s room for improvement.
Sam Brace: Always. Always. Thank you again for coming. I appreciate it. Absolutely. So Jen, what’s your big takeaway here? What’s the thing that stood out to you most from what Seb was able to show us and talk to us about today?
Jen Brissman: A big takeaway for me [00:54:00] is that Seb and what he’s built within Intuiface really uses Cloudinary in a small way. However, he’s been able to scale that and continue with what they made eight years ago now.
And I think there’s sort of … Like when I first was using Cloudinary, I was really just using Cloudinary to extract the URL as well. And when I learned all the Cloudinary was capable of, I was almost a little embarrassed, like, “oh man, I really, maybe I missed the point altogether” but that’s not true. You really just need to use given softwares in the ways that they work for you. You just need to get what you’re trying to do to work. And that’s it. You don’t need to use 100% of what every technology offers. And I think that’s sort of a shift in mindset, at least for me. And to hear that Seb is using this at this huge company that’s doing amazing things and it’s okay that he’s not using optimizations or, other things that we know exist at Cloudinary.
And, I think, that’s a cool thing to realize. And anyone listening, if you wanna use Cloudinary in a really simple way, that’s awesome. Do it. Go for it. And you [00:55:00] can probably even use it for free too, because Cloudinary does offer free tiers as well when you’re not using it in so many ways.
Sam Brace: Yeah. You wanna use the tool for what you’re trying to intend it to be used for. If it is for a simple task, then use it simply. And if it needs to be advanced and complex, then use it more complexly and it, and I think that’s exactly what I’m seeing here, is that this, there’s lots of different varying levels as we show on this program, of how to work with images and videos.
And this was meant to accomplish a specific goal that was set out for Intuiface’s customer base. So this is great and I love the fact that it is simple because a lot of the factors of how to do this with your own platforms or with your own types of integration work, Seb was able to demonstrate that very clearly in this episode. So that’s wonderful too. And of course, if you are interested in taking a look at all of this, as we mentioned, intuiface.com, is where [00:56:00] you can check out all the great work that Seb and the team are doing over there. And also, one thing that I’m gonna be doing personally is, every time I walk into a museum and see a kiosk, I’m gonna be like, “hmm…I wonder if Intuiface was behind that now.”
And also notice that the repository that they had for the image uploader that he walked us through, that’s gonna be at his own GitHub. So that’s gonna be github.com/intuiface/cloudinary for a very simple URL. And of course, we’ll have all of the links listed in comments and show notes on all the things that we referenced today, such as the blog posts that guided us to Seb, and also the help article on how to work with the uploaders that they’ve gone ahead and built, too.
Lastly, before we dive away from this, remember we have all of the DevJams episodes everywhere that you typically listen to podcasts, or watch podcasts that includes Spotify, Apple Podcasts, Google Podcasts. It also includes YouTube. It also includes our own training academy, the Cloudinary Academy. So wherever you wanna check [00:57:00] out this content, we’re probably there.
But of course, the main repository for all of this is cloudinary.com/podcasts. So you can hear from guests like Seb and many other amazing developers that are pushing the boundaries of what images and videos can do. And also remember, you can continue those conversations with any of those amazing guests, as well as the millions of developers that are using Cloudinary at community.cloudinary.com.
Now, with that said, any final thoughts, Jen, before we let our guests go on with their day?
Jen Brissman: Final thoughts would be, it just seems like AI is making our lives easier. Everything from using ChatGPT to help Seb write some code, to even moderation. He was mentioning that they have a manual moderation, and I was just thinking, “oh, forever Cloudinary has offered AI moderation” and they can just send that out and, immediately get a moderated response and just code in any parameters they want and, use multiple plugins we have. And I was just thinking, it’s [00:58:00] 2024 now, when we were thinking like, wow, the, Wii was so futuristic. Now we’re here in 2024 and we’re talking about these futuristic things and I’m just excited for even five, ten years from now the things that are gonna be coming out. Really cool conversation with Seb. I hope we see him again too in the future. And, really great episode.
Sam Brace: I agree. I agree. So on behalf of all of Cloudinary, me and Jen, thank you for being part of this episode and also, be sure to check us out again when we’re back because we’ll bring forward another amazing developer who is pushing the boundaries of what’s possible with images and videos inside of their own projects.
So thank you. Take care, and we’ll see you at the next one.
2024-03-25
Syncing Local Folders to Cloudinary for Automated Cloud Storage
Cloudinary regularly hosts internal hackathons! These allow employees to stretch the boundaries of what’s possible with our products. Hadar Bejerano, the head of the Solutions Engineering team, created one of the winning projects. With CloudyDesktop, users can sync a local folder to Cloudinary for automated uploads! Find out how he developed this desktop application in this DevJams episode. You’ll learn more about ways to use Cloudinary’s CLI in your projects. Hadar also shows how to use some of the project’s tools and packages – Electron, Keytar and Chokidar. If you’re trying to find a way to automate your team’s uploading processes, this is an episode you won’t want to miss!
Sam Brace: [00:00:00] Welcome to DevJams this is where we talk with developers who are doing exciting, interesting, innovative, inspiring things with images and videos inside of their development projects. And because this is a program developed by those at Cloudinary, it probably means that they’re using Cloudinary in some form or fashion with that image and video management or delivery.
My name is Sam Brace and I am the Senior Director of Customer Education and Community here at Cloudinary. And I am so excited for you to be part of this episode where we are bringing on Hadar, who is leading our overall solutions engineering team here at Cloudinary. And he’s been here at least as long as I’ve been here.
And I’ve been here for quite a while now, but he’s developed an amazing project called Cloudy Desktop . And what this is doing is allowing for you to [00:01:00] sync a local folder that you have on your desktop, whatever you have for your local storage. And then link that to a folder in your Cloudinary account. Now, that’s pretty simple, but it’s also something that is going to show you a lot of different ways to start thinking about the extensibility of the APIs and Cloudinary’s own command line interface.
So that way you can start developing your own projects for ease of management, uploading, and organization of your overall files. Joining me for this episode when we are going to be talking with our friend Hadar, as she is for many episodes, is Jen Brissman, who is a Technical Curriculum Engineer here at Cloudinary and a member of the Customer Education team.
So Jen, it is great to have you here for this episode.
Jen Brissman: Hey, happy to be here.
Sam Brace: So why are you excited to talk to Hadar today?
Jen Brissman: A few reasons, but the main one being I’m really excited that this project was developed at a hackathon. And it’s really cool when something developed for not a [00:02:00] necessary reason becomes this awesome tool that people can get such a great use of, so I’m hoping this inspires some people today.
Sam Brace: Absolutely. And it’s a really good teaser into some of the things that we are going to be talking about here today. And of course, Cloudinary’s hackathon culture is something that we haven’t dived in too deeply into in any DevJams episode, but I am very excited for me and you to do that today with Hadar.
So great point about this overall episode, and hopefully it percolated some ideas for people to be thinking about as we get into that portion of the episode. Before we do bring on Mr. Hadar, I do have to of course, point out that everything that we will be discussing in Hadar’s project is going to be located at cloudinary.com/labs. That is where our projects, some of them have been inspired by hackathons, that have happened within the company. They’re going to be found here. So this is a way for you to extend the overall capabilities of what Cloudinary has done, where we’ve had developers like Hadar that have done that.
They’ve really outreached and found ways for Cloudinary to do very [00:03:00] interesting things, including ways to have, as you can see, in painting interface to remove certain objects from overall content, ways to easily inspect your media. Even some of the things that we are really pushing when it comes to our Media Library and Chrome extensions for that.
Lots of things that happen to be here. So definitely take the chance to review cloudinary.com/labs for all details about Hadar’s project, including others that have been part of our Cloudinary Labs effort. Also inside of the Cloudinary Labs section, you’ll see that all of the code for Hadar’s project, Cloudy Desktop happens to be there and that’s in an open repository on GitHub.
So make sure if you want to download it, check it out, extend it, do what you want to do to be able to play with it and get it to work for your needs and use cases or just general inspiration. It happens to all be there for you to fork, download, clone, whatever your heart desires . On top of all of this, Make sure you are checking out all the podcast episodes, not just this one, [00:04:00] on cloudinary.com/podcasts. Of course, we also happen to be probably wherever you like to listen or watch podcasts at, whether that happens to be Spotify or Apple Podcasts, Google Podcasts, YouTube, even our own training Cloudinary Academy. And keep these conversations going, of course, in our Cloudinary community.
That’s going to be community.cloudinary.com. And that includes the forums that happen to be there, as well as an associated Discord server, for overall conversations that happen in these episodes, or anything that happens to do with Cloudinary, or general tech that you’re working on in your stack. Lots of good things to remember.
With that said, I think we’ve done enough promotion for the stuff that we do, Jen. Let’s bring out our friend Hadar here. Hadar, welcome to the program.
Hadar Bejerano: Hello, how are you?
Sam Brace: Good, we’re good. We’re so excited to be talking with you today. It’s not just a case where we’ve developed this amazing project, but you do a lot of really innovative things.
Being the person [00:05:00] that oversees the engineering efforts of the Solution Engineering team, and the operations that are associated to that, you’re definitely tied to a lot of really cool, “let’s get people excited about what they’re possibly able to do with images and videos” when you’re talking to lots of different types of audiences, whether those are customers, prospects…
We do a lot of that work, Hadar. So tell us a little bit about that. What does that mean for someone that leads the SE efforts at overall Cloudinary?
Hadar Bejerano: Yeah, so first of all, great to be in this podcast. Amazing team to join. As you said, I’ve been in Cloudinary for more than seven years now. And I lead the solution engineering team, which is the pre sales team in Cloudinary.
Now, Cloudinary is both a platform that is used by developers and, but it’s also a very visual platform, right? You upload a lot of visual media into it, images and videos. And us, as the solution [00:06:00] engineers, as the pre sales of the platform, what we do is talk to this audience that wants to use Cloudinary and show how they can use Cloudinary on their projects.
And because it’s such a visual platform, it’s really easy just to share your screen, show how it can be done. And there are a lot of APIs that allows easy integration, but also a lot of really amazing features that just look so great. So anytime you get the chance to demo the platform, people are wowed and it’s really a great experience to be part of that.
Sam Brace: Absolutely. And I completely agree with everything that you said. Highly visual, highly engaging platform that we have here, of course. And hopefully this doesn’t turn into too much of an advertisement for ourselves. But it is where some of the things that led to the creation of this Cloudy Desktop project that we’re going to be talking about today.
Was there any experiences you had from being in SE, leading the SE team that said to you, this is [00:07:00] something that more customers could use or it could be used in projects?
Hadar Bejerano: Yeah. So I think because SEs talk to prospects all the time, we get a first hand look into what interests our potential customers and users of the platform, what’s top of mind for them, what is an important requirement for them.
And being a cloud based platform means that you have this ongoing requirement of taking the work that you’re doing locally, on your computer and sync it up to the cloud. In the same way that we hear other many requirements as well, right? So there’s so many use cases that Cloudinary supports.
But this one looked really interesting to me because it included that technical challenge of also doing something locally and natively on your desktop. While most of the [00:08:00] work that is done in Cloudinary is web oriented and web based. So trying to merge these two worlds together with having this real requirement from the field was the reason to try and take this project on.
Sam Brace: Wonderful. Wonderful. And so looking at something like Cloudy Desktop from a very high level, just break this down for us. What exactly are we doing here? Because as I mentioned, there’s going to be syncing between a local folder and a Cloudinary folder.
So it means that you’re taking something from local storage to cloud storage, if I understand this correctly. And then also that means that you’re using aspects of our Command Line Interface (CLI) to do so. So what gaps am I missing here in this like basic rundown of what this is?
Hadar Bejerano: So I think the main point is that you don’t want to do this manually, right?
You have all these files and it’s up to you now to make sure that you have the latest updated in your Cloudinary [00:09:00] account, which is on the cloud. And it would be great just to, to have that automated. Because Cloudinary is really open to integrations and APIs, there are so many times that the Cloudinary is the backend behind automation of many mundane processes that you do around media management.
In this case, it’s just syncing the work that you do up into Cloudinary. That’s one of the challenges. The other challenge is also the fact that, in this case the project is actually multi platform. So the code that we will review can be compiled to both a Mac and a Windows application. So you actually get an XF file and you actually get an app file and you run it from a local and from the same code So that another challenge as well so you can support all [00:10:00] different users that use different types of desktops .
Sam Brace: I think that’s one thing that’s actually very unique about this episode that we’re going to be doing here today is that I don’t think we’ve ever had any project that we talked about, it had to have a Mac version and a Windows version.
So that alone is very intriguing in itself to be able to talk about here today, Hadar.
So this is very cool. And to your point, I can see why it would make things a lot easier if there was just regularly syncing between something locally so that way, whatever is in your Cloudinary storage, it is what happens to be within that folder.
So you can just keep adding to it as needed and just automatically brings everything through so that you have it for cloud storage. And then of course all the amazing transformations that Cloudinary provides with optimization, aesthetics, etc. So this is wonderful. Is there any big points that we’re missing here before we start diving into the project?
Hadar Bejerano: No – before going into the technicalities of this, just pointing what you mentioned earlier, but all of this started from a hackathon, right? [00:11:00] Cloudinary… Because it has this API based platform and it serves developers, it’s part of all sorts of hackathons, right? So we have customers running their own hackathons where they use one of the groups might use Cloudinary to try and do a cool project of their own.
We have global audiences that can be part of Cloudinary Hackathons that sometimes are open to everyone that uses Cloudinary and can join one of our Hackathons. And the third type, which is a very common one, are Hackathons that we run inside the company. Once or twice a year, and everyone is really excited, you get to team up with people that you don’t know from other departments. You can, people list ideas before the day, of things that they want to work on and you can just join the team and also this project started with a team. I was not alone working on this. Once people like the idea and join you, then [00:12:00] you have that 24 hours where you need to run and code everything in a day or sometimes less.
So that’s pretty cool as well and a great, I think, culture in Cloudinary to keep doing this and get an interesting project out of it.
Jen Brissman: So how much of the project that we’ll be talking about today was built within that 24 hours, and then how much was, you know, kind of trickled over time to improve it?
Hadar Bejerano: That’s a really good question. So one of the secrets of doing a good hackathon is actually to get some time added from all sorts of areas.
I would say that one of the things that I would recommend people that are in process of going into a hackathon to do is try to have an idea in mind and also try to have a working environment in mind. Just like even if you didn’t write a single line of code for that specific project, but [00:13:00] if you have already the framework that you’re going to use already up and running in your computer, already compiling, you can already get something basic to work, then you are, you might be saving like six hours of trying to have that done under the pressure of the hackathon day.
So I guess we did a bit of that but most of the code was, and you’ll see in a second when we’ll go over it, we tried to reuse existing libraries. So we don’t need to write a lot of code. Eventually we try to use frameworks that are powerful. So using all of this actually made it possible to write most of the project within the hackathon timeline.
Jen Brissman: Wow. Okay, cool. Let’s get into it. Let’s see what you guys built.
Hadar Bejerano: Actually what I’m showing you right now is just, if you want to learn more about Cloudinary [00:14:00] hackathons, these are just blog posts that we put out to talk about hackathons that have been done. So the latest hackathon that was done was even around a different area, which is Generative AI.
So you can read all about it there. You mentioned Cloudinary Labs already. This project is inside the Cloudinary Labs. And if we go into Cloudinary Labs and inside Extensibility, then you have the link to go into the GitHub and and see the code of Cloudy Desktop. Now, before, actually going into the code, I’ll just show you how it actually works so you can see it in action, and then we can go and dive into that- all the details. So for that, I’ll move into the Cloudinary console. But just to mention one more thing before. [00:15:00] As I said, in order to try and just write the code that we need for the project, we tried using existing libraries and existing components that can power this project so you don’t need to write everything from scratch.
One of a very powerful tool that is part of the Cloudinary formal, released to customers, components is the Cloudinary CLI module, which means it’s a Command Line based Interface (CLI) interface that you can use to invoke and to run all sorts of commands. You don’t have to write code there. You can just run it from the shell.
So it’s very powerful for IT people. It’s also very powerful in this case because we are using it under the hood. So again, just to also mention that as one of the components that powers the platform and then Thank you. We’ll jump into the demo.[00:16:00]
Sam Brace: I agree. With the CLI, by the way… like it’s one of those things where the more that I’ve seen people using Cloudinary, it’s where many cases our SDKs are very powerful, but it also sometimes takes a second to write scripts for it, to be able to get it all up and going. The fact that you can do quick commands with the CLI the way that you’ve been able to knock this out is something that’s truly fantastic.
So a big shout out to everybody that worked on the CLI development because not only is it helping the power of the Cloudy Desktop, but man, what a cool tool. Our CLI is pretty awesome.
Hadar Bejerano: Yeah. And do check it out because it has actually higher level functionality than the APIs. So the APIs are the basis of everything.
And the CLI actually implemented some even higher level function . So let’s go into the actual demo of Cloudy Desktop. So what I’m doing right now is I’m showing you the Cloudinary Media Library. Hopefully you’ve used Cloudinary already and you are familiar [00:17:00] with that. And as you can see, as a graphic designer, I just created these five amazing work of art. I don’t know where I got the inspiration for, I’m about to do the next one, right? So then to do the next in line, which I guess you, you can know what it would be. And that would be the number six in the dice. What? What I want is instead of me going back and forth, uploading and updating Cloudinary, I want all of this to be done automated. So let’s look into a Cloudy Desktop. As I said, Cloudy Desktop is an app. So you can see I have an icon. It’s an app. It looks like a standard Mac app. I’ll run it. And it opens rather small because the UI here is not intended for ongoing use.
You just need to [00:18:00] configure it once, and once it’s configured, you leave it as is. You can here put the parameters of your API, so of the Cloudinary API. So it’s a Cloud Name, the API Key, and the API Secret. And we’ll talk later on the developer part of how you do this really in a secure way. And next, you need to configure two folders.
One folder would be the local folder on your local machine, which you want to sync to Cloudinary. And so this is where I select a folder here. And you can see that I can open the dialogue to do this. Or I can second, I need to select it if I did it. And second is I have the Cloudinary path to the Cloudinary folder inside Cloudinary. And Cloudy [00:19:00] Desktop will always save files into a folder under Cloudy Desktop folder so we don’t by accident overwrite some folder we didn’t anticipate would be there. So I created a folder called also local dir inside the Cloudy Desktop folder. So if I now go back into my view of the console, then here I have my folder here, so let’s run Cloudy Desktop, and once I run it, it will start working automatically for me.
So I’m running it now, and you can see that it says Sync On, and now, I cannot change the folders anymore, because if I want to change, I need to stop it first. And it will now start to listening in on changes that I’m doing on the local folder. Okay, so [00:20:00] far?
Jen Brissman: Yep.
Sam Brace: Makes sense.
Hadar Bejerano: So let’s go back to our local dir, and let’s put this aside for a second.
And now I’ve done my amazing work and I’m ready to publish my dice number six, and I’m putting it here in my local folder. So just putting it there. What happens in the background is that Cloudinary is running. So it detects that this is happening, and let’s refresh and see if this was actually updated. Yes!
Sam Brace: It was. That’s great.
Hadar Bejerano: And easy to see that number six is now there. Now that was a really basic kind of a thing, right? Just another file, but it’s not limited to that. I [00:21:00] can also drag. So I have a folder here. A folder that includes other folder and other images. So maybe I’m dragging all of this also here.
So again, it will detect that, automatically update it, going back to Cloudinary again. Let’s see where we are. Let’s refresh the screen. And yeah, we have another directory here. And in that directory, we have our file that were there. And that other file as well. So everything is updated and I haven’t needed to go back and forth doing it manually.
Sam Brace: Very cool.
Jen Brissman: Thanks for doing that demo. Cause you know, really it, it, if the picture speaks a thousand words, a demo speaks a million words. Cause we see exactly how this works and it’s so clean and really people don’t want to do anything manually and this isn’t new, but [00:22:00] this is just a great tool for anyone who does do a lot of either migrating or just uploading to Cloudinary for them to just do it in a single drag and drop of a folder.
And for people who are a little maybe not as technical or would rather work in a CLI or like the idea of not having to use code to do these things, someone who’s a DAM administrator could absolutely do this no problem at all. Or someone technical who just wants to do a drag and drop and doesn’t feel like writing code that day.
Sam Brace: All right. Yeah so, Jen – I’m sure we were all – we have all the same question. How did you build it?
Jen Brissman: How’d you do it? Let’s see under the hood.
Hadar Bejerano: Amazing. So – great question. And I apparently by coincidence, I have all the code here. So, a gain, as we, we already said the same code that we are going to review now is actually being able to be compiled to both Mac and Windows.
So you’re… [00:23:00] so if I have a colleague that wants to do the same thing, using Windows, you can do this as well. So all of this magic starts with a really cool framework – a JavaScript framework called Electron. And when I was thinking about this hackathon, really, I was looking to try and use the code that I use in my day to day. And Cloudinary’s day to day is usually around web development.
So what we use, the CSS, HTML, JavaScript, all of these development technologies that are not part of native desktop development, right? Usually, if you want to write a Windows app, I would now need to open a .NET application or an Xcode application Mac and write in different languages that, that maybe I haven’t used for a while and all of that.
It’s really [00:24:00] amazing to find Electron as a really stable and useful framework that just gives you the option to reuse the code that you have with JavaScript, with HTML, with CSS, with all of that. But as it says here, but still build the cross platform desktop application. And and it’s not only me doing this, right?
You can see that this tool is already have built some applications that I’m sure all of you know. Visual Studio Code is built with Electron and Slack is built with Electron and many other examples that you see here that you might be using already like Postman and so on.
And by the way, if you have… now that you’ve seen this list, if you compare how the web interface of those application looks to the native interface, you would see they are very [00:25:00] similar. And this is because it wasn’t redeveloped. It really was ported using Electron to be a desktop app.
Sam Brace: This is very cool. And enlightening, frankly. It’s like you’re pulling back the curtain on a lot of this overall development. We’re like, hey, did you know it’s done with Electron? So this by itself is interesting.
Hadar Bejerano: Yeah. And then, and you write UI, you write desktop UI with CSS and HTML, and you’re like “what, how is this going on?”
But yeah, all the praise goes to Electron, which is a platform by OpenJS really cool tool to use. And next is so let’s look into the, into, no, let’s go up and also look into the code for a second. So I just wanted to explain a bit what Electron is. What Electron actually does is open [00:26:00] a Chromium window.
So it’s a Chromium, let’s say, engine window. And this is why it can run HTML and CSS and JavaScript understand what it means. It’s like opening a browser window within the desktop, let’s say, environment, and it holds the best of two worlds. One is the frontend world, which is CSS, HTML, JavaScript and the other side is also the Node.js.
So you can also do all the stuff that you do with backend code can be done with Electron as well. So you have the powers of both these infrastructures.
Sam Brace: Very nice.
Hadar Bejerano: Next is to understand a bit the architecture of Electron. So just again going here in this article to another diagram that they created.
So Electron in [00:27:00] basics works like you have one main process and then that process will go and generate let’s say windows. And each window that it created, it’s called the render process, and it will have its own HTML that actually defines how the window looks. So in the application, we will see the Cloudy Desktop, it has only one renderer. But you will see that we will start with talking about the main process, which is the main application, and then going into talking about how we create the renderer process and actually build the UI for the application.
Sam Brace: Got it.
Hadar Bejerano: We understand so far, or we are good?
Cool. I want to show you this image because it was so funny for me. I was starting to write this code. I [00:28:00] went across a blog post just saying how to write Electron correctly. And they had this image that stuck in my head like they were saying “just don’t write the code in this way because it has this Size of a security vulnerability in it” And I was like, “Okay. Okay. I’m not going to do anything that looks like this.”
What is this vulnerability he talks about and I think It’s already disabled in latest Electron versions, but just to be aware, they have… they want the communication between the renderer and the main process to be done in a certain way that that is secure.
So former Electron version was open to really just sending messages as much as you want. And you could even see code samples that you would just send message all the time between two processes. The right way to do things is actually to try and keep each side independent as [00:29:00] you can.
So you run the main. It does what it does, and you run the renderer, it does what it does, and you try for them not to keep talking to each other. If there is some functionality that needs to be there, just move it to the right process. And there are some functionalities that only the main can do. For example, only the main can open the dialogue that you’ve seen me opening of the finder of the folder of the of the local desktop, right?
Because there are some functionalities that are restricted from a browser window. And then there is a function that you can do that in a secure way – we will go over it. But just remember, have the track in mind and remember, write the main process and the renderer as independent as possible. And if they do need to communicate, then there is a way, it’s called an Invoke API, where you can actually call a function from renderer that will run on the main.[00:30:00]
Sam Brace: Got it. You’re helping with a lot of concepts here.
Hadar Bejerano: Amazing. So let’s go into the code. So because this is built on JavaScript and because it starts from kind of Node.js infrastructure. Then this starts from the well known package. json file. So that’s a Node.js configuration file. And in essence, the one thing that is important here right now is just to say, “okay, where do I start?”
So you start here. Your main component that we just talked about, the main process, is written in main.js. Okay, it’s easy to keep the same name. You can write any name that you want. But so we now know where, when we go and review the code, we know where to start looking. We want to go first to main.js, which will be the JavaScript that will tell us how exactly the main [00:31:00] process. Now that we are inside main.js, we can see that it’s Node.js, Node.js code. What I’m doing is going to require the Electron npm package, and I’m going to ask for specific modules that I’m going to use throughout this code, but you’ll see eventually it’s pretty short code and electron really gives me the models that can do what I need.
Next thing that I’m doing here is that I, because we are writing code that eventually will be compiled to do different desktop environment, Windows and Mac, there are some points in the code that you want to do differently. For example, just a basic thing. If I go to a Mac application and I close it, it doesn’t really close, right?
Sam Brace: Right.
Hadar Bejerano: It goes down into the dock. And now [00:32:00] here in the dock, I have a quit option. And in windows, if you close it, it’s really closes. So you have these different nuances on how the app should behave and you will, and we will go over it. We will, you will see that you write code that controls it, but just for me to have these variables that are easy to use, I’m just checking “is it Mac or is it Windows?” And I’ll use this Boolean to tell me. Or I could just check, because part of what Electron gives to me is this process.platform variable that tells me which platform it is. Next, I’m jumping a bit forward to just show you the main thing here.
Main would next would be that you, you seen that I took a model from electron that is called app and app is my main app thing. [00:33:00] And what I want to do with app is actually to add a listener here for when it’s ready to start, and when it’s ready to start, it needs to run the function that I define here.
In this case, I’m defining a function called startApp. So this is actually the first thing that’s going to happen is that the operating system will tell the application “you’re ready” and then the application will go “okay, I need to run startApp”. And then what startApp does is the first thing that he does is createWindow and what createWindow does is creating that browser window. Okay. It’ll create that window, which will actually will be that render process that we talked about. So it’ll have an HTML file that defines how it looks, because this main component doesn’t have a UI, it just runs in the background as a server in the background, that, that spawns [00:34:00] the windows.
And now it’s going to generate a window. I define the sizes. I can define if it’s resizable or not. In my case, I did very basic CSS and HTML. So I didn’t want it to be resizable. But you can write it in a way that you know, like you build a proper responsive website, you can write it in a way that it will be resizable.
And also some, some functionality here to define if I’m using or not, and at the end of the day, it just defined this, that I’m going to have this size of a window that I cannot resize in my case. And we’ll see in a second also that it loads this file. Which will be my HTML file that will define exactly how this window looks.
So as you could see, my main code created the [00:35:00] main process that can create one window or more in my case one, by calling the browser window and defining which HTML it will run and what would be decided.
Sam Brace: Incredible. Incredible. And the great thing about what you’re doing here, Hadar, in my opinion, is that it’s not only where we’re walking through how you built this project that’s going to be using Cloudinary, but this is an amazing primer for anybody that’s doing any Electron app in general.
So it’s this is, you’re getting two awesome tutorials in one with this episode here. So far, so good. Excellent work, Hadar.
Hadar Bejerano: Amazing. Thank you. Another cool thing about Electron and the fact that this is actually a browser run window. Is the fact that if you are using Chrome, right? And you want to check stuff in your Chrome application you can open DevTools, and you can start debug [00:36:00] your website.
Sam Brace: This is the part that blew me away. When I first saw Cloudy Desktop, when you saw, you could actually pop open DevTools inside of this. This is, that’s cool.
Hadar Bejerano: Yeah, so the reason I can do it is exactly this code here. I can decide to disable it, right? If I now go to to Slack or to Visual Studio Code, a production version, I won’t be able to open the DevTools because probably it’s disabled.
And so they probably have “devTools: false” on the code. But here you can see it’s remarked. And therefore I can go and open the DevTools in the same way that you would open DevTools on your Chrome. And I can go between the different elements and I can see all the messages that were sent to me throughout the sync process, right?
So we learned the sync before. So all of this was a print to console. And I could debug this if I had any [00:37:00] issues, if there were any problems with the sync, or I can look back into the element in the HTML and see if it’s, if I have any UI, CSS issues, I want to, and if I’m doing any network, all of that is available to me. So again, as someone who is used to work with their web environment, you get all the tools that you’re used to.
Sam Brace: What a wonderful way to make sure you are able to troubleshoot. I think the example you had, Jen, about Let’s say that as a DAM administrator, you want to get this on everybody’s computers. It’s going to be putting things into the DAM, make sure you’re syncing to the right folders. Let’s say that somebody’s saying it’s not syncing or something like that. You can go immediately and troubleshoot for them inside of this. So this is great that they have this backward looking capability where you don’t always have to say, this may not be a issue that’s inside of the JavaScript.
It might be because of something that’s tied to their desktop itself. I think this is great.
Jen Brissman: And because the width [00:38:00] and height are specified as 750 and 620, if you were to try to resize this window right now to show the DevTools bigger, it wouldn’t work, right? Because it’s not responsive?
Hadar Bejerano: Yeah. Yeah. So I would, let’s say, I would run it resizable too if I need it to be with bigger DevTools. So I don’t need to do everything in my, in that 750 size, yeah.
Jen Brissman: Okay, cool. Good to know.
Hadar Bejerano: Cool. So you think what I’m actually doing in the main is mainly just defining the window, defining the file that it’s going to run. And then again, as I mentioned earlier, I will do stuff that is around getting all the events on the windows and handling them a bit differently between a Mac and Windows. So here, for example, if I get a close event, I’m actually not going to close it but just going to resize it. But if it’s Windows, it will go and [00:39:00] resize.
So other than handling these events on the windows and running the browser window, that’s pretty much what what the main application does. So let’s jump and go into the index file. So let’s see what the browser does. So here again, I just have a, I just have a HTML that defines exactly what we just seen…this UI.
And there is also a CSS file. So again, above here, there is include to a CSS file and there is also a JavaScript file. So here I have a CSS file and here at the bottom I have a JavaScript file that will run the actual functionality. So let’s jump into index.js, which would be the JavaScript file that would actually run the functionality here.
So I’m going [00:40:00] into renderer and inside there is index.js. Here what I want to do is to do the functionalities that we’ve seen in the demo. First, what I want to do is I want to be able to read the parameters of the Cloudinary account, right? In order to be able to communicate and to upload files to Cloudinary and to have full access and full control. I have here the Cloud Name, the API Key and the API Secret. So I want to, I don’t want to retype them again and again each time I’m opening this app. I want it to be stored and when I open it to read it from somewhere. So I’m actually each time this is being updated and save is clicked, it saves to two different stores of variables. One is let’s say a regular store of information [00:41:00] for Electron and the other one is the secure one for the password. So you can see that I’m defining here a store that will use a library called the Electron store. And then I’m for the secure one, I’ll use a specific library for passwords called keytar.
So let’s look at the store at first. So you can see that I just doing get of all the information that I need. So if it was already there, already saved, I just get it. Where do I get it from? Let’s see how this Electron store looks like. Let’s just find it here. I have it here.
Jen Brissman: So many tabs.
Hadar Bejerano: Yes. Ah, Electron store. Okay. So Electron store shared the source as you can see here in the README. [00:42:00] It allows you to read and write data, so it will be persistent. The data is saved in a JSON file, and this is why I’m not saving the password there. Just saving the other data that is open. And it’s also can work in Electron in both Windows and Mac.
So make it super easy for me. And you can see I have the code example here. I either set or I get. That’s it. It makes my life easier. So all the parameters that I have here, the Cloud Name, the API Key, the API Secret, not the API Secret, the local path, the Cloud Name path, all the parameters that I need locally here, apart from the API secret, I just use Electron store, get and set, and I’m done.
If I don’t have anything, then this would be open and empty. If I do have something, I’m reading it as I’m coming up.
Next, I want to [00:43:00] do the secret. So again, it can be a very complicated job to store variables locally in a secure manner, right? So the API secret in Cloudinary should be stored securely. Actually some of the functionality sometimes you can do in Cloudinary, you don’t need to use the secret at all. So you can also upload to an outside preset that we have options to do it.
But in this case, we gave full control for the app. So we just need to store the secret securely. So how do we do this? Again, luckily, there is an existing library that does this work for you and open in NPM called the keytar. You can see a lot of downloads, which usually gives a good indication that you are on to a reliable source.
And what [00:44:00] keytar does is, as it says here, it uses, in macOS, it uses the keychain, and in Windows, it uses the credential vault. These are just two repositories that are managed by the operating systems. They are there for that exact reason. You can store data in a secured way. So if I’m just, coming into this desktop, not as the application, but just looking for the data to find it because I have a virus and it search for stuff on my folders, stuff like that, you won’t find it.
All right. So the data is secured. The app can retrieve it. You don’t, you won’t find it in a JSON file like the other files.
Sam Brace: This is excellent. Absolutely. And it’s something that I know me and Jen preach constantly in courses is like, “When you’re doing anything that’s server side with our API secrets, you got to put it in an ENV file, or you got to make sure that it’s not exposed in client side code”.
So once again, security: [00:45:00] vitally important to working with anything in Cloudinary, and I’m glad that you addressed it in this project.
Hadar Bejerano: And the number one thing you don’t want to do with this secret is to put it in GitHub.
Sam Brace: That’s right.
Jen Brissman: Don’t check that in.
Hadar Bejerano: It’s there for, it’s hard to get down. So yes.
Sam Brace: The general rule of once you put something out on the Internet, it’s very hard to remove it from the Internet.
That includes your API Secret. So yes, very good point, Hadar..
Hadar Bejerano: Even if you delete it afterwards, it’s in the history. So we’ve seen that what the renderer does is it reads all the variables. And then the other thing that it does actually it would go and use these variables in order to run the sync itself. But luckily, I don’t even need to implement the sync myself because you’ve seen Cloudinary CLI.
We mentioned that. So Cloudinary CLI already have a function that [00:46:00] will run and sync, but the only point is that it will do it one time. So what I need to do is I need to do two actions. I need first to listen in to any changes in the folder. And once I have noticed that there is a change in the folder, I can run CLI to update the entire folder to Cloudinary,. So how do I listen into changes in the folder? Luckily, again, there is another library that I can use, which is called chokidar. So going back to NPM, going back to chokidar again, we have increased the number of downloads by, so this is 44 million downloads.
So again, you can see it’s a really good and used by many to do exactly that. It can go and watch all types of events that folder has [00:47:00] so we can know about everything. If a file is added, deleted, folder added, file was updated, all of these events. You get as events in the code so you can listen to those that you want to respond to and do something about it.
So here what I actually do is exactly that. I just build a watcher that is based on that library and I’m just listening to all these different events that I want to be aware of ,that I want to go and perform a sync because they happened. Each one of these events will actually go and make me do the same thing: run the CLI so that it will sync between the local path and the Cloudinary path.
Jen Brissman: So once you’ve started up the app, is it always going to be listening because of chokidar? If for any changes, it’s watching, it’s listening, how often does this update? And do you need to close it down completely for it to stop listening [00:48:00] for changes?
Hadar Bejerano: Great question. So you can see that here I have the status defined. So right now it says Sync On. So it means that it is listening and any change that I will do will be detected and updated. When we started when we just initiated it, it wasn’t on yet. So you need to click it once to run it. There is also this amazing rotating arrows, if you can see it, that shows that it is in action.
And, but if I want to, if I want to stop sync, I have here, inside the dock menu, I have a stop sync option, and you can see that it stopped, and now it’s waiting for me to, and now it also allows me to change the folder again. So the folders were disabled, and once I stopped syncing, I can change the folder if I need, and I can click sync.
Jen Brissman: And is it immediate? Just say you make a change like you demoed before. Is it every [00:49:00] second, every five seconds? Okay.
Hadar Bejerano: Ah, so once I run, once the sync is on, then any change that I do will trigger the event here immediately.
Jen Brissman: Yes. Okay.
Hadar Bejerano: So it doesn’t wait for every hour, every two hours. It is constantly immediate update on this.
Jen Brissman: Yeah, cool.
Sam Brace: I like that. And what’s cool about that to me is that it acts very much as that single source of truth concept where whatever is in your Cloudinary DAM, whatever’s in your Cloudinary account, whatever is in your product environment, whatever we’re going to be classifying this Cloudinary storage aspect as, it’s where whatever you need to be in it is there at all times.
So I think to our original point, if you install this on some multiple computers, the people that are working on Cloudinary environments. They always know that whatever is the latest, the greatest, the most important things, they’re in that area. There’s no waiting period where you have to suddenly [00:50:00] say “well, at the top of the hour, it’s going to be correct.”
Yeah it’s what’s there, is what’s there. So I like the fact that you make this listening and actionable at all times.
Hadar Bejerano: And now, as you saw, every event drives the same function, which we saw is runCliSync. And that is running the Cloudinary CLI. So I’m spawning. Once it’s installed, and you’ll see that in the packaging, I’m actually installing it.
But once it’s installed, then in the terminal, you call it as CLD. And there is a sync function. Part of the CLI, this is what I mentioned that it has a higher level of functionality than our regular API, because it has a sync option. But it just runs once, and again, as I said, we are listening to events and then running it.
That would be the trigger for it. I have all sorts of options here that are command line based, that I’m just building the right function that I want to want to run. So I want to be pushing form local [00:51:00] to Cloudinary. I want to make sure that it’s getting updated. And I want, keep-unique means that even if I delete files locally, I won’t delete them from Cloudinary.
So I’m just keeping there. Maybe you delete it by accident. I’m just keeping the stuff but this is, can be changed. But this is the option that for this project we use.
And again, this CLI function just from the command line can be run by any, anyone that installed the CLI, go to the command line and build this and run it if you want to do it manually. Cool. So yeah, in essence, this is the app. Usually, this is where it ends. But here, because it is a desktop app, you now go into the amazing world of redistribution. You now need to take this code and actually make it into an executable [00:52:00] file that can be used by both Mac and Windows. In the old days, I could, FTP use a file today you can’t do it anymore. The operating system is protecting itself, so one way, let’s say the best way, would be to go and take this into the process of registering this app in the store.
So the Windows store would have Cloudy Desktop and the Mac store would have Cloudy Desktop, this won’t happen in 24 hours in the hackathon. They also haven’t happened in this case. I did do some of the work after the hackathon of packaging, which will go over but haven’t got to the level of putting it on the store. So actually in Mac, there is one level before that, where you can build a package that you can [00:53:00] redistribute by yourself and sign it so that the operating system is allowing you to run it as well .
Sam Brace: Right – and which it makes sense because you don’t want to be having put in malicious material into anybody’s computers.
And obviously, it’s in the best interest of these OS creators, Microsoft, Apple, to make sure that they’re not allowing for easy pathways for that to happen. So it makes sense and I agree with the steps to take to make sure that your application is able to be used by all.
Hadar Bejerano: Cool. So to see that, to learn a bit about that, we go back to our package.json configuration file. So far we just talked about main.js.
Sam Brace: Yep.
Hadar Bejerano: Now you can see these bunch of scripts, that will actually help me to go and build a file that I can redistribute so that you can now download from GitHub, install it. And you still would need to tell [00:54:00] your Mac operating system to allow third party applications because by default it only allows from the store, but once you tell the yes on that, it’ll let you install. And you also know that is that it was checked and found okay. So what you need to do is get the app both signed and notarized.
So let’s explain what signed means, and what notarized means. Signed means that you are a developer that have an account with, the Mac developer, and that you’re registered and they know who you are and you got a certificate from them. And you need to pay for that, an annual fee, but Cloudinary has that certificate.
So I’m using the Cloudinary certificate. Any developer can just register and get certified based on their process. So you get a certification. So you know who [00:55:00] you are. So this is getting the code signed, which means you put your name on to that code, so if there are issues, they know to track it down. They know who you are. What notarized means is that it’s actually you take the app, you don’t go to the full process of submitting it to the store, but there is a shorter process of they just you send the app to the Mac servers, to the Apple servers, and they will do a short review, just making sure you don’t have malware.
So signing means I’m putting my name on it, I’m certifying it with my certification. Notarizing means that I have sent it to Apple, they checked that there is no malware on it, and approved it.
Sam Brace: I like it. This seems to be, “trust, but verify” the way that I’m looking at this is “yeah, we trust you. You’re Hadar.” You’re saying that, obviously you put your work into this, but we got to still check, you make sure. So I like this code [00:56:00] plus notarization aspect to it. So this is good.
Hadar Bejerano: Yeah. And as it mentioned there, if you are going to eventually send it to the store, then you have a process to be approved in the store and then you don’t need it to be notarized because they will do additional checks there. But not our case. So we are going to do both signing and notarizing. Going back to our code, and let’s do signing first. As I mentioned, I need to have a certificate. So I need to go to Apple Developers Community, sign up, get a certificate, pay them the annual fee. Cloudinary, luckily did this already. So I’m using their certificate and I’m using a tool called package build that will actually create a .pkg [00:57:00] file. A file for installation on Mac because my file right now is a .app. It’s an app. In Windows, it would be a .XF. But I want to create a file for installation.
So this tool will create a .pkg file. Now there is another way to do this. There is also a tool called the Electron forge that actually do all the work for you. I haven’t used that tool, so I won’t go into the detail of that. Just be aware, you can also use Electron Forge. I’m using the lower level tools of the operating system of, so package build is in Mac.
The other one is product build. What is the difference between these two? What package build will do is create a, as we said, a .pkg file, and sign it with your certification. What product build will do, which you run after the package build is it adds additional [00:58:00] resources on top of it.
Because first, your installation package can have more than one package, if you have several components. So a product is built of several packages. And second, a product also includes additional resources. For example, the message that you show to the people starting to install, and we’ll see it in a second.
So there is an HTML file with that message. The message that you say at the end of these definitions. So you can see here that I have a file called the product.dist that if we go into that, actually define messages. If I go into build, then you can see that there is a file called welcome at the start, and a file called conclusion at the end, of this file will be shown at the start and at the end of the installation.
And I [00:59:00] just see an example of installation. So I have here the package. So if I double click in the package, you can see it starts the installation. Let’s see if I can. This one is also you cannot reset. It starts the process, and it will say, this will install Cloudy Desktop on your computer. So this actually text comes from the welcome HTML.
And when I continue and end up with whatever it needs, and at the end it will show me the summary.
Let’s run very quickly. So we created that package saw, and we built. So it was two step, we built it to something that you can run. You still need to authorize it. So there is this tool from Xcode that runs an authorization, and you tell the, you tell it where the package is.
It actually takes time. So you run the command. It takes time for it to give you back a response. So you just sign it on the terminal and you wait. [01:00:00] It submits this file to Apple. It’s getting files all the time. So in I, I think in an hour you get a response back. “Yeah we reviewed it, we didn’t find any malware.”
You get back the file with the authorization on it, and you’re done. And now you have the .pkg file like I just showed you. Any one of you can now go into GitHub and going to release us here and find it. So you can download it and install, or you can also, as is explained in the in the README, or you can just get all the code as it is, and compile it yourself. So this is also explained On the readme so you either get the pkg and install it or you get the code and compile it.
Sam Brace: Incredible. From top to bottom. This is great work, [01:01:00] Hadar. Very great work. And like we were saying now we have very comprehensive view of some ways to streamline work that you have with Cloudinary, but also ways to be able to say, if I need to create some form of a desktop application and do this with basic HTML, CSS, JavaScript, how can I possibly pull this off? You’re doing that with Electron. You’ve shown a lot of different opportunities here.
So this is excellent review. Is there any best practices, anything that you said, if I didn’t do this step, it would have gone poorly, or if you were to do Cloudy Desktop again as a second iteration, would there be anything that you would have done differently?
Hadar Bejerano: I think the point… that kind of helped is, as I mentioned earlier , just to get something basic working first.
So I had, I used the code samples that Electron gives that are very useful. It just had some, basic window open. And then as I [01:02:00] was reading about it, I came across that blog that said, “Oh, don’t do this, do that”. But it’s actually, I think the main decision that was important here is just using Electron, right?
If I would go through any other framework to try and write it, which are native desktop options, I probably would have taken a lot more time. So I guess choosing the right framework and the right libraries is key. No, I wouldn’t build it right now differently, but but there was a lot of thought was go into that before we actually started the hackathon itself.
Sam Brace: Makes sense, . So Hadar, we’ve covered a lot here today. And obviously, there’s going to be a situation where someone’s going to take your work and try to do something with it. They’re going to install it, just run it as is, or they’re going to try to do something [01:03:00] with the repository that you have here.
Where can people go for more questions? I see that obviously you’re on GitHub here as one of the contributors. Is that the best spot? Is there ever places where you can be, you’re actively reached by your listening and watching population?
Hadar Bejerano: Yeah, so I was joking around with Jen earlier saying they can send a fax to me, but probably that’s that’s not useful anymore.
Just kidding. Yeah I’m available on LinkedIn. And happy for people to connect and to join and to start a discussion. It would be great if people will actually try this. Any questions that they have either on Cloudinary in general, or Cloudy Desktop, or what I can answer on Electron, I’ll be happy to, for people to, to connect and to continue the discussion.
Sam Brace: Wonderful. Hadar, this has been fantastic. Thank you for coming on the program and being a part of this. We can’t wait to see what else you’re doing. I know that as we pointed out at the very beginning of the program, you’re [01:04:00] working with some of the best and brightest at Cloudinary and our solutions engineering team.
So it can’t be just where you’re the only one making great stuff. There’s probably things that your team is making on the daily. So keep us updated on all the happenings within your team. And hopefully we can have you guys come back for another DevJams episode.
Hadar Bejerano: Amazing. The team is doing much better work.
So for sure you should see what they are doing. But yeah, it was great joining you and thank you for having me.
Sam Brace: Absolutely. Thank you, Hadar.
Jen Brissman: Thanks for coming.
Sam Brace: So what I want to ask is, Jen, what’s your big takeaway here? What’s the thing that stood out to you about Hadar’s awesome work here with Cloudy Desktop?
Jen Brissman: So aside from his demo, which was really thorough, we really left no stone unturned and anyone can watch and really learn some things. He even mentioned, “Oh, we didn’t use Electron Forge, but you could”. So he really has a lot of helpful nuggets within his demo. But I think the biggest takeaway for me is the Cloudinary CLI.
It’s fully supported by [01:05:00] Cloudinary. I didn’t even know that there’s a higher level of functionality with the Cloudinary CLI than our SDKs. I don’t know exactly what that meant, but it just makes me wonder about the CLI and really want to get my hands dirty and work with it more. And – no code.
There are so many attractive factors about the Cloudinary CLI. And so I think this is our first real project that we featured that is working with the CLI in a big way. Am I missing anything, Sam, there? Or is this really…
Sam Brace: Oh no. Yeah. This is probably one of the first major ones that we have on a DevJams episodes, for sure.
Jen Brissman: Yeah. So I think my biggest takeaway is just, wow the Cloudinary CLI is powerful and should not be overlooked and is available and fully supported. That’s a big takeaway. And then I guess the other thing that we did touch on throughout the episode is: hackathons. And a lot can be created in a short amount of time, and I think it’s awesome that Cloudinary has this hackathon culture that is exciting here that we do internally, especially, but also as Hadar was mentioning, [01:06:00] there are other forms of hackathons that we do. It’s just, it’s cool that this was built at a hackathon and now it’s featured on Cloudinary Labs. So that’s another
takeaway for me.
Sam Brace: What an amazing segue to be able to talk about Cloudinary Labs, because that is where all of these projects that have come up from labs have come up in some form of a hackathon that Cloudinary has supported of its employees. So definitely go and check out exactly what Jen has mentioned all of the projects that have been the best and brightest of those hackathons over at cloudinary.com/labs. And also, I’ll completely reiterate what you just said. Our CLI is crazy powerful. Crazy powerful. It’s where if you’re a developer and you’re saying, okay, I’m using one of their SDKs, let’s say Python in this case, because their CLI is a Python based application. And then we have the CLI.
Now you’re able to do very quick situations where you can easily just run things command line. You have your full forged [01:07:00] SDK, but then you can also do things like what Hadar has done and really empower your entire team to have streamlined uploads and management of all the files that they need to be able to deliver with Cloudinary.
So there’s a lot of connectivity here with all of the things and all the different types of personas that really care about digital asset management. Whether it’s going to be images, videos, things that you’re going to put on your website, your mobile app, whatever it happens to be. There’s a lot of streamline here that Hadar created, which I’m very happy to show off.
The other big thing, of course, as we’ve said a few cases, make sure you are checking out that GitHub repo that Hadar has gone and put out there. You can see here that project, as well as all of the lab projects that we talked about. It’s just going to be a github.com/cloudinary-labs, and you can see all of those happen to be there inside of that overall space.
On top of all of this, make sure that you are checking out all of the podcast episodes because me and Jen have been [01:08:00] producing these things for quite a while. You can find all of the episodes, of course, listed at cloudinary.com/podcasts. On top of that, you can always find all of our podcast episodes, wherever you probably like listening and watching podcasts.
So that’s Apple podcasts, Google podcasts, Spotify, YouTube, and also our Cloudinary Academy, which is where you’ll find many training resources and courses also happen to house all of our podcasts as well. And of course we have to mention our amazing and vastly growing Cloudinary community. So if you are wanting to be part of these conversations, let people know about the great work that you’re doing, maybe asking questions of Cloudinary employees and staff and users about some of the projects that you hear about here on DevJams. You can always do so at cloudinary.community. — Wait, community.cloudinary.com. I will get that. And of course we have an associated Discord server, which you can always find linked inside of that space.
So – [01:09:00] Jen, any final thoughts before we let our audience go and have a wonderful day?
Jen Brissman: Yeah, I was just thinking, get this going, you’ve watched this whole episode. You’ve gotten to this point, get Cloudy Desktop going for yourself because, using Cloudinary CLI to automatically sync a local folder into the cloud and into a Cloudinary folder, that’s a very common use case. I know as a Cloudinary employee myself and with the work that I do at Cloudinary, I’m always making uploads to Cloudinary and I’m thinking just throughout this episode, why haven’t I gotten Cloudy Desktop going? I think that’s what I’m doing as soon as we finish this episode.
So if you’re watching, if you’ve gotten to this point, if you’ve watched Hadar’s awesome demo throughout this episode, get it going for yourself and let us know what you think.
Sam Brace: I love it. I love it. I like the call to action. Good job. Yeah.
Jen Brissman: Listen, you’ve gotta.
Sam Brace: So on behalf of everybody here at Cloudinary, including myself, Jen and Hadar, thank you for being a part of this DevJams episode, and we can’t wait to show [01:10:00] you what else developers are doing when they’re pushing the boundaries of image and video delivery, management in their own projects, hopefully with Cloudinary as part of it. Take care, and we’ll hope to see you at the next episode.
2024-01-29
Adding Images to Tableau Data Visualizations with Cloudinary
Tableau is one of the widely used data visualization and business intelligence tools! And adding dynamic images to charts and graphs is even easier, thanks to Cloudinary’s transformations. Timothy Ngwena, lead consultant for Aimpoint Digital, created an eloquent solution with the two tools. In this DevJams episode, he walks through the steps he took for adding images in Tableau. You’ll see how he breaks apart the Cloudinary image URLs to create a consistent output. On top of this, you’ll learn how to dynamically resize and shape images with Cloudinary’s transformations. So, join Cloudinary’s Customer Education team and Tableau Tim for this deep dive! You’ll be using your Cloudinary images for business intelligence purposes in no time.
Sam Brace: [00:00:00] Welcome to DevJams. This is where we talk with developers who are doing interesting, exciting, intriguing things when it comes to working with images and videos in their projects, and because this is a program that is developed by Cloudinary, probably a lot of that image management, video management, delivery, is probably done by Cloudinary too.
My name is Sam Brace. I am the Senior Director of Customer Education and Community at Cloudinary. And in this episode, we’re taking a little bit of a unique spin on this. If you are a regular listener and watcher of the program, you know that we typically are talking with developers that are going to be showing off code and scripts many times for websites, especially for optimization purposes or unique ways of delivering their [00:01:00] content through our upload APIs or Admin APIs, who a lot of times are talking about frontend frameworks. We’re talking about all sorts of interesting things, but there’s a certain flavor of developer that we’re talking to.
Today, it’s a little bit different because we’re gonna be talking with somebody named Tableau Tim. And if his name tells you anything, this is an episode about how to use Cloudinary with a very powerful, very well used business intelligence software named Tableau. And it’s not something that we commonly talk a lot about here at Cloudinary.
Since it’s not the main use case that we have for this, but what I love about this overall episode is that Tim is going to be showing us how to stretch the boundaries of what Cloudinary is able to do and be able to use it for business intelligence purposes, particularly when you’re having to add images into data visualization, into overall business intelligence data points that you’re going to be having inside of Tableau and how to handle that with dynamic resizing, which is very cool. [00:02:00] Joining me for this episode, as with all episodes is Jen Brissman, who is a Technical Curriculum Engineer here at Cloudinary. And I am so happy to have her here to help us guide this conversation with Tableau Tim.
Jen, welcome to the program.
Jen Brissman: Hey, nice to be here.
Sam Brace: So tell me, why are you excited to talk with Mr. Tableau Tim?
Jen Brissman: Mr. Tableau Tim, the Tableau Tim. I’m very excited to talk with him today for a few reasons. Personally, I’m really into data and databases and the power of what you can do with data to assist with business growth and development. But also it makes a lot of sense that we’d be talking about Tableau with Cloudinary because Tableau is focused on visual analysis. It would make sense that images are getting pulled into this? And I’m excited to dive into that a little bit more in today’s episode.
Sam Brace: Me too. And you said it very well, Jen. I completely agree with everything in this case. And what we want to make sure of before we dive into this is if this is your first time coming to us. Please know that, of course, we’re going to have show notes. We’re going to have links to all the places that we [00:03:00] reference the material that Tableau Tim, myself, and Jen are going to be talking about, but also know that you can always check it out at tableautim.com and you’re going to be able to see that he has lots of material, lots of links to all of the content he’s creating, that’s teaching people that are in the business intelligence and data visualization space, how to better use Tableau. On top of all of this, of course, this is not the first episode that we’ve done of DevJams.
In fact, this is one we’ve done for many years now at Cloudinary, so you can always check out all of the previous episodes at cloudinary.com/podcasts, or wherever you like to watch or listen to podcasts, such as YouTube, Spotify, Apple Podcasts, Google Podcasts, and our own training Cloudinary Academy.
On top of all of this, please know that you can continue a lot of these conversations in our Cloudinary community. That’s going to be at community.cloudinary.com, and you can see that there are forums where people can be able to post all of the questions and answers and findings they have about working with Cloudinary, and we also do have a [00:04:00] associated Discord channel, Discord server with many channels to be able to give you all the information that you need to be the best Cloudinary user and be the best developer that you possibly can be, especially when it comes to images and videos.
Without further ado, let’s bring on our friend Tim. Tim, welcome to the program.
Tim Ngwena: Hey. Thanks for having me.
Sam Brace: Tableau Tim. It’s an amazing name. I love alliteration myself. Talk to me about how did this come about? What sparked the interest in Tableau? What started the overall push to start educating people on this business intelligence software?
Tim Ngwena: It’s a great question.
As with most answers in this space it’s typically never intentional. So I started working in marketing analytics, essentially social media analytics, quite a long way ago in higher education and one of the issues and challenges at that time. It was just the start of sort [00:05:00] of social media and starting to think of analytics for social media. Was that the only real sort of analytics you could get was descriptive analytics quite basic stuff you know, counts of likes, counts of shares, and It was is really hard to really use it to do anything.
And so I realized then that I didn’t know enough about handling data, you know beyond Excel which I think is most people sort of initiation of data.
I realized I didn’t know enough about it, and it just kept on coming up. It was a common theme in a lot of the discussions I was having.
And you’d never mention data itself, but it would come up a lot. And so I started on this journey, essentially working in consulting, in an analytics tool called Tableau.
I’d actually met Tableau before that. I didn’t know it, but it turned out that I really enjoyed using the tool. And here we are nearly a decade later and I’m helping people learn how to use it. I learned online on blogs, videos, and actually I didn’t think there was enough video content out there, which is the predominant format that [00:06:00] I make.
And so I thought I could add something to the space and bring a bit of my passion for creativity and design and sort of video content creation to that as well. And that’s pretty much how the channel started three years ago.
Sam Brace: Absolutely. Amazing. Absolutely. Amazing. And I’ve seen, you’re in the tens of thousands of followers, subscribers, and I know that just in conversations with our Cloudinary community, we’re seeing that people are responding to a lot of the work that you’re doing. Where they’re referencing it in tickets and community conversations. It definitely seems like you’re making a major impact. Have you seen that where like people in the business intelligence space are almost seeing you almost as like a celebrity? “Oh! You’re Tableau Tim!” Is happening now?
Tim Ngwena: It’s an interesting one because I think it takes time to… it takes time for good ideas and things that help people to reach people.
There’s so much content I’ve made three years ago that people are finding today and they’re finding it today more than they did last year and the [00:07:00] year before that. So, I always say this to people, when you start out and you’re trying to help people, whether you write a blog, make any content, don’t expect the value to come immediately.
And just because it’s great doesn’t mean everyone who’s going to think it’s great will find it at that moment in time and that’s pretty much just how the channel is growing The majority of my content is just generic stuff that gets people off the ground. I’ve always tried to focus on the zero to 60.
I think once you get into a product well enough, you know where to find really good advice and really good help, but when you’re starting from nothing, you don’t know what you don’t know and therefore you don’t know what to search and find, right? So, my role in the community has always been about getting people from absolutely nothing to deep enough into the subject that they can then go off and consume, many other bits of content made by other great people in the community as well. So yeah,
Sam Brace: Then what sparked the interest for the project that we’re gonna be talking about today where we’re talking about images within the [00:08:00] overall Tableau platform. I know, Jen, you said it perfectly about data visualization. It’s where you’re able to visualize data. So of course, images do commonly come into play here, but Tim what sparked the interest?
Tim Ngwena: So, it goes back to the point I made earlier about creativity and business intelligence tools are designed to be exactly that. They sit on top of a pretty old architecture, which is SQL. And so they have to have some sort of way of getting information from a database and bring it to the sort of end user.
Now, new databases do support images, but traditionally the presentation hasn’t typically thought about that. If you think of a typical SQL interface, the only way it can return images is through ASCII art, right? That’s what happens. And visualization tools have had the same sort of challenge actually, because they’ve come from this world.
Images weren’t something that they [00:09:00] had natively as a format that you’d pull through. But that’s ironic because they’re visualization tools. They actually build charts. They build really beautiful pieces of work, which in themselves become images. Working with images has always been difficult.
And the thing that makes images difficult is that when you create an image. We take images almost frivolously today on an iPhone, but when I was young and giving away my age, you really thought about taking a photo. You had a windup camera and they had 30 photos in there, right? And so you didn’t want to waste the shot.
And a lot of things came with that. You thought about composition, you thought about size, you thought about placement. And actually in today’s world, because we generate images so quickly, we’ve lost that sort of care and attention to images. And so when you come to, business intelligence and you’re trying to add images to your dashboard, all of this thought didn’t take place when you took the image.
And so you’re faced with a few problems like. How do I get these images in a consistent format? How do [00:10:00] I bring them and size them all so they fit? One of them is too large. One of them is too small. One of them has information that isn’t suitable. How do I remove that?
And again, you’re looking at other tools. Image tools, typically, which, things like Photoshop scripting tools, and that just doesn’t make sense in a business intelligence workflow. And so I’ve always had this sort of, idea in my head, like business intelligence professionals are good at working with data.
They don’t need to care about the, idiocracies of working with images. Let’s try and find a way for allowing them to work with them in the way they know best. And actually a friend of mine previously introduced me to Cloudinary because we were talking about hosting images for websites, which is how I actually found Cloudinary.
I used it as a way of hosting images for my blog. And it dawned on me when I was going through, I was like, “Oh, look at this. You can actually manipulate the image just through the URL and Tableau can work with URLs.” [00:11:00] And so I kept the idea. I didn’t actually do anything with that thought I just sat on it and it wasn’t until I got the hint that Tableau was starting to take images seriously that I thought, “Right. Now we can really put this to use. Let’s get this let’s get this concept out there.” Because when that feature comes which it has done and it’s been enhanced on since, there’s going to be some really powerful things you could do with this.
So yeah, that’s how I got into the topic. Long, long explanation, but hopefully it gives all the context.
Sam Brace: So, when we’re talking about dynamic resizing, talking about using Cloudinary in those cases, how are the images being used? Are we essentially putting images for data points or are there other elements that are going to be the image aspects?
Tim Ngwena: Good question. Good question. In business intelligence, you’re typically analyzing data from businesses and businesses operate in certain, let’s call them verticals. And so there’ll be some verticals where images are just native. So if you take retail, if you take consumer products, if you take fashion, if you take [00:12:00] real estate, which will be the example we’ll look at in the demo today, these are all places where you’re looking at information about a thing and that thing sometimes it’s visual aspects make it easier to define in a dashboard or make it easier to figure out. If I take fashion as an example some items of clothing can have 35 different variants of color, size, shape. Just being able to see it makes you identify it much faster. And that’s the whole point of visual analysis, getting to the answer faster. Not having to work through data. Whereas, if you look at the naming convention for some of these products, it just makes no sense.
I always take a dig at Sony. Sony are the ones who are really bad at this. They name their devices with like weird letters, like W X Y, all these things. And so actually just being able to see the product, you immediately know what it is. It’s the same with a car. If you see a car, the make, the make and the model sometimes very quickly, but if you only looked at the names. It’s quite hard to figure out, which caused which.
Sam Brace: No, absolutely. That makes a [00:13:00] lot of sense.
Tim Ngwena: Yeah.
Sam Brace: So, I’d love to see this. Let’s go ahead and pop over your screen and then let’s look at what we got here.
Tim Ngwena: Good. Should I start with an explanation of what Tableau is? While I do this?
Sam Brace: Oh, yeah I feel like we’ve talked about this a little bit in terms of business intelligence software data visualization, but the official intro from Tableau Tim would be fantastic.
Tim Ngwena: Absolutely. Absolutely. Hopefully you can see my screen. So i’m on Tableau public. This is a free version of Tableau. The simplest explanation of what Tableau is, is it’s a business intelligence platform designed to help businesses get their data through what I would call an analytical pipeline and ultimately to some sort of visual analysis. Whether it’s a dashboard, it could be a metric with some sort of indicator telling you how good or how badly you’re doing.
And Tableau is a company, that sort of look after all the different products that help you achieve that overall pipeline. So, Tableau desktop is [00:14:00] the tool that, we’ll mostly be using. Strictly speaking, we’re going to be using the web version. Tableau public is the free version. This is what I’m using now, which means anyone watching this can come and follow along this tutorial if they want to.
And they have other tools in the setup, but fundamentally Tableau desktop, Tableau public, and web authoring are the core of what we’ll be using.
They connect to data and allow you to visualize it. And you see the approach to that as I start working through it, but it’s supposed to be accessible to anyone in any business so they can just get on with insight rather than spending time writing SQL or doing whatever.
And it just all sits on top of SQL. When you do something in Tableau, it translates it to SQL, gets the data for you, brings it back, renders the visualization and presents it to you. That’s how it works. Yeah, good. Let’s start with let’s start with the images actually. I’m using ARC here, so I’ve got everything already to go here.
So, [00:15:00] if I go to Cloudinary. It’s managed to log me out. So, let me just log it back in quickly. And, I just want to give you a flavor of what the images are, what the use case I’m using here is. You can see I have a bunch of images, have a bunch of assets. And these are just essentially, if I go out of the list for you and go to the cards, you can see these are images of buildings.
And the use case here is I’m an asset manager in a property development company, and, buildings have weird names. If I’ve never been to them, I don’t know what they look like. And on top of that they’re located in lots of different places and sometimes just being able to see them can help you make some sort of value judgment about. The next step you might need to do, depending on the kind of property it is.
So, I went on unsplashed.com and you can see the tags are all from unsplashed and I brought them into Cloudinary. Super easy. A few things to [00:16:00] notice. You can see their resolutions are all very different. Nice high res images for the record.
I like high resolution images. Take them once, use them everywhere. Low res images. You have to do a lot of work to get them usable. Just being able to bring everything in here really quickly, upload them. It’s perfect. It’s probably the easiest image upload tool I use other than systems that backup stuff automatically on your phone, which is the next easiest step where you do nothing, but with a business use cases, you have to be more intentional. Then this is what we’ll use.
And what I’ve done is I’ve selected all of them and I’ve tagged them. So, if I go to… let me just go to, let’s say this image here. Let’s just go to this. You’ll see that it’s got a, it’s got a bunch of assets related to it. And on the bottom, you can see these transformations.
These are the transformations that I got super excited about when I first saw this, cause I thought, wow, this is amazing. You’ve got the [00:17:00] main image here and you can make this sort of do something different. And what I’ve done is I’ve tagged them in order to be able to find all these images easily.
So they’re all building images. So I’ve gone and tagged them with a tool called building. And if I just come out of this and the problem I have is that I need to be able to load all these specific images into a data set. And of course, Cloudinary is a developer tool, but like I said before data nerds we’re not strictly developers.
I’m going to get roasted for that, but anyway, we use mostly SQL, which is, the scripting tool, I’ll say. Dashboard development is often a visual tool, it’s got some calculations, but no more complex than something like Excel. So we sit in the middle.
We’re not quite developers, but we think we are right. More roasting for that.
And [00:18:00] the problem is I just wanted to get a CSV of this image. So actually I just, I went on Cloudinary, I went to Google, actually, and asked, “Hey, how can I bulk explore all the images easily?” And actually found this from three years ago someone asked the same question in the Cloudinary community and there’s a couple of really good questions and responses and requests for features, but someone actually made this nice little script here jsfiddle.net.
And I took a look at that and the images are public so i’ve got no issue using this script and so I just took a look at that and it actually does exactly what you’d expect it to. You just give it the cloud name, in which case is my name. So Tableau Tim and I tagged all the images with a tag called building.
And that is pretty much it. It goes and downloads a data set with the Image ID, which is known as a Public ID, and then a URL, which we won’t strictly use, but we just need an identifier and we need to be able to figure out the the URL for that. [00:19:00] And so all I’ve done is I’ve downloaded that onto my desktop. So, if I just bring this on screen. If I… give me one second.
Sam Brace: And the one thing that I’ll point out while you’re doing that is that the great thing about JSFiddle, that open source tool that they’ve developed, you’re showing, of course, the UI or the user interface aspect of it. The nice thing is if any of our watchers go ahead and click that edit in JSFiddle option, then you’ll see all the underlying code that will show the script that’s associated with that.
So, to your point, like if you are a developer and you’re trying to get this to all work, we gave you all the details that happen to be here so that we can see JavaScript and you can see basic HTML and CSS just to mark this up. But all the underlying stuff, of course, is going to be right here in the JavaScript aspect of what they have for JSFiddle.
Tim Ngwena: Exactly.
Sam Brace: I’ll add that the work that Aditi, one of our fabulous developers was able to do, and it actually had amazing applicability. So this is great, Tim.
Tim Ngwena: Yeah, absolutely. Just it … and it speaks to [00:20:00] that point, the platform lets you do this and the way to do that is through the API.
And this is, this just bridges the gap. And you can actually customize this right to do something. I’m sure someone could wrap this up into an analytical tool that sits within an organization. You give it a tag within a Cloudinary account and off it goes it brings all the images for your dataset ready to go.
That’s probably another little tool someone can build. But nonetheless, you get the idea, we bring the data set. And so what I have here these are small, but I’ll just show you the the mock data set. We’ll just wait for this to open up. It’s a CSV, so it should be quite quick. Excel typically likes to catch these.
So here’s the, here’s what it generates. And this is pretty boring still. I appreciate that, but you can just see what I’m getting here. I’m getting the Public ID. That’s actually what I’m really interested in. And for this demo, what I did was I took this Public ID. [00:21:00] And I went to Chat GPT actually to create a mock data set one of the great side effects of the code interpreter from Chat GPT is that it’s actually really good at creating mock data sets. So, I created a mock data set.
I went to the platform. I said, “Hey, can you create me a mock data set?” Where you’re using these specific images as images that are related to a specific building and give me some sort of mock, latitude and longitude. Just so that I could show you something meaningful, but also not actually sensitive to anyone. So, it came up with a mock data set for a building company, and you can see here, the Public IDs for the images. I’ve pretty much been mapped to a specific building. So, you can see here this Public ID is all mapped to building number 14. And if you go down, you’ll see it again and so on and so forth.
So, that’s our data set. That’s pretty much everything ready to go. And the reason this is important is in an analytical context, when [00:22:00] you’re taking pictures of assets, you’ll typically use the ID of the asset, the unique identifier of the asset to define not just the image, but also the row, the record in the database.
And that gives you a key. A key is basically something that allows you to map the two things together, and so we can then use that key in Tableau, a business intelligence tool to do a couple of things. So, let me walk you through that process, but, before I carry on have you guys got any questions things to ask before we hop on over?
Sam Brace: I feel really good. Jen, what about you?
Jen Brissman: The only question that I had was just in terms of the file type here, like the Tableau data extract file. I know that’s… What’s the difference between that and then the file we’re looking at here?
Tim Ngwena: Absolutely. Absolutely. So Tableau allows you to connect to a bunch of files. That actually tees up the next step quite nicely. So, let me go to that, because I think it’s easier to show you there.
Let me go to Tableau public. For everyone’s benefit, Tableau public is free. You can go create an account and it actually allows you to [00:23:00] build visualizations for free. There is no difference to the full version of the product other than you can only save your work here to this Tableau public gallery.
You can keep your work private, you don’t have to make it public. But in essence, you also can’t connect to databases that’s seen as a paid for feature or professional feature. But otherwise you can go up to Tableau public. Download the desktop version if you want to use it on your machine rather than on the web I’m going to be bold and do everything in the cloud as Cloudinary is a cloud tool. We’ll do everything in the browser and here you go, it immediately opens up the authoring experience and it points to your question.
Look, what can we connect to? And in terms of connectors on the free version, you’ve got Google Drive and O Data those are viewed as things that you can use because people store datasets in those places. I think tools like Microsoft OneDrive and so on will come in the future. But when we connect to data here, it’s actually just asking us for our raw data.
So let’s go to this data [00:24:00] set here. Let’s just open that up. And this is a CSV. Okay? And when Tableau opens a data source. You have two options. It can connect to that data source live. So, it just uses that data source as is, but because here we uploaded it to the cloud platform, what it’s done is it’s taken that data and it compresses it to a format called a TD, which is just a Tableau data extract.
It’s a form of compression that Tableau applies to the data. That is really good. You can take a 200 meg CSV and turn it into a 10 meg file, which is quite nice, but it also does a few things like it stores the data in a more optimized format to be able to do computations in a more sort of, performant way. So things like count distincts, sums, averages, those are all faster if the data’s been stored as a TDE. But you don’t have to. When you connect to a database, you can just connect to it live if your database is fast enough. But most people tend to take an extract because [00:25:00] an extract is essentially a snapshot. So, it just performs a little bit faster. Yeah, hopefully that answers your question.
Jen Brissman: It totally does. Thank you.
Tim Ngwena: Good, so here we are. We’ve got the data. You can see the general information I can actually click update now and you can see the same thing we saw in Excel. And this is great the nice thing is that this is not unique to Tableau, all business intelligence tools have features like this. We can do some basic data prep here.
For example, if you want to split this out using the forward slash, you absolutely can. So I can just go in oops, sorry. I can go in here and create… where has the option gone? Why has the option changed in front of me?
Jen Brissman: Because you’re doing a live demo, of course.
Tim Ngwena: Because I’m doing a live demo, of course. Web edit has come to haunt me. There is there, the reason this is caught me out is because there’s a slight differences between desktop and web edit. And when I did the [00:26:00] initial start of this demo, I did it in desktop and then I thought, ah, we’re doing Cloudinary, let’s do it in WebEdit and I just transferred it to WebEdit.
So, I’ll show you how to fix this problem later.
What I wanted to do is split this with the forward slash automatically, but it’s not showing up here. So, we’ll do it inside of the desktop with the calculations. So, that’s fine. The other file I wanted to bring in was actually the other CSV file.
So, let’s go ahead and get the image URLs and here we go. We can see that this is loaded up here. So you don’t see it here because of course we’re still connected to this file. But if I click on this little box, you get a little preview. You can see our image URLs are right there. Okay. So it’s actually done this in a new window.
I don’t know why it does that. So let’s just go back to Tableau and click okay. And let’s just bring it in. And what I’m doing here is I’m bringing the dataset into my data window and it draw, it drew a little line and it’s got this exclamation [00:27:00] mark saying, Hey what is going on here? So let me zoom in to make it easier to see what essentially.
It’s trying to do is it’s trying to form a relationship between these two datasets. If you’ve ever done any data modeling or work with data, it’s essentially asking, “Hey, how do these datasets relate to each other?” And the common field they have is the Public ID. So, let’s go ahead and get that. And let’s go ahead and match that. And so as soon as we’ve done that, Tableau now understands the relationship between those two. It’s not quite the same as a JOIN, if you’re used to working with data it’s slightly different because what Tableau does is it dynamically decides on the relationship. As you work with the data and that kind of gives you flexibility when you’re answering business questions, because you might have a question that needs to answer a question from the perspective where there is no data. Whereas, if you do a JOIN typically you lose that information.
So, that’s why I’ve done it this way, but you could do it in multiple other ways. This is not a data show, so we won’t go into those. [00:28:00] We’ll just carry on. So, here you can see my Public ID and everything’s good to go.
And then now i’m ready to build a chart, so once I’ve done everything with the data, I can just go ahead to sheet one and once we’re there you’ll see you get the Tableau desktop interface and it actually creates the file we were talking about earlier the Tableau data extract because this is being done in the cloud this is fairly quick, but it’s just processing the two CSV files.
It creates an extract file. You don’t see the extract, it’s not for you to worry about, but you see our two tables. Tableau calls them tables. If it was a database, these would be separate tables from a database. But, you can see the fields from both of these, if I expand these out and we’re pretty much ready to go.
And if you’ve never used Tableau before very quick guide, this is your data pane. This is where we build the chart, and everything is controlled by what you do in columns and rows and marks – the marks pane here. [00:29:00] And then filters and pages are just all forms of filtering. So, the blue areas are where you control what you build and the red areas are where you get things and put them onto the canvas to build something.
So, if I wanted to build a simple chart showing utilization for a particular complex, I would just grab complex name, drag it into rows, and you’d get a row for every complex, and then you’d get utilization percentage. You’d put it on columns. And there you get a chart. Pretty dead simple, right? And you’ll notice that it says 600% utilization. And this is where being able to very quickly work with your data is useful because what you want to be able to do is to quickly have a look and see, “Okay, what’s going on with my data? Why is it behaving like this?”
And so with Tableau, anytime you click on a data point you can actually go and see a table, and it goes back out and you can see here, we’ve got 618%, and why is that? Oh, it’s because it’s aggregating multiple records, right? It’s just summing this up. So, very quick [00:30:00] insight just to get you straight to the point.
So, let’s go back to the tab and what we’ll do is we’ll just tell it to give me the average utilization. I know you can’t do averages of percentages, I know, but let’s just for ease of use. Let’s just assume we can.
I know someone will say that you can’t do that. That’s why I said that. Right, so we have our utilization pretty much ready to go, and so you’re probably wondering “Well, where do images come into this?” This is it. This is what I was saying earlier. These building names are pretty standard. Yes, it’s mock data, so it’s not easy to see. If it had real names I might be able to know which one I’m talking about, but nonetheless, I’ve never been to them.
How do I know what they look like? It would be great to have images. And so the first way to do this is just to bring the URL in.
So let’s go ahead.
I’ll bring the secure URL, which is actually from our dataset that we exported using JSFiddle, and you can see the images are here. I’ll keep them there just so you can see that the images… that the [00:31:00] links are working. And we’ll go ahead and create a dashboard. And we’ll just bring our Dashboard into the canvas. We just drag it in. And i’ll go get a web object and just drag that in.
We’ll make it floating so we can keep it just there. I’m a little bit tight for space, but we’ll just keep it like that and then what I’ll do is I’ll just leave this -I have to put something in so I’ll just put Google.com for now.
It won’t load anything. And because that’s not a proper URL it’s looking for http whatever, but it’s fine, we’re going to change that.
And then the nice thing we can do now quickly in Tableau, let’s go to dashboard actions. And we can add an action to go to our URL and put that URL into the web object, which currently is loaded with the Google.com.
I want Tableau to do this on selection. So I’m going to click on this. And we’re going to insert the secure URL when I click. And it gives me a preview of what that looks like. So, to explain this, when I click on a complex, [00:32:00] Tableau will kick off this action. To get the URL, secure URL. This is this field here. And we’ll get that from our dataset and it will feed it into the web object right here. And that web object will change and if it’s an image, we’ll see an image hopefully.
So let’s click okay.
And I hit okay. And now when I click on one, you see it loads an image and it is working. Not great images cause they just seem to be single colors. But remember earlier on, I said here’s the idiocracy of images. The photographer went on site and took a beautiful high res image, but here we are in a dashboard and it’s not sized correctly, right?
This is the problem, and most people are probably complaining.
“Oh Tableau. Why can’t you just fill the box with the image?” Like you probably want an option to say scale to size or whatever. But this is a business intelligence tool. This is not Figma. This is not one of these other design tools, it’s not designed to do that. So, how [00:33:00] do we fix this? And this is where really Cloudinary comes into play, okay.
So, we’ll get a bit more nerdy. Let’s go back to our sheet, and what we want to do is essentially grab – let me just open a new sheet here and just do this. Let’s drag the URL in and make sure that’s the only thing we’re seeing, and pull this out. So here’s a full URL.
And what we want to do is we want to basically intercept, not intercept this URL. Sorry, that’s a bad word. We want to split this URL into two. So we want to take this first part of the URL. And then we want to take the second part of the URL. And the reason is because in between those two, we can put what are called transformations from Cloudinary into that space in the middle.
And those transformations can help us. Change these images just using the URL and that’s the use case here. We’re going to change this without having to go back and rescale the images. Right here inside of Tableau, we’re not actually going to do it in Cloudinary. We’re going to do it here in Tableau [00:34:00] where you’re essentially doing your work.
We’re going to do a couple of things. Now, what I’ve done is ahead of time I’ve written some calculations, but I will explain them.
And yeah, if you’re a data nerd or a developer, this is probably the closest to development we’ll ever get.
And this is what I mean by kind of developers not really. It’s just a very simple string calculation, essentially to find the position of a specific phrase.
It’s called upload. We count back one, and then after that, we know that the specific points in that URL relate to specific things. So I’m just essentially splitting this out and getting what I need from it. That’s what I’m doing. So, if I hit apply, let’s call this base URL.
And then I’ll just put this in place of the secure URL and you’ll see that this is what it looks like. So all I’ve done is I’ve just gotten rid [00:35:00] of the first part of that URL and that’s useful because now I can put whatever I want in front of this to do a transformation. And that’s where we get to the second step of the calculation.
And have you got any questions before I carry on? I appreciate I’m moving quite fast, but yeah. This is a good time to stop.
Jen Brissman: Yeah. The only question I had is about versioning. So, I noticed you do keep the version number in here. And I wondered if there was a reason or intention for that.
Tim Ngwena: No, when you say versioning number, do you mean this? The this number? Yeah. I actually I’ve never, I said, I’m not a developer. So I just go with the URL that the platform gave me.
Jen Brissman: Okay, cool. Yeah. Your calculations have to do with that upload slash, like that resource type part of the URL you’re calculating from there. But these version numbers hang on, and this isn’t super important to mention in the episode, but they’re not necessary in order for the image to render, you could delete the version number and it would still look the same. It’s just to prevent [00:36:00] overwrites essentially.
Tim Ngwena: Perfect. Perfect. So it means I can use the same asset. And if a new version does come up, I use the latest version, right?
Jen Brissman: Exactly. Yeah.
Tim Ngwena: Good.
Jen Brissman: That was the only question.
Tim Ngwena: Yeah. No, that’s a great point to highlight like I didn’t put that in my video, and I bet you everyone who’s followed my video doesn’t know that they think they need it. So good point of clarification.
Jen Brissman: It doesn’t matter whether they know or not as long as it works like that’s the part we’re focused on
Tim Ngwena: Exactly. I always say read the docs for yourself. Good work. Now that we have this here, we’re pretty much ready to go. The bit that we are interested in is actually the, what I call the the leading part of the URL. So let’s create the URL we’re actually going to use. And I’ve just copied that off screen.
I copied it earlier on. What I’ll do is I’m essentially building the text parameter that’s going to create my URL and I’ll just put a forward slash after that upload because everything else pretty much comes after that. And what [00:37:00] I want to do is add a few things in between here. I’ll also add the base URL.
So you’ll see Tableau auto completes. So we’ll just bring that in. And I will also add one more plus. Because what we’re going to do is add something in between here. Double and single quotes. I’m just doing this to show that they’re different parts of the text, and you can ignore the spaces in between here.
And so here, what we can do is we can actually add the transformations. So we can say it’s a very sort of simple format. And just so you know where I’m getting this from, there’s a transformation URL, API reference you can actually see the transformations in the demo sort of area.
When you go to an image previously before when you click on, let’s say this image. When you click on the demo transformation presets here you can see what’s being done to URL. But [00:38:00] the thing about this is it’s got quite a few transformations baked in. So if you’re just trying to follow along, it could potentially be it’s an okay place to start, but if you want to deconstruct it, so you know how it works.
And so that’s why I like this transformation reference, because it’s actually quite a simple setup. You’ve got letters of the alphabet on the right hand side and they just relate to a specific transformation. So, if we want to change the width and the height, surprise surprise, it’s w and h. So, we can just go back to Tableau and we can just say, width_, let’s say 300. Actually, I’m going to choose 150 cause I’m thinking ahead here.
So, width_150 and then comma h_150. So that will give us an image with a width of 150 and the height of 150, and it’s just going to sit in between those two things.
So let’s go ahead and say, this is our Cloudinary URL. And we’ll hit apply and we’ll hit okay. And so we can just check that out and make sure the URL works.
[00:39:00] And this should work. Let me put away my sidebar again. Grab this. And the thing I’m checking here is I’ve not got too many forward slashes, yeah. So that looks good. And you can see it’s applied it across the whole thing. So this is the nice thing about Tableau. It’s an analytics tool, so you can do calculations.
The thing I could also do. Is I could do conditional calculations. So for example, I could say “Hey, if it’s this building complex, do this specific transformation, and if it’s that building complex, do another transformation.” Because it’s a calculation, logic statements, everything are all possible inside of the window.
And Tableau will set this up. In my YouTube demo, I even give the user the option to choose the transformation by giving them a parameter and they can change the transformation themselves. So, we’ve got this here. This is working. Let’s go back to our dashboard here because you see what we want to do is get that loaded into this box. So, we’ll go to sheet one and replace the secure URL with our [00:40:00] Cloudinary URL, sorry. Go back to our dashboard and we need to change this because it’s still expecting that field called secure URL. So, we’ll go back to our action and we’ll tell it instead of secure URL, let’s just delete that.
Let’s insert the Cloudinary URL. So, same concept as before. I can even change this hyperlink… I won’t change the hyperlink cause we’re not going to actually see it. So, we’ll leave that as is. Hit okay. Was there a question there?
Sam Brace: Nope.
Tim Ngwena: No, cool. And if I click on a particular image, there you go.
There’s a transformation it’s worked. So now that, these were like 6,000 pixel by 6,000 pixel images. Cloudinary is doing the work of wrangling them. And it’s doing this in real time. Like, I’ve not gone to these images before and pre-cached them. Although, if you do use them multiple times, you’ll see they load instantly once they’re cached.
So, that’s another nice use case. In business intelligence, you [00:41:00] typically have hundreds of users using the dashboard. So as soon as one person goes to the dashboard and loads it up, it will get cached and now every load after that, it’s going to be super, super nice and zippy and it’s going to work nicely.
And if you need to change the transformation afterwards, you can. You can just go back in and change that. And so that’s the first thing. Just being able to control this little box. And this is a nice other use case. Businesses dashboards tend to have a logo, company change logo, have to go around all the dashboards, trying to find which one’s using the old one, whatever. With this, what you could do is just give it an image URL.
And that could always be a specific size. You could even size a logo within that box Leave it in the corner when the company changes the URL, all the dashboards change. Really simple use case. Perfect for this. Okay, and I think Cloudinary supports like a whole host of image types SVGs…
Sam Brace: Oh yeah. Yeah.
Tim Ngwena: Exactly. Which Tableau does too. So [00:42:00] that’s good. So, this is great, but I think most people watching this are like, “This isn’t what we were imagining. We want the images over here.” And this is where Tableau really stepped up in the last six months. They added this capability first with JPEGs and PNGs, and now they’ve added SVG and even GIF support, which is great if you work in products, because you’ve got these, yeah.
I always think of GIFs as little videos. So, if you’ve got these sort of product videos in the form of a GIF, you can actually bring products to life on a dashboard with this as well, because it’s all supported here. I’m not going to go through that sort of pipeline with GIFs, but what I’ll show you is how we bring these images into this little table as a simple example.
So, we’ll go back to our sheet, and Tableau have this ability. If I sort of bring your attention to this field here. When I go and right click on it. So, let’s go ahead and right click on that.
You’ll see there’s this option called image [00:43:00] role and an image role essentially allows you to specify that this piece of information is actually an image and it’s being pointed at a URL. And so we can just go ahead and do that and you’ll see Cloudinary rendered all of those and there we have all the images nicely loaded.
And so this is a huge deal because without the ability to resize the images dynamically what we can actually just show you what, what would happen. If I just go and just remove basically everything in here. So we just basically have nothing in that space and hit apply and hit okay.
And you’ll see, it’s okay, but it’s not okay. The first thing you’d get from this is, “Oh, can we get everything aligned?” If you work in business, it’s literally, people take shots, not at the analysis, but at the design, right? [00:44:00] So this is the first thing they’d go for. So, it’s really useful just to be able to come in here and specify what you want. And the transformations are super powerful and I’ll go into that in a second. Let’s just say h_300, sorry, hit apply open them back up.
Sam Brace: And the thing that you can always do with all this stuff too is as you’re showing you can play with these transformations. So, if you are finding an output that you don’t like If you’re saying, I want to change the aspect ratios to be one by one, I don’t want to play with what the actual width and height parameters are. That’s a way to get nice squares.
Tim Ngwena: Yeah, exactly.
Sam Brace: There’s lots of really cool things you can do. To your point you could change it from 150×150 just to 300×300 in this example. You can visualize this how you want this to be done through simple URL params. So this is great.
Tim Ngwena: Exactly. And you can even build a mock interface for that, right? Very quickly in five minutes. And that’s where I want to point to this URL [00:45:00] API reference.
Because the list of things you can do is just absolutely crazy being able to enhance the image, right? You know sometimes… Property sticking on property. Let’s say you take a picture of a property indoors now most people most real estate agents take photos indoors, and they’re awful, because they can never balance the exposure between outside and inside correctly, right like… even though smartphones have come a long way you still get either a blown out outdoors or A super bright indoors and no detail whatsoever.
The enhance, I think there’s “e” the letter.
Sam Brace: Yep. So, e_improve would be a great one for that.
Tim Ngwena: Yeah, e_improve exactly is a good one. So, if I find it, where is it?
This is not great screen sharing etiquette, but yeah, here we go. Found it. So it’s super simple. You’ve got you’ve even got examples here so you can see how it works and how it’s set [00:46:00] up. And again, it’s exactly what I’ve just showed you. Just adding this parameter, I think you can even control how much, right? So 50%. Yeah. Nice. Yeah, exactly. So even fine tuning. Yeah.
Sam Brace: And to the point that you’ve made originally about Photoshop, this is meant to duplicate. A lot of the things that I’ve seen people use Photoshop for is hit like auto tone, auto contrast, auto color, and it’s all we’re using it for. And we’re like, “Oh let us do that for you dynamically.” And then you can scale that across all of your… rather than manually doing it one by one.
Tim Ngwena: And I think I mentioned indoor. I think I must’ve seen it before and it’s sat in my mind because you’ve even got the indoor what do you call it, the indoor tag there. So, you can just give it a situation in that context and it improves it.
Sam Brace: Actually, not to steal any thunder here, but one other cool one to mention is that let’s say that you get that really small image from the real estate agent. And you’re like, I can’t use this. One new one that we have is called e_upscale. [00:47:00] And what that will actually do is you using AI to upscale the image to something two or three times the size.
And so you can actually apply that. So that way, that real estate image in that case, now it can be dynamically sized. And so let’s say that you’ve got a bunch of like little I don’t know, 100×100 from the person. You’re like, “these are not usable for my project.” Don’t worry about it. Upscale them yourself. And it’s been amazingly useful.
Tim Ngwena: Yeah, that’s a huge one. That’s a huge one. It’s so important. In business intelligence, you also have this use case sometimes if you are working on sensitive information. You sometimes need to be able to dynamically add not censorship, but you know blur a photo, or cover a face, and these are all transformations that exist here in this sort of nomenclature.
All things that would be an absolute pain to do dynamically [00:48:00] and the thing I’m hoping to see one day is that someone is already using Cloudinary for some other part of their image stack, right? And maybe they’re building apps. Maybe they’re working on other things. I think it’s always nice that you highlight like, here are all the ways you can work with this image.
I’m using the simplest form, which is a URL, right? But you don’t have to change this image pipeline to then go use the same information in like maybe your fashion app where people buy the products. It can all be the same asset, which means your business intelligence and your front facing consumer thing are using the same thing, which is, I think, super important.
Sam Brace: I agree. I agree. I couldn’t have said it better. I love it. I agree.
Tim Ngwena: Single source of truth is like a big buzzword in analytics. It’s super important here.
Sam Brace: Absolutely.
Tim Ngwena: Yeah. So there we have it. That’s the use case. Now there’s so much more for anyone who’s [00:49:00] curious. There’s actually a couple of issues. Tableau do put like a file size limit on the images. There’s a certain number. And so again, Cloudinary actually enables you to get everything into the window, the operating window. If that wasn’t the case, you’d spend all this effort uploading everything to a place.
Only then to find out in your dashboard that actually two of them are wrong. And then now you’ve sat there with notepad and pen taking the image names, exporting them, putting the back up. It just gets rid of so much of the hassle. You know these, this is how to work with images and the sort of list of image types that are supported in Tableau. But I thought i’d just show that for context and it’s also worth noticing…
Sam Brace: One thing that made me really excited, Tim, was like, when you scroll down just a little bit on that screen, because I’m seeing they’re also supporting WebP here, if I saw that correctly.
Tim Ngwena: Yeah, where are we?
Sam Brace: It’s where WebP is something that we have lots and lots of support around. And so [00:50:00] one thing that you mentioned was that you can bring GIFs through for animation purposes. But one thing that’s also really exciting is that WebP also supports animation as a file type. So, you’re now able to optimize this so that way it loads quickly. It’s not too large. It’s hitting all the right sweet spots. But then you don’t have to bring it in as a super heavy GIF. You can have it where it’s nice, lightweight WebPs. So there’s lots of cool stuff that’s coming from what Tableau is now supporting that Cloudinary can basically say yes, and we can do that too. So this is very cool.
Tim Ngwena: Exactly. And I don’t know, you guys can tell me does Cloudinary, can Cloudinary downscale to like a target size?
Sam Brace: So there’s a few ways that you can do that. One of the easiest ways to do this, and honestly, if with the resizing that you’re applying, if you also apply our transformation called f_auto to this, and what that will do is it’s going to automatically deliver it at the most optimal format in that situation, so [00:51:00] as an example, as I was talking about, GIFs are typically pretty heavy. PNGs also are fairly heavy in size, so that would immediately start stripping out kilobytes by changing it to something more optimal. And then on top of that, we have a service called q_auto, which is essentially auto compression.
So it’s going to add a little bit of compression based on the situation that’s there. So I think if you apply your resizing your f_auto and your q_auto altogether, you, there’s no reason that you should never hit the sweet spot of the 200 kilobyte limit that Tableau has.
Tim Ngwena: Yeah. And then that’s, and that’s it like, again, it’s so hard to look at an image and tell someone whether or not it’s going to hit that limit. Because if I like as a really simple example, like this shoe as an image will take up less data than this shoe. And to explain that to someone, it’s quite hard because it’s all about the amount of color, the amount of detail in that [00:52:00] image, whereas the white shoe has literally probably only seven image, seven colors in there.
The other one has tons more. And people just don’t think of that and why should they right? And so the this kind of this just being able to just delete these challenges is really good. I like it.
Sam Brace: Well and this image that Tableau supplied here, it’s no offense to Tableau at all, but i’m looking at it I’m like, “He should be using our c_pad transformation because it would add white space around all of the shoes perfectly So that you have these nice two kind of crops but all of the shows there, but we’re also in white space to make sure we all feel properly.”
So, there’s definitely cases where I’m like, “Oh, Tim, if we could only get like everybody to see this.” The images and data visualization would just be perfect together. It’s like chocolate and peanut butter, you combine and they’re perfect. So..
Tim Ngwena: Exactly. Yeah. And I’m due to make a follow up to the video I made a few months ago. Because Tableau have added capabilities to this. And I think it’s starting to get to the point where [00:53:00] you don’t have to just use images in this sort of technique that I’ve shown you. I think if you’re smart, you have this capability in Tableau of just having floating image objects, and actually you could have them almost dependent on specific data fields.
So, it could actually even allow you to theme a whole dashboard. Completely differently based on the image and using Cloudinary to deliver that quickly to the dashboard in a performant way and just change the entire look of it based on data attributes. So you click on a building maybe the entire theme changes. Maybe you’re analyzing sports. You click on something and the entire sports field change or the coloring or the branding changes. All of these are super possible with this. So super good.
Sam Brace: And that’s interesting. It’s something for us to explore together, I think, because…
Tim Ngwena: Yeah, absolutely.
Sam Brace: I think that we analyze and are able to associate with a image when we’re bringing it in is there’s lots of metadata that’s associated with these images.[00:54:00]
And one of the things that we immediately start tracking is predominant colors that are inside of that. So, I wonder if there’s ways where if you’re talking about theming of a data visualization chart or a dashboard, that way you can say, find the predominant colors of the images and then map it to the actual theme of the dashboard.
Tim Ngwena: Yeah.
Sam Brace: That’s something that we already have baked into Cloudinary. So, there’s possibilities.
Tim Ngwena: It’s definitely a cool one to try. And you know this is always this is really simple functionality. I always have to highlight to people because I think if you come from something like Photoshop or Figma, this probably looks ridiculously basic.
You’re probably wondering like what world you live in where you get excited about images and tables. But in analytics, this is so relevant in so many use cases. And it’s just the context of where you’re using the image that matters. Yeah.
Sam Brace: Yeah, and it’s not like Tableau is only used by a couple people. This is a big piece of software.
Tim Ngwena: Absolutely. Absolutely. Yeah, [00:55:00] absolutely.
Sam Brace: It’s the reason why Salesforce made a major investment into it.
Tim Ngwena: Exactly. Yeah. I didn’t even bring that up. So yeah, absolutely. It’s it’s part of an even bigger ecosystem now as well. So super important.
Sam Brace: Absolutely. So I’m very impressed by what’s been done here. I think you’ve given most people that have to do work with data visualization and business intelligence a very clear path on how to cut up the Cloudinary URLs and use the Cloudinary place, essentially our accounts, our digital asset management portion as a single source of truth. And then, and I love your call to action and I will echo it. If you have a website that’s powering images and you have mobile apps that are powering those images, there’s no reason why your BI teams or your data visualization teams couldn’t immediately use the same assets for creating amazing workflows like this in terms of data.
Tim Ngwena: Yeah. Yeah. And it doesn’t matter what pipeline you use. I’m Tableau Tim, so I’m not going to demo Power BI but, [00:56:00] Power BI, you can literally follow the same steps. The steps I followed are I think tool agnostic. You know, those split functions exist everywhere. The ability to bring it onto the dashboard I’m sure there’s ways of doing that if you can serve up the URL. Cloudinary is just presenting the image and so it’s it’s something that you should try in whatever workflow you have, whatever visualization tool you have.
Sam Brace: I love it. So Tim, one thing that I want to ask you about, because now we’ve seen this awesome project and we know what’s happening with it and we’ve also pointed out as well that you are on tableautim.com, but is there any other like big spaces where, if someone wants to get ahold of you and say, I have a lot of Tableau questions or I need consultation, or I just want to say you did a great job when you were talking with Sam and Jen. Where should they be going? Is it LinkedIn? Is it Twitter? Is it somewhere else that’s cool? Where
are you wherever you are? Just search tablets him. I’m fairly confident. You’ll find me. I never like to tell people where to go because [00:57:00] it’s a bit like it’s just really tough people go where they naturally want to go, right?
If it’s threads twitter linkedin youtube search tabloid sim, i’m pretty sure you’ll find me and Yeah, I do have things like discord and newsletters, but those are less well used So start wherever you are and just reach out. I’m always open to contacts and meeting new people as well So feel free to ask questions
Okay, I have one, one question before we let you go.
That’s a little unrelated to everything we’ve talked about, but very related to the fact that you are a content creator, which is different than a typical guest on DevJams. And something I wanted to ask as a fellow content creator, and Sam is also a content creator, is… First of all, your content is fire.
It’s absolute fire. Like every video I’ve watched, I’ve absolutely loved and been really engaged by. And I wanted to ask you, what program do you use or how do you go about making those awesome sketches and all those animations? Yeah. [00:58:00]
Yeah. Cool. Yeah. The animated videos are just me and an iPad.
So I use procreate and procreate has this time lapse feature, which just records your sketches. To get it to work for video, there’s a few tricks, but anyway, I essentially use a green screen technique. So that when I sketch it’s accurate every time, but I first build a composition in illustrator.
So we started illustrator with a composition. We bring it into procreate, make it all green, and then I draw over it. And then in the video editing tool, I apply a green screen effect and the green disappears. And you can’t tell that I was essentially tracing it. And then This is all drawn to a storyboard and the storyboard comes after the script which I write I then do the audio for the script So the audio is done ahead of time and then I do the animation and drawing afterwards So it’s like a backwards pipeline.
You’d think I’d draw then I’d do the narration It’s actually the other way around because the animation has [00:59:00] to match the audio. That’s why it works So that’s that technique. And then I just sit in DaVinci resolve or primary prayer, whatever you use. And I just do time queuing and stretching out clips, compressing clips to make the timing or work.
And yeah, again, it’s just a creative outlet, right? Like I have this idea, something I want to do. I just find the shortest possible path to do it. And as I’ve been doing it longer, I found. Shorter and better ways of doing certain things. And yeah, it’s just been a really good way of bringing people on board.
So I do have a plan to take that format to lots more places and it just takes a lot of time. So I’m going to actually hire an animator at some point. I’m going to do it properly because tracing doesn’t always work. So yeah we’ll find some help.
Wow.
Jen Brissman: Thank you so much for letting us see behind the curtain there.
That’s really fascinating.
Tim Ngwena: Actually while you’re here. Sorry Sam, if you go to the blogs section if you hit the blogs. [01:00:00] The top blog. Oh, there’s a Google ad there. If you click on making an overview of… that is the blog explaining how I did it.
Jen Brissman: Oh amazing cool.
Tim Ngwena: Yeah, so if you scroll down…
Jen Brissman: So, if anyone’s interested in his awesome videos. Check this video out, which is probably a very cool video about making cool videos. Everything’s connected here.
Tim Ngwena: What happened to my page? I put one ad on there and it’s been absolutely taken over. That’s so embarrassing. Oh, God…
Sam Brace: Do not worry about it. This is great. This is amazing insights.
Tim Ngwena: It’s all the details there. Yeah. You can check it out. I’ll kill those ads quick.
Sam Brace: Thank you again, and keep in touch because we want to see all the great things that you’re doing. And of course, as Tableau releases new capabilities, enhancements, features, there might be more ways that images, hopefully videos, maybe. I don’t know if we can incorporate it into data [01:01:00] visualization.
Let’s see what is possible.
Tim Ngwena: Good stuff. Thank you.
Jen Brissman: Thanks, Tim.
Sam Brace: So Jen, I want to ask you, what’s your big takeaway from this episode? What stood out to you with Tim’s demonstration of everything that’s powerful with Cloudinary and Tableau together?
Jen Brissman: Yeah, I think it’s just that. I think it’s that Cloudinary and Tableau are really powerful together. And there are so many technologies that weren’t obviously built to work together that work really well together. And another big takeaway is just that Tim said, “Oh, I’m not a developer” And, but he’s using Cloudinary and Tableau in a really technical way. And it just opens the door for people who might not be self proclaimed developers to use these technologies in a really technical and beautiful way. And just watching how these two technologies work together is really inspiring for me. And basically having a guest on the [01:02:00] show that isn’t our typical guest and with a program like Tableau that I didn’t know that we would ever have on a show like DevJams, and this perfect example. And I really think people can watch this and gain so much and just copy what Tim’s doing. And maybe even use some cooler transformations or like f_auto, q_auto, like you said there’s just so much to look at here. A lot to think about.
Sam Brace: I agree. And honestly, I can’t say it better than that. I am very excited to see how this is impacting because as I pointed out, we’re seeing lots of conversations where people are now seeing Cloudinary from a new perspective where they’re saying, “Oh, I can use it for this project and that project”.
And I think the point that Tim raised that there are probably many companies out there that are using Cloudinary to power their websites and their mobile apps for image and video delivery, but they haven’t thought maybe there’s other ways to expand that usage into a lot of [01:03:00] the things that aren’t part of the typical web teams or the software engineering teams or website side of things.
So it’s definitely where I think just knowing that your asset can live in one spot and can be used by many different types of programs and applications is a wonderful place to be thinking about. And not saying “now I need to go put it here or there or the other place”, or “now we can leave it in Dropbox and Google Drive and all these other places”.
Just put it in one spot and let everybody else connect to that. I like that approach. Yeah.
Jen Brissman: Yeah. And really that single source of truth is such a buzzword and it is so important and really another takeaway from this episode is that data is everything. Data is everything and it means everything to all tech companies.
So the fact that Tableau, which focuses on visual analysis and data analysis can be using Cloudinary is so cool. And even for myself personally, I come from a Python background and SQL is really my [01:04:00] comfort zone. And what got me so excited about being a developer is
the data and how powerful it is to work with it and these databases and relations and how they relate to each other and these joins that Tim was talking about that you don’t even have to like all that complex SQL that I learned when I was first getting into this, like it’s not even really necessary with programs like Tableau.
So it can make things easier for developers. So whether you’re a developer, whether you’re not a developer, there are these programs, like Cloudinary – developers and non developers can use Cloudinary – developers and non developers can use Tableau -and just take what you can and use it in the ways that work for you. It’s just, it’s a choose your own adventure. I love it.
Sam Brace: I agree. Absolutely. And if you want to continue that adventure that Jen is talking about, of course, go to check out cloudinary.com/podcasts. That’s where all of our episodes, including this one, are going to be located on top of all of the typical podcast services that you [01:05:00] probably enjoy listening, watching the podcasts on, whether that’s Spotify, YouTube, Apple podcasts, Google podcasts.
We also host all of our podcasts in our training Cloudinary Academy. So on top of all the free courses and workshops and live events that we have for teaching people Cloudinary, that’s also where you can find many of the podcast programs that we are talking about here today. And lastly, but also extremely important, check out our Cloudinary Community to be up to the speed of all the latest and greatest things that are happening at Cloudinary and make connections with other Cloudinary users like yourself.
That’s going to be at community.cloudinary.com, as well as our associated Discord server. Both are linked inside of the community section that is at that URL I mentioned, community.cloudinary.com.
Jen, this was wonderful. Thanks for being a part of this. Any final thoughts before we let our audience go?
Jen Brissman: No, I just, I think we’re so lucky to have had the Tableau [01:06:00] Tim join us on DevJams this week. So thank you, Tim, for your time. And I hope that our audiences find this to be as stimulating as I have.
Sam Brace: Agreed. On behalf of everybody at Cloudinary, thank you for participating in this episode of DevJams, and we can’t wait to see you at the next one- to learn more about all the things that developers are doing that are exciting, innovating, inspiring when it comes to images and videos.
Take care, and we’ll see you soon.
2024-01-17
Easy Content Publication with Hugo, Decap CMS and Cloudinary
Are you looking for a simple and scalable way to launch a website? Does it need optimized image and video delivery? How about a flexible content management system? Look no further! Martin Jagodic, who is a senior web developer for PM, has created an excellent solution. It includes static site generator Hugo, as well as Decap CMS for content authoring. And the project uses Cloudinary’s rich transformations for optimization and aesthetics too. Martin walks through his project in this Cloudinary DevJams live stream and episode. In it, he shows developers how to use it for their next website launch. He also showcases Maistra, one of the largest hospitality groups in Europe, and how they use this solution to power their web properties.
Sam Brace: [00:00:00] Welcome to DevJams. This is where we talk with developers who are doing interesting, innovative, inspiring projects. Normally when it comes to delivering or managing images and videos inside of those projects. And because I work for Cloudinary and this episode and this overall show is produced by Cloudinary, they are probably using Cloudinary in those projects.
My name is Sam Brace. I am the Senior Director of Customer Education and Community at Cloudinary, and we are so excited to be bringing you this episode where we’re gonna be talking about content publishing using a few different pieces of technology, static site generators like Hugo, as well as a Decap content management system, formerly known as Netlify CMS.
And of course, Cloudinary to be able to make it easy for you to be able to easily publish your files and create really [00:01:00] exciting web presences with the overall mix that happened to be there. Thanks to the development work of Martin, who is a senior web developer at PM, which is a content marketing and creation company that is based out of Slovenia.
So great work that’s being done by him, as well as being used for some of their amazing clients worldwide. Joined with me for every single one of these episodes is Jen Brissman. She’s a Technical Curriculum Engineer over here at Cloudinary, and I’m so happy to have her here for this episode. Jen, welcome to the program.
Jen Brissman: Hey, how’s it going?
Sam Brace: Good. Good. And I am so happy to have you here, and I’m so happy to be talking to Martin here in a little bit. But tell me a little bit, why are you excited to bring Martin onto this program?
Jen Brissman: Yeah. So as far as static site generators go, we’ve had people on the show that have talked about Eleventy, but we’ve never had anybody talk about Hugo before.
And I’ve heard that it’s really easy to use even if you’re not familiar [00:02:00] with Go. So I’m excited to hopefully inspire our listeners to maybe give Hugo a try. So…
Sam Brace: You’re absolutely right. This is the first time we are talking about Hugo, which is great. And as you also said, we have talked about different types of statics site generators in the past when it comes to this.
And so it’s not necessarily a new topic. You have all the way from NextJS to Jekyll to Gatsby, all these different things that are out there when it comes to being able to create content. Now of course Hugo being another flavor, another choice that happens to be out there, which of course, Martin took.
So this is a case where if you have ever decided, maybe I should check out Hugo and what they’re doing, or as we’ve also mentioned, some of the things that are done with content management is we’re gonna see with Decap, this could be a really good way for you to explore another option that happens to be out there when it comes to web publication. Great point there Jen. Now, one thing I do want to mention is that when we are taking a look at our overall content, make sure that you are remembering that we are going to [00:03:00] be, here we go. We’re gonna be talking about Martin’s project, which he has available as a open repository on github.com. So if we are so inclined, make sure you’re checking out the show notes and we’ll make sure you have a full list of access to all of the things that we’re gonna be talking about today, including this overall project repository.
So everything we’re gonna be covering, it’s something that you can start accessing and start using right away within your own projects. So this is definitely something that we hope you start to use and fork it, clone it, download it, whatever you need to do from GitHub, but be able to start incorporating this into your overall projects for content publication, ease.
And we should also mention that all of our podcasts that we have done for the DevJams program, whether that’s a live stream, whether that’s a recorded podcast, those are all gonna be available at cloudinary.com/podcasts. And as you can see, we have years of content that happens to be available there for your learning purposes.
So make sure to check that [00:04:00] out. Once again, cloudinary.com/podcasts. And finally, before we bring in our friend Martin, I should mention that the Cloudinary community is the go-to place to having peer-to-peer conversations with other Cloudinary users. So if you hear about something on the podcast and you wanna explore it to see if other users are using it maybe in a slightly different way or with a different perspective than what we provide on this episode, make sure to be going to community.cloudinary.com where you can be able to have those conversations with users and notice that we also do have an associated Discord server.
If you do prefer to have conversations inside of Discord versus our overall form-based service. So with that said, let’s go ahead and bring on our friend Martin. So Martin, whoa, not Martin, welcome to the program.
Martin Jagodic: Hi, great to be here. Thanks for inviting me.
Sam Brace: So Martin, I talked a little bit about you mentioning [00:05:00] PM, of course, the agency that you work for. I mentioned that you’re a senior web developer, but let’s get a little bit more flavor. Tell us a little bit about you and the work that you do.
Martin Jagodic: I’m a senior web developer. We’re working with JAM Stack since 2020, I think when we introduced the Netlify, Hugo, and Netlify CMS to our stack. And later on Cloudinary, of course so I’m focused in that department.
Which is mostly frontend, but yeah. Backend is handled by all those services. I enjoy this stack and this work very much so that’s shortly about that, what I do.
Sam Brace: So you mentioned Hugo, which is one of the big stars of, in the overall project that we’re gonna be talking about here.
So talk to me a little bit more about Hugo, for those that aren’t familiar with it, maybe give us a little bit of detail of why you incorporate this as the static site generator and the products that you’re working on.
Martin Jagodic: Hugo [00:06:00] is very fast. I would dare to say the fastest static side generator. Like for one project, I guess largest project that we have builts around 10,000 pages.
And that happens in a matter of seconds. I would say some other generators would take minutes to build that. So that’s one thing. Another is it’s very feature rich. So we, it’s, it basically can help you with whatever problem you’re having with whatever solution you’re looking for. For us, for instance, very important is
having good content organization with large sites a good internationalization support which is great and works well with Decap [00:07:00] cms. What else? The templating engine is from Go it’s a little bit different than what some or maybe most frontend developers are familiar with when using nunjucks and stuff like that.
But once you get used to it, it’s really powerful. Yeah, I could go on. But that are, I guess the most my favorite things.
Sam Brace: You mentioned a lot of really important things too. So the fact that I know that we’ve seen, at least on the Cloudinary side, a growing community of Go developers. So it is to say that if you are familiarized with Go, it seems like Hugo might be a natural choice when you’re choosing a static site generator.
Is that correct?
Martin Jagodic: Actually you don’t have to know Go.
Sam Brace: Oh.
Martin Jagodic: I personally don’t. So it’s you just install it on your machine and you’re ready to go. All you have to know is the HTML and yeah. You have to [00:08:00] learn the templating engine. And you’re good to go. Yes.
Sam Brace: Oh, its even easier. And I like the use of “Go” there too.
Jen Brissman: Yeah. Good to “Go”.
Sam Brace: Excellent. That’s actually great to hear.
Martin Jagodic: Sorry. Another great thing with that is it comes with pre-processors and the JS bundler ES link. You don’t even need Webpack. You don’t need even package.json if you don’t wish to.
So yeah, that’s one of the, also one of the big reasons why we chose it, because dependencies can be a big hassle, and this way we remove a lot of that problems.
Jen Brissman: That’s awesome. Yeah, it seems like there’s a low barrier to entry. Like it would be easy to get going within a day or less and it seems like the Go is more under the hood and it’s not so you don’t really need to [00:09:00] use it. It’s really okay if you don’t work with, Go on a regular basis.
Martin Jagodic: Exactly. You will, you would need to know, Go only if you want to contribute to the project, which is open source, of course. And I must say very well maintained. I haven’t found many issues with it. So yeah big shout out to maintainers.
Jen Brissman: Yeah. Awesome. Yeah, this is like an advertisement for Hugo at this point. I’m just kidding. But, it just seems and I was doing some research too before episode. It just seems like the “go-to”. Now I’m thinking about all the ways that we’re using, go. Get it going, go to. But yeah it seems a really obvious choice if you’re interested in doing fast work, which most developers are. So let’s see. Let’s take a look at some of your code and see how this all works.
Martin Jagodic: Okay. So yeah, I would like to explain. [00:10:00] How Hugo, Decap CMS and Cloudinary could work together and how we do it with our projects. So first let me explain a little bit how this project is set up.
So this is how a Hugo Project look like. You would get an assets folder where we have our styles. The CSS is processed by Hugo. So we don’t need a webpack or something like that for it. We have the content folder where we will store our content in markdown files which have YAML.
Then we have layouts folder where we will define our html. So this is how the templating engine [00:11:00] syntax looks like with the curly braces. And then there’s the static folder where we usually puts that are not not handled at build time. And we will put our admin, so the cms
in this project, but usually this will be where we store our media assets. But in this case, we’ll handle that with Netlify sorry, Cloudinary. And yeah, there’s the hugo.toml where we will define the settings for this for this project.
Yeah, what we’re gonna do so we want to build a website just in this simple example that uses that has a homepage and a simple [00:12:00] blog with some posts, and we will connect the CMS where we can add those posts, and most importantly add an image to this post,
and then add transformations with Hugo to it. Yeah, let’s let’s first try, let’s first see how to add Decap CMS.
Sam Brace: Okay.
Martin Jagodic: Which is really simple. All you have to do is add two files, one of which is index html in your admin folder. By the way, this works with any static generator. You just have to put this into your static public or whatever the name is of the folder for your generator.
In this case, it’s static, and this is gonna serve as a placeholder for the cms. So this included via CDN, and [00:13:00] this is a React app. And the other file for the CMS is the config file in yml format. And this is where we, that this is where the all the magic happens. So we’re gonna define one, the most important collection is the blog.
It’s a folder collection. So for all posts in this collection it’s gonna have the same layout. And I’m also gonna define a file collection where each post with each file here, can have a different layout. In this case I want to have ability to edit the homepage and the blog list page. So that’s how I define that here.
And another thing, Decap [00:14:00] CMS. It has the default media library, but it’s really easy to add the Cloudinary as your media library. So all you have to do is add five lines of of code here. So we would just say the media library is Cloudinary and you need to have your cloud name and API key, and you’re good to go.
So if I bring up my Hugo server to, to launch the website and then run the CMS locally and see that. Okay, so now this is the website that you’re working on, and this is the cms. And so these are the two collections that I created. One is blog where I have my my pages.
And and the pages [00:15:00] list where I created option to edit homepage and the blog list. And since I connected the media library let me just refresh this. If I, right now, so this is the state. Before I commented it, I didn’t save it. So this is the, this would be the default media library.
And if I save this and refresh. I get my media library.
Sam Brace: That’s great.
Martin Jagodic: Yeah. That I’m connected to one, one thing to notice though, you have to be logged in the browser to this Cloudinary cloud that you’re using.
Jen Brissman: Wow.
Martin Jagodic: Okay.
Jen Brissman: So you just have like with those five lines of code that you just showed us that you just commented back in, you have a CMS that ships with Cloudinary, with this media library widget. That’s all you need.
Martin Jagodic: Exactly.
Jen Brissman: Awesome. Awesome.
Martin Jagodic: [00:16:00] Okay for now let’s let’s see what we have here. Or let’s create a new post. And that title I don’t know office I think is cause I know which image I’m gonna choose. Okay. There we go. So I’m just choosing this image of an office and I click insert.
And I have my image here, so if I say this or publish this, and now in my in my content in Hugo, I added the office.md where I said office and what you’re interested right now, here we have restored our Cloudinary URL of this asset. Let’s see how we can show this asset and most importantly, transform it [00:17:00] in a way that cloud Cloudinary will send us back the most efficient image.
So, that means we have to go look back at Hugo, the layout. So we have the base of layout, which is. Layout that all other layouts we use. So here we, we define the head and import our styles and scripts if we have them in this case, we need one script like Cloudinary that will that will get us the correct width of the image.
And then we have three layouts in this case. The index one is for homepage. And in the default folder, we have also list and single layouts, which are for the blog. So the list would [00:18:00] be the one on this. So where released are articles and the single would be if you click one of them then the single layout and let’s see how we can get this image and get the best possible transformation.
And let’s look at the single one. So it’s pretty simple. I print out the title, description, and then I created a partial, which in Hugo is like a component. So we can reuse this many times, and I’m reusing this on all layouts. I have images so I don’t have to worry about transforming them every time.
And in this case let’s see how it looks. So I’m gonna open the image partial, and this is where the magic happens [00:19:00] of transforming. So I want to be able to send in some basic parameters, which usual image tag in HTML would have. For instance, the source, width, height, style class or something else.
So in this case, the most important one is the source. And if I go back to the single, so this is what I’m sending in. Source is the parameter in image. Yeah. There we go. And I’m storing this into a variable that will, I will use later on. And I will also get Cloudinary base URL and Cloudinary common transformations that I stored in my hugo.toml because I want to make this stuff easy for myself and I will [00:20:00] apply the same transformations on most images that I store them in the global config.
The most common transformations that I found are best to use are the crop fill, which will take any dimensions that you specify usually width, and then and then apply crop it so fill the dimensions.
Sam Brace: Yeah. You got it. You got it.
Martin Jagodic: Okay. Then gravity auto. Since fill can change the aspect ratio.
We want to make it we want to ask Cloudinary Okay. Gravitate to the most apparent object in this image. Quality auto, self-explanatory, and dpr_auto. So this would be for instance, for thinner displays, which have I [00:21:00] think this is dot per pixel so basically how many pixels are there? How many dots are in a pixel?
So in this case would have two and normal display have value of one, and f_auto means auto format, which is very useful because some browsers don’t support more image formats and Cloudinary will return the most efficient one.
Sam Brace: And I agree with this yeah, I just wanna make sure it’s clear. This is great what you’ve done here. This is a very good set of transformations that would apply for most use cases. So I think that why having that as the default makes a ton of sense when you’re looking at optimization make things are cropped to the right aspect as well as to making sure that you’re focusing on the most interesting aspect of the image, which is what your gito is having here. So this is great. Hopefully people that are trying to figure out how to use Cloudinary [00:22:00] transformations there, they can use exactly what you’ve done Martin, and say, great, this is a good place to start with, and of course be a thousands of transformations, but this is good place.
Jen Brissman: Yeah.
Sam Brace: One thing I did wanna ask you before we jump away from here. Is you do have the breakpoints that are emphasized. So you have the 1920, the 1440, the 1200. How did you come up with that designation? How did you decide these are right breakpoints to be using for the various breakpoints you do have?
Martin Jagodic: I’m not sure. I’m actually copy pasting this for a few years now.
Sam Brace: And that it shows, it works. If you found something that works, then you can just keep repeating it. So once again, this is also a good test to say 1920, as we know, that’s probably the screen with for a lot of high resolution images and that you have, so all the way down to 566, we probably work really well for mobile purposes. So then you have a nice range. They happen to be there. So I think this is good. And I also agree a hundred percent what we have [00:23:00] here, not too many break points, but not too little. So it hits a sweet spot for most the viewports that you’re gonna be dealing with. So again, theres a lot of intelligence here.
Martin Jagodic: The steps around 200 and some of these values are from, I think, common css libraries, like bootstrap, stuff like that.
I think I found that, these are pretty common, and for maybe listeners who are not watching the screen right now. So we have break points defined from Xs so extra small, small, medium, large, extra large, and extra extra large in the span of around 200 pixels from 576 up to 1,920. And yeah. But these break points are not even used right now.
This suggesting because I [00:24:00] used like I wrote a small library for breakpoint, so for mixing and I’m just copy pasting this in all my projects. So…
Sam Brace: I love it.
Jen Brissman: And also for our listeners, I feel like it’s important to note that. Martin’s globally storing these variables. So like the URL cloud name and all the, all of these common transformations that we’re talking about, those are stored globally.
So it can be used so that like when he’s doing a check, if it passes the check, the URL is built again. And I think that’s probably where we’re get in, we’re gonna get into talking about now.
Martin Jagodic: Yes. Yeah, and also what you said previously, Sam, that these are some really common transformations and really, Cloudinary has tons and I would lo love to use all of them.
They’re really good. But I’m lazy and try to be efficient. And this is, I found like covers 80 or 90% of all [00:25:00] cases. So that’s why I’m storing this globally. I’m using this everywhere and if I see, if I’m like developing a component and I see, okay, now I need a special use case, then I use something special.
This would be like for most use cases.
Jen Brissman: A catchall. Yeah.
Martin Jagodic: Yeah. Let’s now look how we’re gonna apply those.
Sam Brace: Okay.
Martin Jagodic: In my image partial. I get the source, I get these global values, the base URL of Cloudinary Cloud, and the transformations that I talked about. And then first thing I wanna do is check, is this even image hosted on Cloudinary?
Because what if editor adds in, I don’t know, an image from GitHub or something else, somewhere from the internet? And then in that case, I can’t transform it, right? So I’m [00:26:00] gonna skip that if it’s not, but if it is, I’m gonna split the URL and I’m gonna get the relative asset URL. So just the last part or the slag, let’s call it the slag.
I’m also gonna get the width and the height if I send them in. I want to be able to, when I use this partial define sometimes these values, and if I do, I wanna also use it in transformations. And when I have all that, I’m just gonna combine this again together to get the URL with with the base.
The transformation and the slag which I stored here under the src variable. And then I’m just gonna use this in the image tag [00:27:00] cause we’re still in html. And one thing that’s important also here is that when you’re using Cloudinary, make sure that it’s data-src and use the class cld-responsive cause in the baseof, we’re using a library called cloudinary-core-shrinkwrap, which is gonna upon loading get the source and then get the width of the window and then get the… so change the request URL and then get back the correct width. I think rounding up to 100 pixels by default.
Or maybe a better solution to use this breakpoint that we defined. In that case, we’re gonna use less of our [00:28:00] transformation because those can get out of hand pretty quickly if we have a lot of images.
Sam Brace: Absolutely, and that’s thanks to that w_auto transformation, you’re also invoking there too, so that we’re all working together in conjunction.
So bringing in the right class, the right data source, being able to bring in the right JavaScript. But then because of w_auto, it’s saying use the JavaScript to be able to give you the break points that you’re specifying. So that’s also a great way where if you forgot to specify the break points, or maybe let’s say there’s some brand new fancy device and you’re like, what would the be break point for it? It can just automatically do that for you. So it’s an excellent approach.
Martin Jagodic: Yeah. And then, yeah, so if it’s not Cloudinary in this image, lets just bring in the original source that we have. Any class that is stored. I use loading lazy because it’s supported by most browsers by this point. [00:29:00] And then, add in just some other attribute that maybe we want to set. I, of course, advised to always use alt, but I’m also guilty of not using it all the time.
Sam Brace: Okay.
Jen Brissman: Well, it’s a best practice for sure, so it’s good you’re doing it. So, by the time that any of the images get to the website, they’re already optimized. And I guess I say image. We’re also talking about video here, right?
Martin Jagodic: Yeah, of course. This goes for video tool one thing to note is that in the per the base URL, we need a different URL.
Jen Brissman: Yeah.
Martin Jagodic: Because I’m storing this image here, but I could do Cloudinary video URL and put here a video. I think that works on the top of my head. And then I would just use this URL.
Sam Brace: Exactly.
Martin Jagodic: And I’m doing that also.
Sam Brace: And Martin, that was amazingly [00:30:00] fast, I’m very impressed.
Jen Brissman: Yeah.
Martin Jagodic: Now we can look how this looks actually in the browser. So this is our single layout, right? We printed out the title, description, and here we have the image with the partial. We’re sending the data source, which and then yeah, on the bottom we have this script, which loaded up and took the width of 600 pixels, which is probably the width of this browser.
Sam Brace: Yeah.
Martin Jagodic: So slightly less. It’s only gonna round it up to the next 100. And yeah, it’s gonna, it’s gonna transform this URL. The width, the height, c_fill, g_auto, q_auto, dpr 2.0 because I’m [00:31:00] on a 2.0 screen. And yeah, the format is auto. So in that case, I guess it would be, would probably be what could it be?
Sam Brace: Looks like it became a WebP, if I see that correctly.
Martin Jagodic: Yeah. Right now I don’t know where I would look at that, but. It I tested it really thoroughly and it always returns the best.
Sam Brace: It does. It does, and it’s, and to your point, like it a nice catchall frankly for optimization because WebP does seem to be supported by most browsers now, but it’s also where if it doesn’t see any improvement by changing it to WebP will keep it as it’s existing, which in that case would be jpeg. So it’s aware there’s no harm practically in setting f_auto on it. It only will add additional features and additional improvements to the overall loading processes of what [00:32:00] happens to be there. So I think it’s a good thing to have.
Martin Jagodic: Exactly. Oh yeah, so this was the post that we added. Yeah. So initially why there was a short leg, this image was transformed on the fly.
But if I refresh now, it.
Sam Brace: Yep. Thank goodness for caching and content delivery networks. So it makes it all very possible.
Jen Brissman: And so this code that we’re looking at just for the watchers and listeners is part of an app that Martin put together to demo what he’s doing on the Maistra case, which is how Sam and I first heard about Martin and the work that he’s doing at PM.
I thought it’d be cool to look at the Maistra website and see how fast everything loads and how beautiful it is and how important it is to have a beautiful website like this, and why we were like, oh, we have to talk to Martin. This stuff, this is awesome. And it’s so important. And really [00:33:00] part of the reason why Cloudinary is such an awesome product is because, people are deciding on, let’s just say what hotel to book based on beautiful images, beautiful video, and that’s exactly what’s happening here.
Martin Jagodic: Yeah. All these what I’m showing right now is also on this project. This is basically where we came up with this solution. So obviously it’s a website with a lot of images. It’s a hospitality group, so chain of hotels, resorts, and campsites in Croatia. And of course, it relies heavily on showing visually what they’re selling.
So that’s why we switched to Cloudinary because initially we were [00:34:00] using first. Git large file storage for these assets, for some of the, for some of the projects Netlify also provides some some of that with Netlify large file storage or Netlify large media. But yeah, we needed more.
They came up with this for this project, and now I’m using this approach. Through also other projects because I find it easy to use and get the best results for the least amount of work. Cause, I said,, I’m lazy.
Sam Brace: But honestly, lazy is a good thing when it comes to development cause it means you want things done quickly, you want things done the right way. But it’s also where you don’t wanna put a ton of work into it, having to have that happen because you have a lot of things you have to get done. So I think the lazy is not a bad thing by any means. We’ll talk about this way. But what I love about this is that what we’ve shown with this [00:35:00] project you’ve developed where it’s using Hugo, Decap, Cloudinary, it’s not just used for, let’s say, a personal project or a small project.
This is meant for a major company that is representing hotels and resorts and campsites throughout certain parts of the globe. And what I love about this example that we’re showing here is that to Jen’s original point, can this be done for video? This expresses that it absolutely can, because if I just go ahead and use our media inspector on this real fast, and I go ahead and separate this, you’ll see that you have this blank image here that’s used as a placeholder in case the video doesn’t load or for certain screen sizes, but it’s doing exactly what you expressed it to do.
Where if we take a look at the image here, And the browser bar you’re seeing that its bringing forth the biggest breakpoint you have here, the XXL, the W 1920. It’s also using our c_fill, our g_auto, our q_auto, our dpr_auto, and our f_auto altogether to make sure it loads perfectly. And then similarly, [00:36:00] if we go ahead and take a look at the media details here, it’s also doing the exact same transformations for the MP4 that you have in the background.
All that amazing B-roll and footage of the countryside. That Maistra has gone and created. You wanna make sure you’re expressing that as best as possible. So I love the fact that we took this project and were able to show, not only did you take a lot of time in developing it, but it can be used for real life projects too, just like we’re showing here with the Maistra site.
Jen Brissman: Yeah, and I gotta say, like just having this B-roll and these awesome images and video going as we’re talking right now, I’m like, “Oh, I really wanna go to Croatia”. Like it really is important to have beautiful visuals to help people be sold on where it is they’re going or what it is they’re buying.
I understand why you guys changed to Cloudinary when you were scaling up and having this big use case and this important company. And I’m glad to hear that you use it on other projects as well. I know we’re talking about just this one, but glad to hear that when you found something [00:37:00] that worked, you decided to keep using it and keep going with it.
Maybe because you’re lazy or maybe just because you found a great solution that works. And why change it if it works? So let’s talk a little bit about Decap CMS and what happened with your journey there with PM and how it got to be that you, you’re working with them or taking it over.
Martin Jagodic: Yeah, that, that’s an interesting story. In this case, Maistra, we also use Netlify CMS, which is I would say not intended for such large websites. But when we research CMSs we didn’t find anything else that we would say, okay, this is obviously better because Netlify, or now Decap CMS had a lot of functionalities that are just not present in some of those and yeah, we were used [00:38:00] to it. We said, okay, let’s go with it. And yeah I am I could say we tested the limitations of the CMS, but I wouldn’t say we have reached the limits or maybe we reached the limits, but it works in this stack.
Yeah, we were really sad to see that I think last Spring Netlify kind of stopped maintaining it because they turned their focus elsewhere and yeah, we were kinda we were hoping that someone else would take up and nobody did. So we were like, okay, we’re using this CMS. We like it a lot.
We contributed a little bit to it. And we had good relations with Netlify and we said, “Hey, can we maybe take over the maintenance if you’re not [00:39:00] interested anymore”? And yeah, after some talks they said, okay, let’s do it. Yeah. And then in February we re named it to Decap CMS.
And now we’re we’re working on our first release, which will contain a lot of updates, but not functionality wise. Just we need to bring up some more dependencies. Some tests are failing for no reason, so we want to make sure that we that we bring the first release that’s gonna be maintainable for the long run.
Sam Brace: This is incredible and it’s great to see the story that’s behind this. And what I also love about this is that even though yes, your team is now taking a major stake into what the Netlify CMS what its become, calling it Decap and moving forward with it. It’s also [00:40:00] still completely an open source CMS. So it’s where people can be contributing to it.
It’s something that’s readily available. For anybody to start using in their projects today. So it’s great to see that the Netlify CMS found a great home and that you guys are fostering it really well. So this is great to see. And then of course, how it’s applicable for the various projects we’ve shown with what you’ve done here with Hugo and Cloudinary and Decap. And then also see the applicability with the Maistra site. So this is great stuff.
Martin Jagodic: Yeah. I have to say the community is great. I think it’s the best start or the highest start. How is it called? Git based CMS on the JAMStack website where there’s a list of of headless CMSs.
And yeah, we’re really happy to have this, but we are also aware of the responsibility we have to the community. [00:41:00] And also the community is great. A lot of contributors. Were happy to see that this is going to continue. I know a lot of them are maybe getting nervous because it’s been now a few months since we took it over and it’s still as it was.
But yeah, we’re working on this as much as we can. The issue is a bit more complicated than we thought, but yeah, we’re gonna get there. We’re committed.
Sam Brace: Very exciting. Very exciting.
Jen Brissman: Yeah. Anyone listening, just keep an eye out for their first release. And also, Martin, congratulations because, I think that’s just a testament to, you’ll never know if you don’t ask.
And the fact that you just asked, Hey, can we take this over? We had the bandwidth and we care to do it well, and we know what we feel like we owe to the community and we’re gonna do a good job. And the fact that they just said, yeah, here you go. [00:42:00] That’s really cool. That’s awesome.
Sam Brace: So Martin, before we break away from the project, is there any final thoughts you have about anything that you say let’s say that you have a developer that’s hearing this conversation, we’re like, okay, great. I know that there’s an open repository, there’s ways that I can easily implement the areas to this. What are some recommendations, any first steps, any best practices that you’ve had with working with this overall stack when it comes to content publishing?
Martin Jagodic: Yeah, I would say. Find the problem that you have and then search for the solution and try not to go with the, maybe at the most mainstream solution.
Because today there’s a lot of, I think JavaScript frameworks in particular, and JavaScript based generators in particular. Generating a lot of traction, but that’s not necessarily what you need. So, for a website like this [00:43:00] that doesn’t use like loads of JavaScript. It does. It does actually, there’s a lot of Vue behind this.
But for the core purpose of like having pages maybe look for a solution that actually builds HTML pages and that’s what Hugo does. And also Git based CMS is something to consider with like small to medium sized projects. Because your content is stored in your Git repository and you can easily modify it.
You can bring in a CMS that’s free to use open source. It’s really easy to install. And I think this setup has easy entry. So there’s not a lot of traction to use it. So yeah, maybe this [00:44:00] demo repository that I made is gonna help someone. But yeah, if anybody has some questions, they can also add me on Discord and ask questions there, or if they’re interested in contributing to Decap.
They can join our Decap discord server, or just, write on GitHub issues or discussions.
Sam Brace: When you, you answered the question I was gonna ask you. I was gonna say how do people get ahold of you, Martin? If you have additional questions, but you did it very well. Where I can see here on your GitHub main profile, you can see here that you have links directly to Decap.
You have areas to the overall projects you’re working on. You have links to your LinkedIn, your overall. So it seems like if you, if people find you on GitHub and they point to the project that we are showing in today’s episode, we have plenty of ways to contact you and I’m really appreciating that you’re willing to talk to developers if they have additional questions too.
So that’s wonderful. [00:45:00]
Jen Brissman: Yeah. And just if anyone doesn’t know Martin’s discord handle, it’s his first and last name. No numbers or characters or anything like that. First and last name.
Sam Brace: Perfect. Perfect. Perfect. Martin, thank you again for being here. This is, this was wonderful and I can’t wait to see what you guys are up to at decap and stay in touch.
Martin Jagodic: Yeah, it’s been a pleasure. And keep up the good work with the podcast.
Sam Brace: Wonderful.
Martin Jagodic: I didn’t know it before, but now I’m a regular listener.
Jen Brissman: Oh, good. So glad.
Sam Brace: Thank you, Martin. So, Jen.
Jen Brissman: Yeah.
Sam Brace: I wanna ask you, what’s your big takeaway from here? What do you, what stood out from our conversation here with Martin?
Jen Brissman: Yeah. A lot of things I think, obviously we talked a lot about Hugo and I was joking that it sounds like an advertisement for Hugo, but it’s just really encouraging because, there are a lot of static site generators out there, besides [00:46:00] Eleventy, you mentioned a few, and there’s Astro, there’s Pelican, and there, especially because I think a lot of developers go with what they know, and as we talked about on the web, on the episode it’s okay to go with what, it’s not lazy.
It’s what works. But I think I would hear, oh, Hugo, that’s with Go. I don’t know Golang. I’ve never worked with that and I, I wouldn’t gravitate toward using it and trying it out. So I think a big takeaway is that Hugo doesn’t, you don’t need to work with Go previously and there might be other static site generators out there that you might think there is a barrier to entry that there actually isn’t.
So I thought that was a cool takeaway for me.
Sam Brace: No, absolutely. And you are right about that for sure. And I think one thing that was also really great to see is just how easy it was to be able to publish. I think.
Jen Brissman: Yeah.
Sam Brace: It shows that what Netlify did develop with the Netlify CMS, and what it’s becoming when Decap CMS now. Showing how easy it is to be able to publish through overall Git, is awesome and he makes a really excellent point [00:47:00] that the incorporation of just being able to render HTML, Markdown in that case, being able to easily create that type of content.
It does work very well for, as he says, small to mid side projects. So it is something where I think this is a really nice package that he has gone and developed that makes it very easy for any developer when they’re trying to say we have a way to create a content authoring format for overall teams to be able to do.
Jen Brissman: Yeah.
Sam Brace: This is a great mix. So I was really proud to see what Martin and the team have pulled off, and of course they’re using Cloudinary perfectly, so I’m excited to see that too.
Jen Brissman: Oh yeah. I mean, he really found all the best transformations and just really great use case in general.
And I also just really when we were talking about Decap and I know I mentioned it before, but really the initiative to reach out and just ask, “Hey can we take this over?” And when we were talking to Martin earlier, he said even when he was learning to code when he [00:48:00] decided to go into it, it was, he was building a website for his band.
And just decided okay, this is something I wanna do. And I don’t know, I just think that a lot of developers take initiative and and play around and figure things out and we didn’t even know when we asked Martin that he doesn’t work with Go regularly. He just works with Hugo and just it’s inspiring to hear that and just any developers listening, just ask questions, poke around. It’ll pay off.
Sam Brace: Yep. I definitely agree with that and I can’t emphasize enough, take the chance to go check out the repo that Martin has gone and developed online for his GitHub repository. Of course, this will be linked in the show links, but of course, it’s also his main name and has links to many awesome repositories as well as many of the links on how to contact him.
On top of all of this, of course, if you liked this episode, and hopefully you did, then go and check out more of ’em. They’re gonna be always at cloudinary.com/podcasts. You can see that we have fantastic content from [00:49:00] developers for over two years now being published in this space. So plenty of episodes to check back into and learn from the best and brightest in the overall development field or those that were just emerging into the field trying to understand how to properly work with images and videos in their products. And lastly, but not indicating any type of priority, it is to also say that our Cloudinary community is a great place to continue the conversations that took place in today’s episode. So if you have questions about certain static site generators, some of the transformations that were covered, Anything between working with images or videos.
There was a lot of things that we did cover here today. Make sure you’re checking that out at our Cloudinary community to talk with users like you. That’s gonna be at community.cloudinary.com. So on behalf of everybody at Cloudinary, Jen and I included, thank you for participating, being a part of this DevJams episode of this here today, where we will continue talking with developers who are doing [00:50:00] interesting, innovative, inspiring things with images, videos in their projects.
Take care, and we hope to see you at the next one.
2023-12-18
Exporting 3D Objects from Blender to Cloudinary for Optimized Web Delivery
Blender is one of the most widely used software tools for modeling, animating, and rendering 3D computer graphics. And thanks to Anthony Datu and his new Blender add-on, it is now possible to easily export these files into Cloudinary! Anthony’s work extends the 3D creation pipeline for all artists and associated organizations, allowing for Cloudinary-optimized images to be rendered from the files for placement on websites, mobile applications, and more. And thanks to Cloudinary’s Product Gallery, it is easy to display the 3D model, letting users view and interact with it online from multiple angles. Come join this conversation with Anthony and Cloudinary’s Customer Education team to see how he built the add-on, and learn how you can start using it in your upcoming 3D projects!
[00:00:00] Welcome to DevJams. This is where we talk with developers who are doing innovative, inspiring, interesting things with code, and typically doing it with images and videos. Typically, also with Cloudinary powering much of the development efforts that they’re taking. My name is Sam Brace. I am the Senior Director of Customer Education and Community at Cloudinary, and I am so excited for this episode because, in this episode, we’re looking inside rather than outside, we’re talking to someone, Anthony, who is one of our developer support engineers, who has built an amazing project being able to link Blender, which is for those that aren’t tied to the 3D modeling space, one of the most ubiquitously used pieces of software when it comes to being able to create 3D models and [00:01:00] being able to use those in many different types of applications, such as movies, gaming… but he’s found a way to take those 3D models and easily export them from Blender over to Cloudinary. So you can use them for web and mobile types of purposes, such as turning them into images, being able to display those in product galleries and even more. So we’re very excited to be talking to Anthony about the work that he’s done to be able to really bring in a lot of use cases that are in the 3D space and bring those into web delivery and product gallery purposes for all sorts of types of users and buyers.
Joining me for every single one of these episodes is Jen Brissman, and Jen is a technical curriculum engineer here at Cloudinary, so if you’ve ever experienced any of the Cloudinary Academy courses and the workshops that we put out as well, of course, as the podcast that you are listening to right now, you have probably gone through something that Jen has helped to create.
So, we’re very happy to have Jen here as our [00:02:00] co-host for this episode. So Jen, welcome to the episode.
Jen Brissman: Hey, happy to be here.
Sam Brace: So Jen, a little bit of your personal take on this. Why are you excited to be talking to Anthony here today?
Jen Brissman: Well, in addition to the fact that Anthony is one of my friends at Cloudinary I’m happy to have him on here because we haven’t had an episode focusing on 3D before, and this feels like a new concept, and I know I’ve learned a lot just getting ready for this episode. So I’m just excited for the topic in general.
Sam Brace: Excellent. I am too. And you’re absolutely right. This is one of the first times we’ve really broached 3D as a concept within this podcast. So I think it’s for anybody that’s really trying to understand what the space is about, or maybe you already do know what the space is about and maybe are understanding how Cloudinary plays in this space. This is definitely a good primer for both of those use cases excellent point. Jen.
Now before we bring in our friend Anthony, we do wanna indicate that this is a DevJams episode, as you know, but this is a [00:03:00] DevJams episode that, of course, is one of many. We have plenty of episodes, including ones that have to do with topics about our various SDKs or APIs, ways that people have been able to build lots of types of integrations with certain programs or plugins.
And all of these are available at cloudinary.com/podcasts. So take the time to look through all of the various libraries. We literally have years of content available for you within this overall space. And I will also say that the conversations about these episodes are absolutely able to be had at our overall Cloudinary community.
So that’s gonna be at community.cloudinary.com, and this is where you can go and talk with other Cloudinary users if you happen to be one yourself, and hopefully you are, to be able to have them answering questions about things that they’ve come across in their own projects, maybe even dealing with 3D.
So definitely some places to go before we start our overall conversation. In case you’re interested in starting [00:04:00] to say, is this the first time that Sam and Jen have talked about development topics with developers? Not quite, let’s go in and bring in our friend Anthony, and start talking about all things 3D.
So Anthony, welcome to the program.
Anthony Datu: Hi Sam. Hi Jen. Thank you for having me.
Sam Brace: Wonderful. Anthony, I know the amazingness that you are. So tell us a little bit about that though. Tell us about what do you do at Cloudinary? How did you come to Cloudinary? The work that you do.
Anthony Datu: Yes. I joined Cloudinary a little bit over a year ago almost two years now.
But I am a developer support where the day-to-day task is to find solutions for our enterprise customers as well as the free tier customers. We are a heavily API first SaaS product. I enjoy it every day. [00:05:00] But yeah that’s basically the gist of it. We do have a lot of freedom in terms of what we can do and building internal tools within the company. Yeah.
Sam Brace: And so then one thing that of course when you’re working with customers globally, you’re working with customers that have unique codes. We work with many different SDKs and frameworks and languages. You’ve probably encountered some that started the efforts of this overall project, which was being able to start working more in the 3D space Now, How did this ultimately come about? Was this a support ticket? Was this a customer inquiry? Was this just your own imagination trying to figure out how to connect Cloudinary to Blender? What anticipated this project?
Anthony Datu: Yes. It’s a little bit of both. We have had quite a few tickets regarding about 3D inquiries. I do have a little bit of thing [00:06:00] in me that I would like to see what the 3D is all about.
Plus I do have a 7 year old son that loves Roblox and Minecraft, so, I showed him what is the Roblox studio, so instead him playing just the Roblox, I make sure that he creates stuff. So that’s one of the things that, that drives me into creating a 3D model.
Sam Brace: Absolutely. And that’s, it is nice that you’ll be able to blend things that you’re finding professionally, personally, and being able to benefit from this. So, I’d love to know more about Blender. So, tell me about this overall program. For those that aren’t familiar with it, I’m sure those that are tied to the 3D space are like, yeah, you’re telling us about something we already know about.
But for those that don’t know, what is Blender and also, why did you decide to start taking the efforts for building your plugin with this particular software?
Anthony Datu: Like what you mentioned earlier, Blender is a [00:07:00] ubiquitous program for 3D. It’s free and open source. They have tried an enormous amount of improvements in the last couple years since, version 2.8.
Now they’re in version three or above. But I find it appealing that it’s royalty free. And it’s very easy to to create an integration with Blender and it’s even more easier to create integration with Cloudinary. That what brings me to, creating an integration with with Blender and Cloudinary. But, Blender in essence is a 3D modeling application. It has a shading application it has video editing capability. You can do animation on [00:08:00] it. So it’s really a wholesome, a lot of different kinds of features in just one application. So it’s really awesome.
Sam Brace: And I think what was smart about what you’ve done is that from what I know and from what you just said, is that Blender is used by many people within the 3D modeling creation space, so if there is a place to build a plugin to help the most amount of users, it seems like blunder was just a natural choice.
Anthony Datu: Absolutely. I agree with that statement. Like what I said it’s a free and open source, you as a student, you didn’t have to, go in a way to just download a pirated version of a software. You have it for free, basically.
Sam Brace: Exactly. Which is good. It’s absolutely good.
Anthony Datu: Yeah. Exactly. Yeah.
Sam Brace: So tell me [00:09:00] about what the goal is for the plugin. So if I understand it correctly, it’s where you create something in Blender, some type of 3D object that you want to have, and then what does your plugin do with that object at that point?
Anthony Datu: Yeah, so the plugin in itself would eliminate the hassle of. The 3D modeler didn’t have to go through the file system to to bring about all the necessary pieces that what makes the 3D model it is for example, he didn’t have to find and look for where is the the textures the GLTF file, the bin file in order to package it into a ZIP file and then upload it to a cloud storage application, right?
So [00:10:00] this Cloudinary exporter will do it for you. So it take, I believe it takes away a lot of error prone steps and it just, pushes to Cloudinary directly, the whole scene including the animation.
Sam Brace: Excellent. Excellent. Jen what questions do you, is there anything you have for Anthony before we pop over his to his screen and have us walk us through this?
Jen Brissman: I guess the thing that I was wondering is was there a real pain point that this was solving for or were you just thinking, I’d like to take a bunch of things and make it happen all at once? Was there, were there errors that you were seeing that you were trying to get ahead of, or you were just trying to, in general, make a convenient…
Anthony Datu: Correct. Correct. So if you go over some of the steps that we have in Cloudinary, in order for us to upload a 3D, you need to be able to package [00:11:00] certain files within the 3D object that necessary. In order to display the correct texture, whatever that 3D model consists of and I felt like if this is not done correctly it’s error prone. I know in my personal experience, I have quite struggled, where in the hierarchy are we placing those files? Stuff like that.
Jen Brissman: Yeah. Okay. Let’s pop over and see the functionality demonstration of what you’ve built. So everything that we’ve talked about, it’s real. Let’s see it. How does it work?
Anthony Datu: Cool. Can you guys see my screen?
Sam Brace: Absolutely.
Anthony Datu: Okay. So here we have Blender. Let’s say that I’m working on a 3D object like this Chuck Taylor, very classic Chuck Taylor converse. So I, let’s say that I created [00:12:00] an animation to display the product, to rotate the product.
So easy enough if you have installed the plugin, which is included, the steps is included in my repo. That will give you a Cloudinary panel, and you just fill up a couple of, a few fields like the cloud name, the API key, the upload preset the public ID, and the preferred tags that you want.
Then if I push the upload button, What we should be able to see here. It takes a minute because this is a high quality 3D really high resolution 3D object.
Sam Brace: Absolutely.
Anthony Datu: Here in the info window panel you can see that we [00:13:00] got the response from the Cloudinary API. It’s saying here that this now has the public ID of blender/chucktaylor_devjam, and all the other information here, such as the Secure URL and the URL. Now, if we hop over to so what I guess I’m jumping ahead way too ahead. So what it did is it, Zipped the necessary file into a single file and it upload that to Cloudinary.
Sam Brace: And then, so at that point, so we can see that it’s, so now everything that’s there, so as you said, all the texture files, all the things that make up this, it’s all zipped together.
It’s all been delivered into Cloudinary at this point. And then at that point then it’s an asset. So…
Anthony Datu: Correct.
Sam Brace: [00:14:00] Before we jump into the code that you’re showing here on the GitHub, I’d love for you to pop over to your management console here.
Anthony Datu: Sure.
Sam Brace: And be able to show Hey, it’s real, it’s there. Okay, there it is.
Anthony Datu: Yes.
Sam Brace: Okay. So it’s, you can see Chuck Taylor DevJams, and we can see that it has an asset type of an image. And it’s also a GLTZ. So it unzips as it comes through, if I understand that.
Anthony Datu: Correct. Yes. So it recognized it’s a GLTF format. That’s the format that I chose because it’s a royalty free format and it’s well supported by Cloudinary.
So from a dev support perspective, I love the format, the fact that we can go in and dig into what makes a GLTF format this.
Sam Brace: Of course, I think we all are aware that this is not a web friendly format. I know you’re showing this in a web browser right now, but GLTF, GLTZ, 3D [00:15:00] formats are not web friendly by design.
Anthony Datu: Correct.
Sam Brace: But from what I, I know you could easily make this web friendly thanks to Cloudinary now.
Anthony Datu: Yes, so you can display your 3D objects using the product gallery widget as well as the AR view. I believe that we do have a AR view widget.
Sam Brace: Well, you can also change it into any type of image, right? So you can take to make it a PNG, a GIF, a JPEG, whatever you need it to be just from there.
Anthony Datu: Yeah. So, if I copied the the URL just by clicking this copy URL icon, and now I can, what I can do is I can use one of the formatting transformation. Now, mind you that this is a very high resolution image.
That’s why, and this is the first time that we’re generating it. That’s why [00:16:00] now that we do have the PNG format of that 3D model.
Sam Brace: Yeah, and there’s so many different types of transformations you can add to this of course too, because like we have an effect called camera, so e_camera, and we’ll show that later in this episode. But it’s where if you wanted to at a specific angle or a specific type of shot, then it allows for you to do that. Where let’s say that you were trying to show the soul of the. Converse and you said that’s what people wanna see, or maybe it’s the way it would look from the front rather than the side. You can play with those different angles, but still have it be completely web friendly. So you can be able to take that 3D model, use stills inside of the product gallery, and then even on top of that, as you said, you can display the 3D model by itself with our product gallery as well. So it’s, there’s lots of cool things that you’re able to do here, but pretty fast, pretty seamless.
Anthony Datu: Yes.
Sam Brace: So how did you make it all happen? So this is probably a good chance for us to take a look at the code. And I [00:17:00] think one thing that we were talking about yesterday that was very exciting was the fact that you wrote this all in Python, which of course is a language that many people use.
Anthony Datu: Correct. Yes. This is pure Python. I just basically use Blender class inheritance. So, if we go to the repo it’s just a one file of Python code. It’s 241 lines. Couldn’t get easier than that, so as many Python scripts, it starts with the the main statement, here.
So it jumps into register. So this is the register function. What it’ll do is [00:18:00] it will go through, it will loop through the array of classes that I define up above, right? So I do have the Cloudinary property class the panel and the operator, and it’ll register the to the Blender environment.
It’s under utils and register class. And it’ll also register my cld props or property that I custom define. So, if we go up to the code, so this is the cld property or the Cloudinary property where I define the cloud name, API key, upload presets. Public id and tags, [00:19:00] and that in turn gets used in the panel. So that panel is what creates the the UI that you saw earlier. So, when I inherited the the Blender type panel class and I define the draw, it will get called in the Blender and it will render that that panel with the API key, the layout, or the fields in that panel, and the upload button that you see down below.
What I did is I call the layout operator function, and I use the Cloudinary operator ID. This Cloudinary operator [00:20:00] ID is defined over here under the class Cloudinary operator.
Sam Brace: Got it.
Anthony Datu: So that label, the bl underscore label, that’s what gets labeled in the button.
Sam Brace: Now, one thing that I’m seeing here, cause if you’ve used Cloudinary before or you’ve listened to anything that we’ve put out before, we’re always talking about Cloud name, API Key and API Secret as the overall environment variables that you need to pass to be able to link Cloudinary to, let’s say your a ap, like essentially to your development environment or to a program or a plugin. But, I’m seeing there’s no API secret here. So, how does that work? And also why did you maybe get around that?
Anthony Datu: Yes. So what I defined here is an upload preset with unsigned upload. My thought process to this is [00:21:00] that let’s say that I am a 3D modeler that I work as a freelance or agency and they have subcontracted – an enterprise customer, a well known brand, subcontracted a 3D artist to create a 3D model. And this is one way for them to ask the 3D modeler to upload the 3D model that he or she created to their Cloudinary account without giving out the API secret. So unsigned upload will allow our customer to let an upload through their account without giving out the API secret.
Sam Brace: I think that’s huge. It’s something where that’s a real use case where if [00:22:00] you have a team that’s creating 3D content and you need them to just be able to quickly get things into their Cloudinary account, you don’t need to give them a user seat because they aren’t gonna be needing to upload it through the DAM interface or through the user interface by any means.
But, it’s just simply where we need to be able to pass it from their program of choice, and as we said, Blender is probably what they’ll be using. If not, they’re at least familiar with it, probably if they’re in the 3D space. So it’s, I think this was smart. I think it was really smart to do that.
Anthony Datu: Oh, thank you. Yeah, in addition to that so the plugin also allows you to tag the 3D model, which on the receiving end, if you’re the, if you’re the account owner, in Cloudinary, you should be able to see, or you should be able to search with the search tag.
Sam Brace: Let’s see that because you did tag something, we uploaded something. So is there a way we can pop over and take a [00:23:00] look at that?
Anthony Datu: Sure. Here this is the 3D model that we just uploaded. You can navigate to metadata data icon, and you can see the three tags that we defined. So if we head back to Blender real quick that matches our tags.
Sam Brace: And then if I know something about Cloudinary, I know that we have awesome search capabilities, so that’s where then if you need to find things like this through our search API or through the management console and have it where it’s showing it through the search, you could easily pull up everything that has, let’s say Chuck Taylor or Red Shoe, and it could be images, videos, or files like this.
Anthony Datu: Sure, yeah. Yeah. Let’s do a quick demo. Go. There you go.
Sam Brace: Yep. It’s nice and simple.
Jen Brissman: Yeah. And this is a really important feature because with e-commerce customers, they’re, they have a lot of [00:24:00] assets that they’re working with and tagging is really important. And of course for 3D, that goes right into the product gallery.
And this is an important use case. So I can’t imagine without the tags, it would be nearly as helpful of product that you’ve built. So awesome work there.
Anthony Datu: Thank you.
Sam Brace: The other thing I wanna unpackage here is the upload preset because as we mentioned, that’s one of the ways that you’re able to avoid having to deal with API secret details cause it’s an unsigned upload preset. But, is there a way that we could take a look at that inside of your console and explain like how that’s working within this overall upload.
Anthony Datu: Okay, let’s go through the settings.
Sam Brace: And as you can see, so all of our upload presets as Anthony’s gonna be showing, they’re gonna be inside of the setting section of your system. And then all you’ll have to go do is go to the upload section and then I’ll show you all of the presets you’ve created, including the one that Anthony’s gonna show here.[00:25:00]
Anthony Datu: Okay. I’m sorry about this.
Sam Brace: You’re good. It’s fine. Okay. Oh, there you go. Yeah.
Anthony Datu: Okay. Okay, let’s go to the upload preset. I believe I named it Blender 3D. Here we go. So if we come in there, and this is how I define an unsigned upload.
Sam Brace: So, really it’s just that simple. So it’s where you’ve defined the name, you said that you want it to be there.
And when I looked at it, I know that we are, we can analyze things quickly because we work at Cloudinary, but it’s where there’s not much else that you’ve added to this. It’s strictly saying, give it a name, state, it as unsigned and then you can pass it through, and that is indicating that as long as you have the right API key in cloud, then it knows that you’re probably authorized to use that upload preset.
Anthony Datu: Correct. And [00:26:00] the only thing that I added is just where to upload it what folder. They could be organized that way as well.
Sam Brace: Yeah, absolutely.
Jen Brissman: And so how are you allowing people to define public IDs? I noticed that you didn’t define that in the upload preset. So in Blender, is there a field for people to enter the public id? And that’s something they’d manually create?
Anthony Datu: That’s that’s correct. If we head back to Blender this is the public ID field that they can define.
Jen Brissman: And if they weren’t to put anything in that field and click upload, would Cloudinary just assign them a random 20 character public id? Or have you tried that or have you always put in a, have you always…
Anthony Datu: I always put in.
Jen Brissman: Yeah I bet, unless you’ve required it, my guess would be that you would get a random public id.
Anthony Datu: Yeah. Yeah.
Jen Brissman: Just a guess. We can test that later.
Sam Brace: But the good thing is that it like, [00:27:00] because you are defining the public id, and as we’ve showed, that’s essentially what we use as the file name for when we are doing some form of web delivery to it. You can make it whatever you need it to be. And also you can always change it later too. But if you’re saying just review the upload process, so Jen, to your point, like if we did randomize, you’re like, oops, I forgot that field. Then you can always go back and fix it later on.
Anthony Datu: Correct.
Sam Brace: That’s great. This is really great. So looking at this, Is there anything that’s also, that we haven’t touched upon? Like we were saying oh, I forgot to mention about this aspect of it or that aspect of it.
Anthony Datu: Yeah, being a dev support, one of the reason why I gravitated towards the GLTF format is that if we can go through the file system and go to the chuck_taylor_devjam.
Sam Brace: Okay. [00:28:00]
Anthony Datu: And list the files. We can see that there are three files. So, we do have the materials files. That will be the, what we can see basically the skin or the texture of the 3D. The GLTF file, actually, it’s just a simple JSON file. We can basically interrogate what is this 3D model is using as a material, right? We can see that it’s actually defined just a text.
Jen Brissman: And is the ability to inspect this JSON file the reason why you gravitated toward a GLTF file instead of a GLB binary file?
Anthony Datu: Yes. That’s that’s as simple as that. [00:29:00] It just, because I can interrogate more and I can readily understand in plain English what consists of the 3D object.
Jen Brissman: Yeah, and I think it’s super interesting if you pop open one of these files to look at the skin or the layers in the two dimensional view. I think it’s super interesting. I haven’t worked with 3D that much, and I’ve enjoyed getting to see this aspect of it. So these three files that we just saw in Anthony’s terminal, now we have it in his finder and wow that’s crazy. It blows my mind that’s the file that creates this awesome 3D object that we’ve been looking at for this episode.
Anthony Datu: Yeah. Correct. So I don’t know how the 3D model or application does it, but I know it works.
Jen Brissman: Yeah. Really cool.
Anthony Datu: Yeah.
Sam Brace: That is awesome. That is very awesome. And of course the final output for this thing is that we, you’ve built this amazing exporter to be able to link Blender and Cloudinary [00:30:00] together. But the nice thing that you’ve also done, at least I think it’s nice, is that people can access this today where I know that you have this available inside of the Blender market, so that way people can go ahead and easily add it on to their Blender instance and start using it. I think you only have it as like a dollar purchase, so hopefully it makes me a little bit of money on the side.
Anthony Datu: Yeah. Because of the type of account that I have in the Blender market I wasn’t allowed to publish it as $0.
Jen Brissman: You had to put a certain amount.
Anthony Datu: Yeah, I had to put a certain amount at the minimum.
Jen Brissman: Yeah.
Anthony Datu: But, I did link my GitHub repo they can download this repo and then load it from the preference add-on to the blender.
Jen Brissman: For free.
Sam Brace: That’s perfect. And look at that. You [00:31:00] have something for free. In my opinion. People should be able to pay a little bit of money for it. Buy Anthony a coffee. But I’ll show it real fast, so you guys can see it in the marketplace here, but, so this is the so Blender market, the indie market for Blender creators, and this is the overall exporter that we have here, that if you wanna be able to download this and use this right away. Similarly, if you wanna just be able to grab everything from the GitHub repo that’s available for you as well. And one thing that I liked that you also did here was that you have a link to a code sandbox that also shows off the 3D modeling that we have within the product gallery as well.
Anthony Datu: Oh yeah.
Sam Brace: This is being able to explain all those details on how you can have a workable 3D thing where you can move it around, you can tweak it. All the things that you’d wanna be able to do to the 3D model, but within Cloudinary product gallery. So lots of really cool things you provide here, Anthony.
Anthony Datu: Thank you. Yeah.
Jen Brissman: So Anthony, I had a question for you. We know why you built this and we know what pain points it addressed, [00:32:00] but, is this part of your typical work at Cloudinary or were you encouraged to do this by your team? Or is this something you did outside of work? Or was this just something you had the freedom to do as a dev support engineer at Cloudinary?
Anthony Datu: Partly because I do have a freedom to explore different ways of creating tools. But, I see more and more enterprise really large brand enterprise are looking into how would they have 3D objects in their in their e-commerce store.
I think it’s a little bit of both that, I think we need to have some sort of a tool to aid, or cater, our 3D artist.
Jen Brissman: Yeah. No, for sure. Yeah, that makes so much [00:33:00] sense. I just was impressed that this is something that you can do at Cloudinary as part of your job that might not have been in your job description when you first applied to Cloudinary.
You might not have known that you’d be making something like this, and it makes me excited to hear about what you might make in the future or what other people on your team might make in the future as a part of their work at Cloudinary.
Anthony Datu: Yeah. Many of our colleagues here at Cloudinary, they build tools.
So they we do have the media inspector, and I’m just one of the guys that, you know inspired by them.
Jen Brissman: Absolutely.
Anthony Datu: So it’s really cool.
Jen Brissman: Absolutely. And I know we have hackathons all the time at Cloudinary and there’s always a lot of innovation happening, so this seems like something that maybe could have come out of a hackathon or could have just been a project you were doing outside, but this is really awesome.
What a great way to help people.
Anthony Datu: Cool.
Sam Brace: I love it. I love it. Anthony, this has been wonderful to have you here and I think it’s great that we’re able to be able to have this [00:34:00] conversation to show these great links. And I think, Jen, you said it well, hopefully this is not the last time that we have Anthony on the program to be able to talk about the great work that he’s doing and the great work that our developer support engineers are doing as well. So keep up the great work, man.
Anthony Datu: Oh, thank you. Excellent. Jen, What’s your big takeaway from this? What stood out to you about what Anthony’s gone and done? I think just what I said that he was able to make this on probably company time is just really cool and inspiring to me.
Like when I, when I found out that he made this I had no idea, I, and I was I was just really happy that kind of work can happen at Cloudinary. But yeah, otherwise, I think we talked about a lot of the takeaways. What about you?
Sam Brace: To me, I think the thing that stood out for is exactly what Anthony was saying about enterprise moving more and more into the overall 3D space. We’re seeing so many customers, big and small [00:35:00] coming to us and saying, how do I work with 3D objects? Or how do I incorporate that into my e-commerce or into being able to show what this looks like within a certain room that would overlays like whatever it happens to be. And it’s where there’s probably a community of hundreds of thousands of 3D artists that are out there that are using Blender. So it’s where we have this now very clear path to say. If you need to be able to deliver this for web, we are seeing you and hearing you. And I think Anthony has really become the person to extend that branch to that community. So, I’m very excited by the work he’s done. I don’t think anybody maybe even realizes how powerful the work that you do is until it’s done. But, there’s a lot of power in what Anthony’s created here today.
Jen Brissman: Yeah. And when you think about it, 3D is so important as we move to online purchasing, you really need to be able to see a product at this point, a two-dimensional photo of a [00:36:00] shoe. I’m not gonna know what that looks like.
Like I wanna see every angle. I wanna see the inside. I wanna see the bottom I, and with 3D, I think companies can have a better. I don’t know. I’m sure there, there are major statistics about 3D and how that affects overall success of online and e-commerce. But, I think it’s gonna be something where going forward we don’t what am I trying to say? We always see 3D, like it’s gonna become the standard and I think there’s been a lot of innovation in this space in the last few years, as Anthony was saying. So, I think we’ll be seeing a lot more of this, and especially at Cloudinary.
Sam Brace: Yeah, and I think you, encapsulated the buyer persona pretty well is that there’s an expectation now where you’re not just showing me an image of something, maybe on a model or a nicely set studio and maybe a video of some people using it.
People want to be able to really see all of the angles for it as, as we showed [00:37:00] with the Converse, being able to see exactly what it would look like if I was able to. Flip it around and look at the soul and see how it looks from a turn angle to see what it looked like on your feet. Basically, it’s
Jen Brissman: Right.
Sam Brace: It’s where there’s a lot of benefits of being able to show something in a 3D space, and I think brands, developers, many people that are tied to websites and mobile apps, they’re starting to understand that power very well.
Jen Brissman: Yeah, the importance and how it can be tied to revenue. The ability to zoom in on the stitching of the Converse could be all someone needed to click the purchase button, so…
Sam Brace: Absolutely. Absolutely. So, one thing that I do wanna show you here, so as we’ve talked about with Anthony, that Cloudinary does work with 3D models very well, and one thing that we alluded to is that there’s many different file types. Of course. The one that we focused on in this episode is the GLTF format and when you take a look at this, you’ll see that there’s lots of different ways that you can play with this. See the different [00:38:00] types of angling, different types of effects you can apply, and our documentation team has even gone and created this nice little interactive demo that allows for you to go and play with the camera positioning of any particular 3D file.
Capture a shot. And then be able to see exactly what that would look like for getting camera angles of some of the stills that you can have within the 3D space. So definitely something that you wanna play with. Of course, we’ll have these in the show notes as well. And as we said at the very beginning of this overall episode, make sure you’re checking out DevJams in some of the past episodes that we’ve had.
So, all of those are gonna be available at cloudinary.com/podcasts, of course, also where you probably enjoy listening to podcasts as well, such as Apple Podcasts, Google Podcasts, Spotify, YouTube, and other well-known places. On top of all of this, make sure that you are checking out our Cloudinary community.
That’s gonna be at community.cloudinary.com, and that’s where you can see we can have conversations, with other Cloudinary users about images, videos, 3D, [00:39:00] and other things that are essentially affecting the way that digital media and visual media is being consumed on the web, mobile, and other places. So Jen, final thoughts, anything else before we let our audience enjoy the rest of their day?
Jen Brissman: No, just thanks for joining us and this was a lot of fun. And Anthony, keep up the awesome work. I can’t wait to have you on DevJams again in the future.
Sam Brace: Absolutely. On behalf of everybody at Cloudinary, of course, from all of us that are working on this program, thank you for listening to DevJams and we hope to have you back to hear some more inspiring, innovative, and interesting conversations with developers that are pushing the boundaries of what digital media and visual media is today.
Take care. We’ll see you soon.
2023-12-18
Elevating User Experience with Cloudinary, Markdown and Deno’s Fresh
Don’t miss out on this insightful DevJams episode that explores the intersection of cutting-edge web development and user experience, alongside one of Google’s leading experts. We are thrilled to have Adam Argyle (Chrome CSS Developer Advocate at Google) join us for an in-depth discussion about his personal website, Nerdy.dev. Adam shares his expertise in leveraging Cloudinary’s versatile capabilities to optimize and customize his image and video content. Discover how he utilizes Cloudinary’s prebuilt strings with standard optimizations to ensure fast-loading visuals and integrates Cloudinary features, such as maximum size restrictions, customized URLs, lazy loading, and asynchronous image decoding. We explore his innovative Markdown parsing techniques that transform authored paths into fully optimized Cloudinary URLs, seamlessly integrating with Preact components and the Deno Fresh framework for optimal server-side rendering benefits. Prepare to be inspired as Adam takes us on his journey using Cloudinary to further optimize and tailor the user experience on Nerdy.dev.
Sam Brace: [00:00:00] Welcome to DevJams. This is where we talk about innovative, inspiring, interesting projects that developers are building specifically when it comes to delivering images and videos a lot of times on those websites, and of course they probably are using Cloudinary for a lot of those aspects, since this is a program thats developed by Cloudinary.
My name is Sam Brace. I am the Senior Director of customer Education and Community at Cloudinary, and this is gonna be a really exciting program cause we’re gonna be bringing on Adam Argyle, who happens to be a developer advocate, specifically under the Chrome side of things, specifically around CSS. But this isn’t about his time at Google.
This is actually about the work that he’s been doing for his own personal brand. Through a URL called nerdy.dev, and he did this [00:01:00] amazing overhaul to be able to create a space for him to be able to share blog posts and other musings. But, he also did some pretty innovative things with new frameworks, new ways to be able to really push the boundaries of what’s possible.
I love the overall social networking look and feel that he did with this. And of course, he found new ways to be able to deliver images and even videos through his overall web presence, thanks to the work that he was able to do with implementing Cloudinary into his overall website blog overhaul.
Joining me for every single one of these episodes, and I’m so happy to have her here for this one, is Jen Brissman, and she is a technical curriculum engineer here at Cloudinary and working with me on many customer education focused projects. So Jen, welcome to the program.
Jen Brissman: Hey, happy to be here.
Sam Brace: Jen, tell me why are you excited to talk to Adam today?
Jen Brissman: So many reasons. I love nerdy.dev. It has such a cool look, and I like that we [00:02:00] have someone focused on CSS and the way that things look, we’re not necessarily focused on something super technical. It’s really about making things look really good in the technical ways that he did that. So happy to talk to Adam and he’s really fun to talk to. So let’s get him on here.
Sam Brace: Absolutely. And before we do so, one thing that we should always point out is that if this is the first time that you’re experiencing the DevJams program and maybe even Cloudinary, know that we have many years of podcast episodes and livestreams that we have done associated with the DevJams program, and you can find all of those at cloudinary.com/podcasts. So simply go through the list and see all of the podcast episodes that we have put out and explore. And on top of all of that, we can also see here that many conversations take place between Cloudinary users at community.cloudinary.com, and this is gonna be a great place for you to continue the conversations about anything that me and Jen and [00:03:00] Adam discussed today.
Of course, also, maybe conversations of things that got broached in previous episodes as well. So, make sure that you have that and whether you like to use the community forums or you happen to join its associated Discord server, there is a place for you to have those conversations with other users that probably care about images and videos just as much as you do.
So before all of that, and after all of that, let’s get on Adam to the program. So Adam, thank you for joining.
Adam Argyle: What’s up? What a corpus y’all have. That was awesome. Dang.
Sam Brace: Oh, thank you. Thank you. And honestly, it’s great to have you here. This is gonna be a really good exploration on a lot of different things, but I think what would be a great place for us to start at is just for everybody that hasn’t heard about Adam Argyle and get a little bit of a flavor, who are you, what are you up to? How do we, how did we get you here?
Adam Argyle: Cool. All right. I’ll try to keep it short. Been a nerd for a long time. I was a nerd [00:04:00] before it was cool, and then I dropped out. I was like, oh, being a nerd’s not that cool. Look at we’re nerdy. That’s not great. And then later all of a sudden, nerds were cool. And I was like, I’m going back to being a nerd. And I was really happy about it. I studied all sorts of things in college and high school. I’ve been building sites for 25 years. I was in like intense computer science college and noticed that no one else cared about what things looked like. And I was like I do. And I would turn in assignments and they looked good and were functional and they were all like you’re weird. And I’m like, you’re weird. Why are you so happy with the math? Why can’t you make little rock hands pop up and bounce around we’re playing a video game? And they were like, we don’t care. And I was like, dang, I care. And so I switched schools. I was even like, I was like databases and, backend was really fun. And then I went to design school where I studied web design and interactive media, 3D animation, all sorts of cool stuff. Meanwhile, while I was at art school, I was at a startup agency and we were building apps for every digital screen, and I cut my teeth building [00:05:00] everything.
I’ve built an app for pretty much every device, every screen type, even voice apps and stuff like that. And I found myself more and more focused on the user. I wanted the user to be empowered. I was the cool part about the web. The web was like mine. It was like that page showed up on my screen.
It came with some of my preferences and I wanted it to be a really beautiful. So, as I implemented other designers, beautiful designs and studied design, and then I just kept building apps and working at various companies. Found myself at Google after about 20 years. I’ve been happily here…
I started out on Google Cloud and the design systems team which by the way has like a hundred people on it just to manage the design system of Google Cloud. So if you think design systems are easy, they’re gonna save us a lot of work. Try again. They make a lot of jobs. It turns out they’re really hard.
It’s like a garden. You have to continually, look after things rot and things grow, and you have to be there with them and tend to them. These days I’m on the Chrome team focusing on CSS, UI, and Dev [00:06:00] tools. I work with a couple of amazing colleagues. I work with all the engineers. I work with the PMs, I work with the spec authors, and I’m in the middle of all this sort of synthesizing it, figuring out how to use it how to teach it.
That’s mostly what I do these days. It’s a lot of teaching. And then I can’t stop building. I’m just a crafter. I gotta build stuff. And my personal side was getting a little crusty. It’s the one that got me my job at Google. So I’d been there for, I’ve been at Google for six years now, and after about five years I was like, I should probably have a website that showcases a lot of the stuff that I talk about that seems dog foody. I’m gonna eat some dog food. And that led to nerdy.dev, the site you saw. And I was like, people love scrolling feeds. I’ll just make my own feed with my own personas. I even added a persona today. The idea came last week, but now I have an evil persona. So that’s the top post you’ll see is evil, Adam.
And what’s he gonna do next? I have no idea, but something evil and its gonna be really fun. My site, my space. I get to do my CSS my way. I get to build it my way. And I could also [00:07:00] keep rambling for a long time. So I’m gonna stop myself right there. I think that’s pretty good.
Sam Brace: It’s something that we’ve heard actually a lot of times in the DevJams program is that someone wants to re overhaul their overall web presence.
And of course, I think you did something that many developers wanna do. You wanna own that space because we’ve seen social networks come and go. We’ve seen ones rise. They allow certain types of customizations, not customizations. So rather than jumping from space to space to space, you know that everything that you want it to be the way you want it to be is at nerdy.dev.
So, it makes sense why you would do a lot of those things. But it also, we’ve seen this before where certain developers might use that chance to check out maybe a new framework or a new way of being able just, looking at fresh code, it’s, it gives you a blank canvas as to work off of something. So it seems like possibly that’s one of the approaches you took too, because.
I saw that you’re working with Deno, you’re working with Fresh, you’re doing all of these fun things with your framework [00:08:00] choices, but that was something that probably came about because you were just deciding to revitalize your overall web presence.
Adam Argyle: Yep. I’ve been building with frameworks since the frameworks got created.
And so I like to use a different one for each project. Like a couple months ago, I released a project called gradient.style, which allows you to build wide gamut, gradients. So it’s a brand new gradient, syntax. It’ll output the old and the new syntax for you. But that was built on SvelteKit.
I’d already liked svelte from a project about three years ago, and gradient.style just ended up being this, I like building tools, I like building design tools too, and I just wanted the web to have a really good gradient. Anyway, so I used SvelteKit. I’ve built things with NextJS. I’ve built things with just everything.
And so Deno was especially interesting to me because they’re on the web platform tests websites. So the every browser before they release a build, they test their code against hundreds and thousands of tests and they’re called the web platform tests. And Deno showed up in there next [00:09:00] to Node and next to other things.
And I was like, Denos here. Deno is implementing web standards and they’re crushing it, and they’re a tiny version of Node with TypeScript outta the box. And I was like, and it and it renders at the edge, right? So it’s got all these kind of cool advantages and. I was immediately in love. I was like, this is like all the fun part of node where it’s JavaScript very familiar with the MPM package registry, all sorts of cool stuff there.
But, I get to be in this more minimal scenario in this modern distributed sort of architecture. And then they also came out with a framework for themselves called Fresh, which is a Preact, very minimal framework, which I’m a very minimal enthusiast. I like to build things myself so that way I understand what’s going on.
So they gave me that and I was like, I’ll give it a shot. And it turned out to be stellar. I’ve had a great time in Deno and Fresh, the deployments are sometimes seconds, so I’ll push code to GitHub and I’ll go check production and voila, there’s my site. It rendered on demand. It does SSR yeah, here’s [00:10:00] fresh.
It’s really rad. And I’ve had a blast. Yeah, every new project I like to pull in a new framework, expand my repertoire and places that I’ve been and things that I’ve seen. It just makes me a better coder. Plus, I get to feel like I’m relating with what other people are probably building with.
And yeah I think it also shows some clout that I’m not just here in a little silo, shouting out about CSS and how you need to architect things. I get to go try these things in the same space that they are and feeling the same pains that they are too. And I don’t know, it’s just, I can’t stop doing those things.
They’re just a part of me, I guess.
Sam Brace: And I think it definitely shows, I love the growth behind that. Like it’s something where, As we know, there’s, as you pointed out, there’s new frameworks that pop up all the time. There’s new programming languages that become the new hot thing where people want to learn these things.
And knowing how, you know the pros and cons, reasons why you might want to use it, the reasons that you don’t, it makes for much more nuanced conversations when you’re in [00:11:00] education role like yourself. So, I think it’s really astute that you decide to jump in, try something out and use different projects. I love the fact that you tried Svelte for something else that was a passion project.
So, there’s really cool things that you’re doing with that. So that’s very good advice, I think, for any developer to be able to take.
Adam Argyle: Thanks a bunch. I always felt like a senior developer has experienced more bugs than you, and that’s they’re still writing bugs. They just have seen more of them, and so they go, oh, wow, that happened to me last year.
I know the fix, and they do it. So that’s one attribute of a senior, and the other one is trade off management. They know what’s at the end of all these different roads because they’ve walked down them. So I’m gonna keep walking down roads and keep collecting those experiences cause I feel like that’s what makes me a stronger engineer over and over again.
Sam Brace: Absolutely. Absolutely. Now one of the things that you also did with the overall rebrand or rebuild of nerdy.dev was of course you decided to start finding new ways to work with images and videos. And [00:12:00] because of course it’s a being a very well-designed website, it has really fun imagery as we pointed out.
Like you have a great icon, which is the skull with the flipped lid, and you’ve got all sorts of stuff going on there. So you want that to look good. You want that to come through quickly. So it looks like you chose Cloudinary for that. What were the reasons that led you down the path to choose Cloudinary?
Adam Argyle: Yeah, I’ve used Cloudinary in the past, so when I was at Deloitte when I was at agencies, we’d use Cloudinary. It’s just nice to, there’s many niceties, but one of the main ones is and then I’ve also used Eleventy and all sorts of other build systems where I would build out my images. I’ve been in the Squoosh CLI and the Squoosh website, just exporting all these different versions, handwriting the source sets and picture elements, and it just became a big pain and all of it, again, for me, it’s like I’m a very user focused builder. I want the user to have a good experience. And so images and video end up being this humongous asset that you download in order to experience a site.
And as a author, I want to upload the [00:13:00] highest res image and on the fly give people all the little ones. I think my first and best experience with Cloudinary was with a startup that I was at called Lively. And Lively was a, we would record the live show that you were at all the audio right off the soundboard, and by the time you were walking out of the show, you could buy the show that you were just at for five bucks.
Sam Brace: That’s pretty cool.
Adam Argyle: And had, it was super cool. I saw so many shows. But the album art and all this stuff was really hard to deliver across all these platforms. This was a while ago and Cloudinary made it really easy so that I could again, just upload one high res asset from these artists cause it’s a pain getting images from clients, right?
I get one of the best that I could and then I would just downscale it and fit it to each user’s device and then those get cached on the fly and all subsequent pulls are super instant. So it’s just superpowers galore. And so when I’m on my personal site, I was like, of course I wanna do that. Managing images and media and video is not easy.
People are like, oh, you just download an image, you just put one in [00:14:00] your pictures folder. Oh, I have an assets folder and I’ll just serve that. And that is totally fine and that does work. But as you dig into sort of these user necessities and moments that they have with various things, whether it’s like I have GIFs that only play three times, right?
I think that’s really important cuz it can get annoying if they’re sitting there doing that over and over again. I have client headers are sent that send your view port that you’re viewing it on, so that I’ll never send you an image bigger than your view port. Like just the amount of little things that you can do to tweak that asset for that user is bonkers.
And y’all give me an API into that. I just build strings. I do it all on the server side so that, by the way, by the time the user gets it, it’s just html. I don’t even use JavaScript to serve any of my images. I did prototype that at one point I was using the LQUIP images, and then I was showing the blurry one and then loading the big one.
Anyway, so there’s just so many niceties to using something like Cloudinary, right? You get CDNs at the edge. Transformations on the fly that get cashed. The list just goes on, [00:15:00] and of course I was gonna use it again. It’s pretty much top notch for doing this sort of work as long as you can read the docs and sift through and formulate these strings and build them. And yeah, that’s what I did in code. That’s what code’s good for. You’re like, “Hi code. This is confusing. I’m gonna teach you so that you do it for me”. Its very good at that..
Sam Brace: No. Absolutely. Absolutely. And we’re showing on the screen here various parts of nerdy.dev, and you can see that we’ve got videos that you’re bringing through for different things that you’re showing.
You’ve got pictures of yourself, you’ve got various, but all of these images, all these videos that we can see that are part of this overall scrolling feed that are here, they’re all coming from Cloudinary. And when I take a look at some of these, so if I just pull up our handy dandy media inspector let’s take a look at this user centered UI plug that you have here for your Google IO speak. You can see here that yes, sure enough, this is coming from Cloudinary and you can see all of the transformations that are being brought through like f_auto and q_auto and [00:16:00] w_auto. there’s a lot of fun things that you’re putting into this. So I think this is definitely showing that it you’re fully embracing the whole process of images and video through us, which is a great thing to see.
Adam Argyle: There’s even more, if you click that image, it should go into a modal view.
Sam Brace: Oooh
Adam Argyle: Thats a separate path. Stashed on the element is the full URL, the one that’s unfettered. So you should media inspect that one because that has less constraints applied to it. It’s yes, you invoked the large image here is, I think it’s still using client headers and stuff, but.
It’s here’s the big one. You paid for that one, when you clicked it, I mean you didn’t pay for it, like that was more to download than the initial one. It’s higher quality. You get to zoom in on the details. Ah, see one like that, you’re like, that’s nice to be able to zoom in on the details.
Sam Brace: Oh yeah. This is fantastic. Yeah. This is very good work and I like that you exposed a little Easter egg that I didn’t even know existed. I’ve been combing your website for a while here [00:17:00] and that’s neat. So I was just very satisfied to look at how nice it looked just in the scrolling view. I didn’t even think so.
Jen Brissman: Adam, I, yeah. Sam said, I love the look of your website. What gave you the idea to make it look like a social media feed?
Adam Argyle: Yeah. It was a lot of observations. So a lot of people been making new portfolio sites. As much whimsy as I generally like to build I’d build tools and I build whimsy.
I was like, for my site, I I was like, everyone’s just scrolling cards. And I ultimately wanted a kind of content centric site. I knew I was gonna blog and I knew I wanted to make posts. They’re called notes in my code, but like the one at the very top where I’m like, evil Adam, or whatever.
That was just a notes, not a blog post. And you can go to the detail and it’s it’s just a note. The idea was like, people are scrolling a feed, they just wanna see a feed of cards. And so someone can come to my site and they’ll be like, don’t care. Don’t care. Oh, that one I care about. And then the sidebar was just like Twitter and I’m like, there’s so many [00:18:00] people on Twitter. There’s probably a lot of people coming from Twitter to my site. I might as well just make it really familiar that way. That way there’s not a lot to learn. I can keep it really simple. That was the inspiration, just observing the way that people are consuming content these days.
I wanted to give it to ’em in a nice, familiar format, but also do it my way, which is, so there’s a lot of Adam-isms and they’re like, did you notice as you scroll the avatar stay sticky inside the card? There’s just like lots of little things like that I had fun with. And the colors, there’s a lot of Display-P3 colors.
If you hover on those filters on the left, those are using the brightest colors that you can get from your screen.
Sam Brace: Oh yes they are.
Adam Argyle: Brightest green. Yeah. And so it’s a little different on his screen than on ours, but in person those are like, that’s a really juicy neon color. And so I got to go use my, so again, that’s like very dog fooding. I do a lot about color talk at at Google. And so I was like I’m gonna have some nice candy colors on my site. But yeah…[00:19:00]
Sam Brace: I think this is great. I think this would be a real, what I would love to see is some of the ways that you were able to put this together what I plan on doing is I’ll take down my screen and showing off all your great work and you can pop it over to yours so you can show us everything that you’ve been up to and maybe give some people some insights on how they can do this on their own.
Adam Argyle: Sure.
Sam Brace: All right, so there’s Adam. All right, so let’s take a look at this.
Adam Argyle: So this is the pic component. And it ultimately builds the picture element that will contain all of the different sort of information. And so here’s a nice little interface, kinda gives you a preview of the different options that you can pass it.
So it requires a string. alt is optional, though I generally supply alt as often as I can. Height and width, class style and Cloudinary. So the Cloudinary string is interesting because you can pass overrides. Like up here you can see there’s some defaults too. You see the. Google’s you need to update your operating system.
I’m like, no, not today. I’m gonna do it later. It might pop again, pop up again. We’ll see. But here’s like [00:20:00] my standard optimizations here where I’ve got format auto, which is gonna let me supply whatever the browser’s capable of. I got c_limit quality auto and width auto. And those things are gonna play really nicely with the client hints that I send it to.
And just really quick on client hints, those are over here in. A bunch of confusing looking markup right here, right? So except ch, we have content. So these are the different client hints. I’m opting in to send along with my headers to Cloudinary so I don’t have to put these in my requests. I don’t have to put them in the URL for the image.
They get sent with the headers and y’all have an intelligent enough server. To look at these properties and return with something that’s relevant to the factors here. So I’ve got the size of the viewport, like I was saying earlier, will never show an image that’s bigger than your viewport, which is nice because I’m uploading some 20, 2000 or 3000 wide pixel images sometimes, and you don’t have to pay for [00:21:00] that.
Just the regular width, which is doing its best. It can get the width off the image element itself. So there’s a reason to put another reason to put the width property on your images. Downlink is how good the internet connection is. So that gives y’all an opportunity to change the quality and the dpr what’s the pixel ratio quality that they have?
And make sure to give a, give me a 3X if these folks around something super nice. Yeah, and that’s and then there’s also a bunch more here to support that additionally. So that’s like the client hints. But the Cloudinary here allows me to do overrides and sometimes I will do overrides cause like maybe in the moment I know better than what the optimizations are.
And that gives me the opportunity to populate that. So custom styles, custom classes, alt text, and then these like bases here. And then here’s the lquip base, which I’m not using anymore, but this was really cool. Look, I can blur it. 2000 pixels, make sure it’s a thumbnail still. Auto formats. I’m getting nice and small image formats depending on the browser’s capability width auto and quality looking low, [00:22:00] right?
Cause I need a, I need something to deliver. Super duper fast to just provide the scent or the hint of what the image will be eventually. And then I’ll, do a tricky swap. But it ended up being, I was like, y’all serve images fast enough and I don’t want to put JavaScript in there just to serve my images.
And then I also don’t wanna do conditional JavaScript that looks to see if you do have JavaScript enabled, blah, blah, blah, blah, blah. I was just like you, y’all got me covered, so I’ll just ship that high quality one. But it’s just still cool to know that the transformations are just a string.
A few commas and some properties away. So when a picture component gets used, I pass in a bunch of props. I extract things from, so this pic paths is gonna go basically take those base paths that we were looking at before all the optimizations, merge them with the actual path of the image that I passed in and return me like I was showing you earlier, that full image.
So that one’s unfettered, and you’re gonna get that high quality, large modal image. A custom one, which is gonna be a mixture [00:23:00] of whatever Cloudinary ones I passed in combination with the base ones and then the placeholder. And those get extracted from this function picPaths. I also have this here too, which is my site, is if you remember the cards, they max out on their width.
And so you could have a MO, a monitor that’s wide screen. And I’m still only basically gonna be filling up the inner column, which means I’m very, I have high confidence in the max size of that column. It’s in my media queries. So I’m able to give that information to the API and saying look, it’s either gonna be like a hundred or it’s gonna go up to 350 on mobile. I’ve got medium and large. Or have you, have y’all heard of the Goldilocks approach?
Sam Brace: So, I know what Goldilocks is. Tell me what the Goldilocks approach is.
Adam Argyle: You got like your daddy bed, mama bed, baby bed.
Sam Brace: Yeah.
Adam Argyle: That’s pretty much a fun way to work with or think about your media queries. You’ve got your daddy screen, your mommy screen, and then your baby mobile screen. And so those kind are, what these map to here is I’ve got like large, [00:24:00] medium, and small.
Sam Brace: Yeah.
Adam Argyle: And so then this component’s gonna return an image. Obviously that’s what it’s gotta do. Always put loading lazy on there, unless you’re worried about LCP and you’re trying to put something up in the main header area, which I don’t have. So, all of mine are pretty much lazy. Here’s that data-full attribute we were talking about .The alt props, the source that we’ve established that we built, customized during the SSR build process. Height and widths, styles, decoding async, which is like another fun little optimization you can tell the browser like you don’t have to stop when you’re drawing and processing this. I’m probably describing that a little wrong, but it just frees up the browser to be like, oh, I’ll come to this later. Maybe it’s not needed this second, I’ll come back to it like loading lazy. It’s not in the viewport. The rest of the information on this image don’t matter. And then I’ve got source set and sizes, and so these are additional ways for me to tell the browser you know what it is that I’m giving it additional information again to attach to the headers and it, and know for itself that it can size something as small as possible for this [00:25:00] mobile user, but also grow for a larger set.
And that’s that the information that we see there. I think down below, here’s just kind where I build the strings. So this again, is kind of confusing JavaScript. I’m making sure it is a Cloudinary image by looking for my folder. So y’all give me a folder, I put everything in the folder and that’s how I that’s my hook basically, to know if it’s coming from Cloudinary or not.
And then I check if something’s a GIF. Cause if it’s a GIF, I actually wanna serve that as an mp4. Gonna be a lot smaller. Y’all do it on the fly, I can limit the amount of loops. There’s all sorts of good stuff to have there. And so I can also generate a placeholder with y’all on the fly so I can show an immediate image and then if they wanna watch it anyway, just lots of really cool little details y’all give me the ability to do.
Sam Brace: And of course, to unpackage that a little bit, the reason why you would wanna serve a GIF as an mp4 is because of size in most cases, right?
Adam Argyle: Yeah.
Sam Brace: You’re saying like a GIF is normally fat a little bit bloated in some cases in terms of what it is, but we can make that look exactly the same way, but deliver it as a video and then suddenly it [00:26:00] becomes a lot more lightweight. Is that the same reasoning that you did it as well?
Adam Argyle: Yeah. Yeah. It was for size mostly. And that you, y’all make it so easy I might as well. And I think I only have a couple of GIFs, but it’s nice in case I wanna embed a GIF.
Sam Brace: Yeah.
Adam Argyle: So, if I’ve got a blog post that I write and I wanna put a GIF in there I can have it transformed on the fly, just put it in my bucket, pull it down and apply some optimizations. But yeah, that’s a pretty good overview of like my pic component that powers a lot of the images. And here, yeah, I’ll just leave it at this spot right here.
Sam Brace: Yeah, I think this is really powerful what you’ve shown here, because it explains that all you need to do is make sure that you are uploading your files properly to Cloudinary, and then a lot of the transformation work has been very scripted out so that you don’t have to worry about, did I apply this parameter, or is this being optimized or is this not being optimized? So there’s a lot of things that you’re doing to make sure that this is streamlined and automated really as much as possible. So there’s a lot to like about this.
Adam Argyle: We could look at usage really quick. So, if I [00:27:00] open up like what’s a good blog post? Oh, let’s see, gradient.style. Maybe this’ll have one in it. Oh, here’s a good example.
So even the, like the markdown posts have a hero and the source look, it’s prefixed with argylelink, so I know that it’s coming from Cloudinary, so I can go fetch it and build out this nice hero image, which is a little bit, oh look, here’s the size of that one was 2144 pixels wide.
I doubt anyone sees it at that size cause I think I maxed out the width of my entire blog post at a certain size. But still, these are just inline initial attributes that the browser uses for a ratio, it’s not actually gonna draw them at that size, it’s gonna look at CSS and make something smarter. And look, oh, here, look at this.
I didn’t even plan that, but here’s what kind of like an image looks like. So I’ve got a little bit of a secret sauce in my markdown that I can use, but I passed the path to my folder, and then the name of the item. Oh, it looks like I adjusted some code. Pass the name of the image. This is my alt text. And then at the [00:28:00] end I use a double dollar sign.
Sam Brace: Nice
Adam Argyle: To note the inline height and width attributes. So that way I know that even though they’re coming through markdown, they’re not gonna cause any layout shift. They’re gonna get embedded and have a proper ratio and then I’ll go Cloudinary them and grab them at the best size that they can.
And that’s the same for videos pretty much too. I don’t know if there’s a video on here. Yeah, look, here’s a simple image. So that one I didn’t apply alt to. Anything else? Nope, just a couple code pen inbeds.
Sam Brace: One of the transformations that I saw that you use is c_limit as well, which is like an excellent way to make sure that you never accidentally upscale that image past when it should ever be. I know that you were putting in huge images to why would you ever upscale something that it was, 2,100 pixels in width. But, you have that as that parameter saying, if I ever make an error and I had an additional zero or something like that. Then don’t worry it, it’s gonna catch it and make sure it never serves it past the original either.
So there’s really smart things that you’re putting into the overall optimization. It’s like it really is. You have a true set and [00:29:00] forget it type of optimization layer, which is great.
Jen Brissman: Yeah you have.
Adam Argyle: Yeah. Build it into the code.
Jen Brissman: Yeah. You have lots of parameters passed in on page load. And I also just, just even going through, if you scroll down to when you’re using. Let’s see a little bit further down. Yeah, you’re when you’re using, you’re just using a lot of Cloudinary features and I was just wondering as we were going through them, how you figured it all out because we talked to a lot of awesome developers that are using Cloudinary in some cool ways, but then they’re missing some really important ways and they’re just like, oh, I just never found out about it.
But somehow, Adam, you found out about all these little lesser known Cloudinary features and it, is it just because you’re a tinkerer or is it just because you’re focused on the user or you just wanna optimize? Like how did you find out about all of these Cloudinary features?
Adam Argyle: That is a very good question.
A lot of it starts with the base of, I work with HTML engineers, so they’re building the HTML spec. [00:30:00] I get to watch image features land in the browser, and y’all do a very good job at watching what’s going on and you start implementing those features as soon as you can. Like you have some special Chrome only information, like I think client hints are.
They’re a spec, but they’re only implemented in Chrome right now. They might be in Firefox anyway y’all were on top of it. You were like, huh, more ways to optimize. You’re like, here, let’s give that to developers. And so I’ve, I follow those and then I go looking for those in your docs and I’m like I need to know how do I pass these things to, to take care of all of this superpower stuff that I know the browser can do.
All this communication that can happen between a server and client, I want that. Again, cause I wanted the user to have it and I wanted to dog food these things. So I scoured the docs, read each parameter one by one. I was like, oh yeah, I want that one. And just had a comma and then, oh, I want that one too.
I had a comma, but there’s a secret sauce which is, y’all have a Dev Rel and his name’s Colby and he’s very cool.
Sam Brace: Yes.
Adam Argyle: [00:31:00] And so I was, showing my site. I was like, I used Cloudinary. And he popped it open and was like, “Oh, hey, you could do this”. I was like, ah, gasp. I would love to do that.
And then he’d be like, “Oh, if you tweak this one little pram right here, you can get that”. I’m trying to remember, he might have been the one that told me to put c_limit in there.
Sam Brace: Oh, if he did, he deserves all the awards. It’s a great transformation. So that’s good job, buddy.
Adam Argyle: What else did he have in there? Anyway, so I also, that was like some secret sauce. I got a direct line to your excellent Dev Rel who helped me really hone it. So, it’s like I’d done a good job. It’s not like I’d done poorly, I’d implemented a lot of great things. But that last little, those are also the things I love being like a user experience oriented engineer.
I’m like, oh, the little things are really important to me. So I got some special help from one of my friends and their name’s Colby his friend now wasn’t a friend before, but yeah.
Jen Brissman: Cool. So yeah…
Sam Brace: Colby’s basically everybody’s friend, right?
Jen Brissman: Yeah. Yeah. Everyone knows and loves Colby and I totally agree. I’m one [00:32:00] of those people. So before the, secret superpower of Colby, you decided something you wanted to do and then went in the docs to see if it was possible. Is that the order or you found out something that was possible and then went into the docs to figure out how to do it?
Adam Argyle: Yes. Okay. So some things like data saver and client headers.
Like I knew all in client hints, I knew what client hints were and I’d never implemented them before. So again, like me being the sort of explorer that just wants to always adopt things and try them out and get a sense of what the trade-offs are. I went reading your client hints docs, which were pretty new at the time.
I think they’re still even, maybe they changed, or I think I found a bug at one point too. Where I was like, hey, I tried to pass this, and they were like looking at my server requests being like, oh, that client information, that client headers are there, what are we doing? And having a conversation back and forth there.
But Data Saver was one that I’m a little partial to that one. I’m one of the spec editors of the concept of Data Saver and CSS. [00:33:00] That’s like in your browser or in your operating system, you can indicate that you are in a tight wifi scenario or a tight data network. And so you don’t wanna use a lot.
And you can send that along with requests and servers can see that and be like, oh, this user doesn’t wanna download my huge images, for example, or something like that. Let’s make sure to give them something low quality or maybe nothing at all, or. Just the alt or, all sorts of, there’s all sorts of like fun moments that happened after that.
So, I went looking at can I do data saver client hints with Cloudinary? And sure enough it was there. But I think that’s the one where it had an issue and I needed to add some special header. Like we were looking at that funky syntax here in the page meta. This took a lot to figure out.
Sam Brace: I can see that. Yeah.
Adam Argyle: sec-ch-width. This sec-ch. Oh, this is the client hints dpr client hints widths client hints viewport. Oh, that’s what it was too, is all this all has to match this and it has to be in the same order. [00:34:00] So there was like a combination of things I had to do that y’all were also looking for. It’s just the classic code dance. And so I was trying to early adopt the idea of data saving and using client hint and scouring those docs. I even think I got a direct line with through Colby to your engineer who’s working on those. And we got to go back and forth looking at the server logs, looking at the headers on my images. They’re looking at the headers on my images.
Sam Brace: Oh, that’s cool.
Adam Argyle: And it was really cool and we ended up finding some little tweak that optimized it for both of us or whatever, and it was like, oh, wins, wins for everybody. That’s cool. So that, yeah, I was return to early adopt scouring docs had good lines to folks. Y’all are very available, which is really nice. And so that’s how that came about. Yeah.
Sam Brace: One thing I did wanna ask you about, because like I could look, looking at your screen now, obviously if anybody knows what TSX is, they know that’s TypeScript. What I’d like to ask more about is just like the choices of using [00:35:00] TypeScript, was it also because of the framework as well? Cause I know Deno pushed a lot, like they’re, they do lots of TypeScript support whatnot. What was the reasoning for this when you were going down to their website side?
Adam Argyle: Awesome question. So all in all, I generally don’t like TypeScript. And it’s not that I don’t like it, it’s just that I like computers to do the work for me and when I have to type things, I’m doing a lot of the computers work for it, and I’m just like bums me out. But okay. But Deno comes with it prebuilt. So one of the, one of the bummers of TypeScript is taking care of TypeScript. It’s kinda needy sometimes. It needs a lot of configuration to be customized or whatever. It has all these different sort of needs.
And so the trade-offs for me were always like, I’m spending too much time in TypeScript. I’m not getting the value back. But with Deno, it’s all built in. You don’t have to manage it at all. There’s nothing that I had to set up. It’s outta the box. And then again, I like to early adopt things. This isn’t my first TypeScript [00:36:00] TSX or like TypeScript JSX project.
I’ve done a couple of them before, but this one was mine. And so that was nice. I got to do it my way. So these days I call my, call myself a light typer. As you can see, there’s light amounts of types. I have some interfaces and I have some typed parameters. But I’m not going overkill. I remember the first time I was learning TypeScript which I come from a strong typed language.
I learned Java as like my first language. And and action script three, it was like a really big language for me for many years. So I was so happy to drop types and then all of a sudden it was cool to type again. I was like, no, we move forward. Okay. Anyway, that’s just still me ranting, but. It comes with the framework in Fresh.
So a lot of it’s outta my hair and I got to do light typing, which was, minor amounts of confidence in my builds or minor amounts of confidence in what am I passing between all my components and stuff like that. And so that was the reason for that. It came with Deno Fresh and Deno is a TypeScript centric edge server to [00:37:00] begin with. Yeah.
Sam Brace: I think it’s cool. I think and I like the trade off there that it makes sense. It makes a lot of sense. Fun, fresh framework, no pun intended, but then also getting to be able to say but I have to do some type script, but I can also get what I want out of it. So that’s cool.
Adam Argyle: Very cool. Yep.
Sam Brace: And I love the fact that, maybe this is intentional, maybe not, but if like the color scheme of your IDE all seems to match the color scheme of nerdy.dev, was that intentional or did you make your own color scheme?
Adam Argyle: Oh yeah. I have made my own color theme. It’s called Oh, geez, I’m gonna forget the name of it. It’s what was the movie where they had a lot of Kung Fu, it was on Netflix, Kung Fury. Kung Fury is the name of the thing.
I dunno if you remember that … It was a, actually it was a Kickstarter. And then it got picked up on Netflix cause it was so successful. But anyway, it’s very tongue in cheek a retro wave type of thing, and it had all these super rad [00:38:00] neon colors and stuff.
So I built a theme based on that. This particular theme, like I normally wouldn’t put a vibrant yellow in mine but someone else made one. I also have a YouTube series called GUI Challenges, which is always using my Kung Fury theme in sublime, and people commented on all the time. They generally don’t like it.
But some people are like super in love with it. Like the things not to like, which are things that are important to me and this one doesn’t have it as much is I try to, if the syntax is correct, I push all the noise away: like quotes, curly brackets, semicolons, colons, commas I do like to keep because like I just as a scanner of the code, that’s all noise.
I just wanna be like imports, pic path from, there’s the path, like the rest of it is all just junk to get the job done. So my code syntax highlighting is always pushing the junk away as long as it’s good, cause if it’s bad, it highlights in red. So that’s my mantra and somebody built this theme. I was like, they, and it’s my VS code theme is very out date at this [00:39:00] point.
My sublime theme is very nice and up to date. And this one was made, oh, what is the name of this one? Anyway, someone built it inspired from GUI Challenges and I was like, y’all did a really good job. I sent a messages and I’m like, I’m using your theme now on my VS code. And they’re were like, huh? I was like, job, I gotta do it.
But yeah, it does all match the cyans. The purples. The pinks. That’s good stuff.
Sam Brace: As every good designer should. Carry the design across all elements. Excellent work there Adam. I like it.
Jen Brissman: Yeah, and I knew okay, so obviously I think Sam was saying, I think it’s intentional, probably knowing that it very much was intentional, but like I knew okay, like not to take a turn here, but like I knew how your code made me feel.
I’m like, wow, this is so clean. I love this. I feel like very safe with Adam’s code right now and I’m looking at his website and it looks like very beautiful and clean. And what you said before, simple and intentional and minimal, but just beautiful and appealing, and it just makes you feel good.
And as much as like developers, I know a lot of incredible developers that are [00:40:00] like, I don’t do like design or I can’t be bothered with that. And that’s fine and great, but I do think it matters even on the Deno website that we were just looking on before. I’m like, this looks really pretty.
I like this like minimal vibe we have going on here and it does matter. And I love that that’s so much of what you talk about Adam and color and all of this, because even just in this podcast and looking at your stuff, I’m like, this all just feels good. Even your background, even your colors behind you, like you just, oh yeah. It now makes you feel good and safe and it’s fun and fresh and I just love it. So this is maybe something I was gonna say after you left the show, but had to give you some compliments in real time cause it just all feels so good. Yeah.
Adam Argyle: Thanks so much. I follow in the footsteps of some other great people where they were like, I just found this cool font for my
code, and I was like, and it was like, I remember operator mono and it was like $150 bucks to buy it and I was like, Ooh, I’m not gonna buy that. But I did buy Dank Mono and that’s what I’ve been bringing with me for all these years. And so that’s, the font in here [00:41:00] is Dank Mono, which has cool Fs and it has the kind of cursive-ish italics and stuff and yeah, look at from, that’s just pretty. And I was like, I gotta have it. Oh yeah. Back when Ligatures were just coming out when the arrow was connected to the greater down, I was like, oh, I gotta, I have that’s just too slick.
Jen Brissman: Yeah. And I’ve never seen a theme where it strips out like, if the syntax is correct.
And I was wondering, I’m like how do you know if it’s not, so it gives you red and squiggly underline of doom and you know to fix it. But when it’s right, like how it just strips it away I think that’s awesome. I’ve never seen that. And I’m gonna, I’m gonna get one of those themes for myself.
Adam Argyle: Thanks. Do it, Kung fury and ping me after the show. I’ll tell you which one this is on VS Code in case you’re in VS Code.
Jen Brissman: Yeah, for sure. I am on VS code. Cool.
Sam Brace: I think the thing that’s great about the project in many ways is that, we are we’re touching lots of different things, right?
As we’re going through this. Obviously, we talk about the images and the videos, but I think the nice thing is that [00:42:00] if people go to your site, nerdy.dev, and they take a look at the blog post where you talked about new year, new site it happened of course, on January 1st, so not hard to track it down it’s to say there’s lots of things that we break down, like the fact that you’ve been able to handle fun ways to handle light and dark modes, and you have all your commenting done through web mentions, and the way you handle analytics is also a little bit groundbreaking, at least in my opinion. So it’s where I hope people don’t just say oh, this is a chance to talk about fun ways to do images and videos properly.
But it’s also to say If you’re not so inclined on the image video side, you want to cover other things. I think there’s lots of little pockets and rabbit holes you can go down in that blog post that can really teach you a lot about ways to really enhance any website, let alone a personal blog post.
So I’m very impressed by the work that you’ve been doing, Adam. So if this is…
Adam Argyle: Thank you.
Sam Brace: …people’s first foray into what you’re doing, goodness gracious you, there’s gonna be a lot that they can uncover where the great [00:43:00] work you’re putting out there.
Adam Argyle: Thanks so much. I appreciate that a lot. It’s really nice.
Sam Brace: So, Adam, since you are a developer, you’ve been doing this for years, you’ve been developing, as you said, you’ve done lots of websites, so you have your time at Google, getting to work with some probably the brightest and best in the field. What do you feel like, is there any like big takeaways to say people should be focusing on X or Y or like maybe inspiration for the developers out there that are saying, I’ve heard a lot.
What should I be doing? What can I do with information? Anything like that.
Adam Argyle: Ooh, I have a…
Sam Brace: I know spot block. The floor is yours.
Adam Argyle: Lot of different rants there, right? Let’s see. I think a good one to mention is that there’s a lot of conversation around DX versus UX. And I feel like I’m a weirdo in this conversation.
So like I obviously I have a lot of DX in mind. I’ve got my own syntax themes that I use. I’ve developed my own way to work with TypeScript. I’m trying out all these different frameworks, looking at their DX, [00:44:00] looking at Cloudinary, experiencing the developer experience of Cloudinary. And these things
I directly use to impact my UX, but I also don’t, I don’t attribute the success of my user experiences from my tools. So what I wanna do is help us split things out. Like we’re doing a disservice to the user experience industry. And the developer experience industry by trying to say that one leads or one rules the other one.
And so I wanted to share that as a user experience designer that’s all they do and they’re doing way more than you could ever do, building it into VS Code the things that they think about, the things that they care about. It compliments everything that you are gonna eventually build into this tool.
So DX can’t exist without UX being thought of first. And so just I would implore folks to really focus on your user. Put yourself in their shoes. Think about what it would be like [00:45:00] to not have a mouse and to only be able to use a keyboard. What would it be like if the light theme gave you migraines?
All sorts of things like that and that, data saver mode, like I was saying, that that’s really important to me that folks visit my site and I’m not gonna be like, here’s 140 images that are all about five megabytes each. That would be rude. So I got loading lazy on there, and then I’m doing all this optimization and then they load my site.
They’re like, oh good. This is only, a light amount on my data plan, which is really nice. Orient yourself to the user and you’ll be happier. Compare yourself and compete less with other people and you’ll be happier. That’s my message, I guess.
Sam Brace: I like it. I like it a lot. And I think it is something that it’s so easy for anybody, I think, in the tech space, regardless actually what your role is, to be so heads down and focused on the tasks that are at hand, that they don’t think to themselves, how is this gonna impact the person that’s actually gonna have to use this thing that I’m building or working on?
So I think constantly putting yourself in the shoes of the person that’s [00:46:00] gonna be experiencing whatever you’re working on is a great focus area. And I love that area to say, think about the user and developers can help drive that engagement for every user. So I love the mirroring between the two.
Adam Argyle: We’re all in this together.
Sam Brace: This is cool. This is cool.
Jen Brissman: Yeah. We’re all in it together. Like you’re talking about working with Colby, all the people available at Cloudinary. Like teamwork makes the dream work, but also it’s not just about. Making something work. A lot of developers, their mindset is like the first thing you have to do is let’s make this work.
But then the next step, which I feel like Adam, you’re all about, is how does it make you feel? Is it gonna stress you out, give you a migraine make use a bunch of data? How is this gonna make the user feel? And that feels like a kinda new-ish concept in the not new, I don’t know what new means, but I hope we see a lot more developers focusing on the stuff that you’re focusing on going forward.[00:47:00]
Adam Argyle: Thanks so much. I have a metaphor I like to say is you could give me two cars and one has a, just the latest, coolest engine it’s so fast, hyper optimized, uses $1 worth of gasoline and goes a thousand miles or whatever. And I sit in it and it’s all squeaky. And then I try stirring the steering wheel and I’m like, it’s weird and uncanny. And then, the interface is all weird. I’m just like, sorry you lost me. Your car is dead to me now I’m gonna go with the car that I sat in that was comfy and might be mildly less good in some other ways. It’s just that’s how we are as users. At the end of the day, the performance factors don’t apply as much as a vibe.
This is like Bauhaus used to teach us that form follows functions. So yeah, you do need to make it work first, but then you need to find out what’s the shape that makes this ergonomic, what’s the shape that makes this last? And that’s the fun part. It’s also a really hard quest, but it’s worth it. Yeah.
Sam Brace: [00:48:00] Love it. Way to end on a Bauhaus situation. I love that too. Adam, this is great. Great work. So thank you for being here. This is wonderful and I highly encourage for people to be able to come over and check out all the great work you’re doing over on nerdy.dev. I think it’s, you’re doing some amazing stuff.
And I, I will also quickly plug the work that you’ve been doing with being able to do the HD gradients, the other one that you mentioned earlier with the Svelte framework that’s different than the nerdy.dev program. Make sure that people are checking both of these things out. Amazing work by you. So keep it up.
Adam Argyle: Thanks so much. Jen, it was really nice hanging out with you and Sam, nice hanging out with you too. Appreciate the time.
Sam Brace: Absolutely.
Jen Brissman: Thanks for coming on, Adam. This was a lot of fun.
Sam Brace: Jen, I gotta ask you. What is your big takeaway here? What’s the thing that stood out to you about everything we talked about with Adam today?
Jen Brissman: I don’t wanna sound like a broken record because I feel like I’m, [00:49:00] I keep saying it, but I’ve been in the head space just personally. I’m in Japan right now and everything is so aesthetically intentional and it makes you feel good. It’s minimal and the design is just like something at least I’m not used to in the US.
And I feel like Adam I don’t know, maybe he belongs in Japan because his stuff just makes me feel so good. I don’t know if I’m not used to that is the right thing to say, but it just feels like a newer concept. And I know as a developer myself, CSS is like not that fun to learn.
There’s a big hump to get over until you’re actually good at it. And I’m not over that hump myself and I just see what he’s doing and it makes me like wanna get over that hump because I think what you’re really fluent in CSS, you can do some amazing things, but there are a lot of different programs coming out that are like low-code, no-code or drag and drop, snap to fit Wix, like website [00:50:00] creators and programs that take that part out of it.
But, it just makes me wanna go back and do it like Adam’s doing it because I think it can be so much better when you customize it and you really know what you’re doing and you really have the user in mind and. And yeah, I just feel really inspired. So those are my takeaways.
Sam Brace: Good. And it’s wonderful when we feel inspired. We already knew Adam and knew what we’re gonna walk into. So it’s nice when there’s layers and layers on this as well. I think the big thing for me with this was I love the exploration that Adam did, where like new site knew everything and like where he basically started fresh, like I said, new framework, new way of handling commenting because he wanted it.
He works at a company that does analytics and he’s but I can potentially do it slightly differently and try out in different platforms and see what’s possible. So, I just like the fact that everything was blank canvas theres nothing assumed. That’s coming in there and trying it and seeing what [00:51:00] works.
And so I, I really appreciated the fresh takes of a lot of the things that he did and I hope that many developers, even ourselves, continue to do that and say, just because we did it that way yesterday doesn’t mean is the right way to do it today. So I think there’s a lot to learn from Adam there.
Jen Brissman: Yeah. And I love that comfy car concept. I hadn’t thought of it like that, but, and also the fact that Adam has gone in and just poked around and just seeing how things work. Obviously that’s an incredible quality in any developer, but it just goes to show when you’re passionate about something, you can just get so much farther and learn so much more. And his passion clearly shows and what he’s landed on and what I trust, he’ll continue to grow and continue to land on, continue to explore. And yeah, it’s just really awesome stuff.
Sam Brace: Absolutely. Absolutely. So with that said, let’s make sure that people know if they liked us.
Great. Stick around because we got plenty more episodes for you to check out all of them at [00:52:00] cloudinary.com/podcasts. And it’s not the only place you can get our podcasts, of course we’re gonna be on all the various services you probably listen to podcasts on, such as we’re on YouTube, we’re on Spotify, we’re on Apple Podcasts, Google Podcasts, we’re on basically, you name it, we’re there. And of course, we have years and years of content to go through. So you can see here we have episodes from all the way from student developers all the way to some of the best and brightest in the field, like this episode right at the top from Kent Dodds. So, make sure to check those out if you wanna see the full library, of course, cloudinary.com/podcasts.
Also, as mentioned before, keep the conversations going. If there’s anything that Adam talked about or you’ve heard about on other episodes and you want to ask other users… are they doing this? Like maybe some of the transformations that Adam went explored, like f_auto and q_auto and c_limit, or maybe some of the ways that he was able to do conversions from GIFs to mp4s, anything like that, you can discuss that at Cloudinary’s community.
So that’s community.cloudinary.com and as you can see, we have a [00:53:00] handy dandy Discord server for realtime chats amongst yourselves as well. So make sure not to miss any of those. And even though I plugged it earlier, I can’t plug it enough, go check out nerdy.dev for all of the great work that Adam’s doing.
You can see he’s regularly posting content about all the things that he’s up to, what places he’s speaking at, and of course just some of the moods that he happens to be. So wonderful things that are happening in this case.
Jen, any final thoughts before we let our audience take the rest of their day?
Jen Brissman: I don’t think so. I think we covered it. I don’t wanna sound like a broken record. I just I think this was a really fun episode.
Sam Brace: Yeah. I agree. Absolutely. On behalf of everybody at Cloudinary, including myself and Jen, thank you for participating in this DevJams program and we hope to see you at future episodes where we will talk with developers that are doing innovative, inspiring, and interesting projects with images and videos, and likely using Cloudinary.
[00:54:00] Take care and we’ll see you at the next one.
2023-12-01
Generating Image Galleries, Open Graph Content with Vercel and Cloudinary
In this Cloudinary DevJams episode, we are joined by Ben Seymour – Director of Sales Engineering at Vercel! Ben has developed several interesting open-source projects using Vercel, Cloudinary, and Next.js. With these technologies, it is possible to create fast-loading, animated image galleries. Combined with Vercel’s Open Graph Image Generator, he also can easily create and update the images used by social media sites and microbrowsers when sharing projects! Ben provides how-to details on some of the steps taken, such as markup with Tailwind and extensive use of Cloudinary transformations for background removal and other effects. This episode is jam-packed with practical tips and tricks to take your development skills to the next level! So, do not miss out on this exciting opportunity to learn from a seasoned pro like Ben Seymour.
Sam Brace: [00:00:00] Hey there. My name is Sam Brace and I am the Senior Director of Customer Education and Community at Cloudinary. And you are watching and listening to DevJams. This is where we talk with developers who are doing amazing, interesting, innovative, inspiring projects, especially when it comes to working with images and videos on the web and software on mobile and many other amazing projects.
And because of course, I work at Cloudinary, this program is produced by those at Cloudinary. They probably are using Cloudinary for some of those image and video management and delivery aspects of their projects. In today’s livestream and episode, we are talking with a good friend of mine, Ben Seymour.
Ben, for full disclosure, actually did work for Cloudinary for a portion of time, but has been- for a while now- the [00:01:00] Director of Sales Engineering at Vercel and Vercel, if you haven’t encountered them, their amazing platform, especially for frontend developers, and we’ll walk through all the details about what Vercel does, especially in this program.
But he has an amazing set of projects that he’s gonna be able to show us today when it comes to being able to create image galleries very quickly on the fly with information coming from Cloudinary, particularly with the images that are coming from a Cloudinary account. And then we’re gonna dive deeply into a topic called Open Graph, which is of course, a type of metadata that is used by social networks like Facebook and Twitter and LinkedIn, as well as what we call micro browsers, such as services like Slack, to be able to display images that are associated with a certain URL.
We’re gonna dive into a lot of different ways that Vercel making that easy to work with, and of course, in conjunction with Cloudinary. Before we bring Ben onto the episode, I do wanna emphasize that if you, this is your first time ever being part [00:02:00] of a DevJams episode. Note that we have all of our previous episodes at cloudinary.com/podcasts.
That’s where you can go through the entire archive and find any episodes that tickle your fancy when it comes to details about JavaScript or Next js, or just working with images and videos and working with webhooks and metadata and all sorts of things are associated that there’s a lot of amazing content that’s inside of our overall podcast feed because we’ve been doing this for about two to three years now, so it’s a pretty impressive amount of content that we have in the library.
And we do also wanna emphasize that if you want to continue the conversations that Ben and I are gonna be having in this overall episode, many of the concepts are things that our users talk about daily inside of our Cloudinary community. You can find that at community.cloudinary.com. And as you’ll also see, we do have an associated Discord server for those that would prefer to talk in Discord versus our forums.
Or maybe both. [00:03:00] It gives you lots of different opportunities to be able to start conversations and meet users like you. As we said, Ben does work for Vercel, and I also emphasize front end development. It’s an amazing platform for all the things that you need to do when you’re working in this overall space.
But of course, we’re gonna dive into two specific types of projects, image galleries, and Open Graph. So with that said, I’m gonna bring my screen down and bring on Ben and welcome to the program Ben.
Ben Seymour: Amazing. Hey, Sam. Wonderful to be talking to you again. Just like good old times.
Sam Brace: It is.
Ben Seymour: Hey everybody. Ben Seymour, based in the UK, not far from Oxford, sleepy little town, very cute place. Founded in 1155. Great to live unless you like night life and food to be delivered to your house or the ability to catch a train all of which are impossible. There we go. I ultimately with live with my wife, our two kids who are 16 and 13, and our little dog.
And as you probably gather, I [00:04:00] like things through physics space and also fast moving things with two or four wheels. By day. I work for Vercel who also love speed in terms of web performance, but also developer iteration speed as well. So the sales mission I think is. There’s many missions in here, but one of them that I love is to enable developers to create at the moment of inspiration.
I think capturing that spirit, that flow state is something that I’ve always loved in terms of my work in this industry. And then one of our other mantras is the iteration velocity solves most problems which I think is one of these things where when you’re in the groove, almost anything is possible.
Outside of it. Added friction, added frustrations is deeply annoying. In terms of the rest of the team I’m very fortunate to work with some remarkable people. So we are massively open source. The people who work at Vercel are involved in all these projects, so Tobias created Webpack.
He’s currently working on the latest version called Turbopack with more of the team Rich who made Svelte is here, and Turborepo. Some amazing projects. [00:05:00] All massively open source, huge numbers of downloads and it’s something that we massively pride ourselves in contributing towards the overall community.
Lots more to say, but probably not today in terms of our story. What do you think, Sam? Should I move on to the conference? Should we get set?
Sam Brace: Yeah. Let’s talk about this conference that you guys did with an Next JS.
Ben Seymour: Perfect. So this was October of last year. And effectively it is by Vercel, all about Next JS in this case. So really it is run on the platform. We build the everything conferencing facilities. We look after everything, but it’s fundamentally not about Vercel per se, but about Next JS specifically one, one of our open source projects. In this particular instance, we had 110,000 people sign up to watch it.
55,000 people watched it online. And if you look at the kind of follow on views that they’re pretty impressive. In this one we talked about a variety of things being released. One of them was this thing called edge functions, which at that time was in beta. This is actually quite important to what we’re gonna talk about in terms of Open Graph because we leverage this under the covers to allow certain things to be very [00:06:00] capable.
It was a hybrid event. It was actually the first time we’ve done a hybrid event. It was fairly small. We had a few hundred people in San Francisco, also in New York. We also had one in London and also Sydney. But one of the joys we did is that we took lots of photographs of the day to capture the fact that lots of people look to meet each other for the first time.
So we are a remote first company, but also we are a member of a very large community of people, many of whom would also not seen each other for a long time. So lots of friends came, lots of people from across the industry came, and we made this rather splendid and glorious image gallery that came out of it.
It’s very hard to run a performance test while we’re live on air, but effectively this is an incognito tab and if all goes well you’ll notice that was staggeringly fast. We’ll share the link at another time, but ultimately it is one of the fastest, frankly, media rich. One of the fastest loading sites I’ve ever seen.
The general interaction, oops, I clicked my mistake. The general interaction with everything that you do is incredibly fast. Now, behind the scenes of all [00:07:00] this, just like Sam said earlier there’s fundamentally a lot of Cloudinary going on and a lot of Next JS with Vercel going on. One thing that we’re massively fond of doing is also is sharing what we’ve learned.
So Hassan, who works on that main project for the gallery also wrote an extensive blog going into all the little details that he did, some fascinating stuff that he did along with some of the engineering teams in the ways that we were using effectively the Cloudinary’s APIs alongside some of our data loading properties to allow us to leverage, the best power of all worlds.
There’s some tips and tricks he gave down that I’d never seen done before that were quite amazing that some of his suggestions are to do with things like having a. Having a zero transform 3D which ultimately forces hard work acceleration where it’s available to you. So little tricks like that in effect it looks like it shouldn’t do anything, but behind the scenes it does some fairly subtle things. Also amazing things about this is if you notice there is a clone and deploy button. So another thing that we love to do is somebody wants [00:08:00] to again, learn at the point of inspiration, is that if this looks cool, you can read the blog and you can literally hit clone.
And effectively you can in about three clicks have a version of this fully running on your own local host or also on your own Vercel account. If you take one of our other templates. So if you go to vercel.com/templates, this is where effectively, you have a huge list of starter kits and by no means is it only Next JS you will find most frameworks cause we are also framework agnostic.
You’ll find lots of partnerships and effectively if you search in here a Cloudinary. Then you’ll find there you go, that one there, which is one we’re also talking about. So again, getting going super quick, this is one that I was considering doing live on air, but frankly, take my word for it. The whole thing was deployed in 46 seconds.
So I think one of the things that often I am looking for my many developers is if I want to go and learn something, how much time do I need to invest in this? Can I make progress in. An hour, a day, a week, how long do I need to go and do this before I can actually show that there is [00:09:00] some value coming out of it? Our goal is to make that, frankly, seconds and minutes more than anything else. So…
Sam Brace: Really incredible. And what I love about what we’ve done here is that we’ve combined, as you said, best of breed where we have all of this amazing technology that Vercel went and did, but it’s not where you went and tried to reinvent the wheel with image delivery, image management, you’re able to combine two distinctly different technologies and bring them together for this one project and. It’s something where I was interestingly showing this to our events team that ran our user summit back in London a few weeks ago now, and they were saying, “oh, we need to do this for all of our events”. So it’s to say this is a easy to use tool that any team can absolutely adopt. So great work by the Vercel team to be able to make this possible.
Ben Seymour: Perfect. Perfect. I think that bit where the two worlds meet is probably most if I come down to here. So effectively within Next JS and ultimately this is using there’s a new version of Next JS that went into [00:10:00] stable release last week using a thing called App Router.
This one is actually based on pages. So in this instance, we’re gonna do a single set of data fetching within Next JS. Get static props is effectively a way of saying we would like to pre-build this page or build the page at a certain moment in time. So you can have versions where you do effectively what is server side loading.
Every request goes and make something happen on a server that typically has some kind of performance impact that is rarely good for user experience, but it can help greatly with things like personalization and a few other things. In this instance, we’ve got an option with a Next JS GET static prop says, I’m gonna go and effectively pre-build all of the pages a bit like static site generation that I’ll need in order to then serve what is effectively static pages out onto the web.
But there’s a couple of small twists into that. One of them is that you can choose to do only a small subsection. So imagine if I’m a massive news and media company and I have got a million assets in Cloudinary, maybe I’ve got, 10,000 collections- building all of those is gonna take a long amount of time.
So what you can do within here is you can actually say, [00:11:00] build certain of the collections but not the others. The rest can be generated at request time and after that point will be then served as though that they were fully static objects. In this particular instance, you can see that ultimately I’m using the there you go.
There’s the Cloudinary search. I’m using a variety of things and I’m passing in through environment variables just like you would do. So mostly my credentials, my authentication is done behind there, but I also do certain types of kind of configuration against the actual media that we’re gonna serve in here.
So in this instance, we’re going against a given specific folder. We could have done tags, we could have done any other piece of metadata. And then effectively we’re gonna say to Cloudinary via the APIs, please give us all the information that is relevant to this particular query. If you can just see in the terminal at the bottom, I hope that’s big enough.
This is only the response that comes back, so the JSON response comes back. And ultimately this one brings back what is it, about 111 items. I think it was just in there. So again, I’m making the API request. This could be done at build time or also in [00:12:00] this instance, another interesting thing happens, which is I’ve added a single line which completely changes certain elements of the information architecture.
So this single line revalidate effectively 3,600, which is one hour in seconds. What this says is this page is gonna be classed as static. So from performance perspective, this is a really static file served by globally deployed CDNs. But the revalidate effectively says that every hour we’re gonna check to see if there’s updates.
This is highly configurable. What it means is you do your event and on day two, you wanna do the next one effectively you’re not gonna have to rebuild everything from scratch, but you will find, pick up those kind of, those changeable aspects, if that makes sense. Sorry, Sam, I think you were gonna ask me something.
Sam Brace: No, I wasn’t gonna say, I was just saying that’s a very, very smart one line of code because as you said, one thing that we push a lot in training is being able to set it and forget it to say get your system to be able to work for you. Set up automations, let Cloudinary do its work with automatic transformations.
And this is an example of that where you [00:13:00] can easily say, just revalidate and it’s gonna continue to make sure that whatever you’re adding to this folder is gonna make sure it’s updated to what’s showing in this overall app. So this is fantastic.
Ben Seymour: You mentioned web hooks earlier, it’s one of the other things that you talk about.
So we can also do a think on demand for revalidation, which effectively is, as long as you’ve got a slightly more complex system, which is gonna trigger an event, we can then catch that and do the invalidation on request as well, if you like. So lots of options. Next what I was gonna do is, so this thing here is using an environment variable.
I’m just gonna manually override it. And if you look on the left, so effectively, there you go. So what just happened is in my local environment, I have literally made one change. This has then regenerated this particular page. It’s changed the request in the way it’s gone out to Cloudinary. Cloudinary has come back with an entirely different set of media and everything else is then built on demand.
I think it’s remarkable how quickly you can affect change. If I roll this one back to just as it was, and again, hit save there are certain things within, the Next [00:14:00] JS development environments that are pretty much instantaneous. We have a hot module reloading, so if I change that title at the top there and then hit save, you’ll instantly see it.
In this instance, we’re of course making a change that triggers an API request. Which then comes back, hence even what you’re seeing there is the full round trip. And then all the media also being loaded. Another cool thing, this is something that I for create, create, there we go. In this version, effectively what I’ve just done, as I’ve said this time, please can Cloudinary give me the JSON response back for all the media that matches my query.
But please can you do it in descending order effectively reverse order by the created app. So this is literally the reverse order timeline. So this is the most recent photograph most recently. This project actually is slightly more complicated, which is it’s actually my Instagram feed. And as you probably gathered I’m very fortunate I gotta go and spend a couple of weeks in Iceland very recently.
Yeah, this is actually me setting up a slightly more complex workflow, which was, there is [00:15:00] a Zapier integration running with my Cloudinary account, which effectively is looking for changes in there. It’s then doing an automatic import into my Cloudinary account, doing a bit of tagging, doing some object aware kind of AI analysis as well.
And then this allows me to effectively keep almost like an owned media version of my social media as well, just to gimme lots more choices and things like that.
Sam Brace: Which is incredible. And we’re seeing even more people doing this. Like we had previous episodes where people did something very similar where we’re trying to get everything to come from our Instagram account because of un unreliability they found sometimes with their APIs.
So it’s what you’re demonstrating is not like edge case by any means. We’re seeing more and more developers trying to own their Instagram content and put it into somewhere a little bit more safe or just at least more reliable. So this is cool.
Ben Seymour: The other wonderful thing is set it and forget it is, I’d actually forgotten I set this up until I came to do this project.
I went to go and set it up and found that effectively my Cloudinary account was already [00:16:00] still running on the old API that I’d set up quite some time ago.
Sam Brace: Very nice.
Ben Seymour: So, the next thing I was gonna look, talk about, so this is all fairly local. This is me working at my machine rapid iterations, trying lots of stuff, seeing what the outcomes are like, making sure that each, I suppose each use case fits.
There’s gonna be certain things in here that, if we look at, again, you might look at how we handle different aspect ratio ratios of images does a pretty good job. But having done my local work, I suppose the next thing that typically wanna do is we wanna open up to more people. So this is me going into my Cloudinary dashboard and my, sorry, my Vercel dashboard and my account.
And ultimately, this is me finding what’s called my deployment pipelines. So these are all of the bills that I’ve been doing, and as you can see in the run up to this webinar, I did a few double checks of a few things over here. I did a few redeployments, a few status changes, a few changes.
This is every deployment that I’ve done against my account, but not just the live production work, but also the preview, what’s called a preview deployment. So if you see here [00:17:00] preview- what this actually means is that I did a branch on the code. So locally I branched. In this case it was called Iceland.
It was for that trip that I just mentioned about and effectively having done a branch and then worked off that on that branch. As soon as I start to do commits against it, my Vercel account picks this up, realizes it’s not a production deployment, it then spills up an entire preview deployment, which allows me to do things like share this with somebody like Sam, who can then come in and inspect it without making any changes to production.
It gives me a couple of other really nice, handy things as well, which is I can have environment specific environment variables. So if you saw earlier, sorry, let me just mute when I cough.
If you saw earlier I made that change locally. In this instance, this is me doing it via environment variables on the platform. So I can take a fork of my code, I can come up with another edge case, I can have a preview deployment, and then effectively I can say, Hey, but let’s try it in a different configuration.
And what [00:18:00] you get out the other end is effectively a live running version of that same thing we saw earlier. But it’s not gonna affect the production. So it’s a live preview deployment that frankly, to all intents purposes could be used live if we so wished. The other thing that is pretty cool is if you see here, effectively, we’ve also got DNS settings.
So within my account, what I’ve said is look for the branch called Iceland and set a subdomain against only that branch. Obviously, it can be called whatever you like. So in this instance, if I’m working in a bigger team, We can already know in advance what the end state URL is going to be. That everybody can then run tests against, if that makes sense.
You can either have these against against things like the the Git project name, so that’s also predictable further in time. Or you can have it against manually curated one. So if you wanna share it with your QA team, they will know in advance where it’s gonna be. And it’s just a question of orchestrating.
I don’t think we have. Time today. But there’s some other cool stuff that we can also do, which allows actually other elements of feedback, which is this preview deployment also [00:19:00] includes the ability to annotate. So effectively anybody coming in here could start to add in things to passing comments back to the team.
So phase one is rapid iteration locally. Phase two is sharing with the bigger team. Phase three is getting feedback from the rest of the team. And it does things like it goes into your linear boards as well, if that makes sense. So this one I think is all about the iteration speed of the team.
And that’s pretty important.
Sam Brace: Truly incredible. And the thing that I love that we’ve done here, to take a little bit of a Cloudinary angle on it as well, is that many times when people see that search API that you’re using, they think of it strictly as a way to go and pull a list, but they don’t necessarily always think about it as a way to pull a list that’s gonna be driving delivery.
And the fact that you’re able to do it this way to say that we’re calling this, we’re getting the list of 150 results from that folder, and then deploying that into this gallery. That’s a really cool use case for the search API. So I think that there’s a lot of amazing things here, but I’m blown away.
Ben Seymour: Wonderful. In [00:20:00] a way this kind of brings us to the start actually.
Sam Brace: Yeah.
Ben Seymour: So the reason that you and I got in touch again was that I shared that project that we just looked at. I shared that into LinkedIn. This is the actual post, and ultimately, I think you spotted this and saw that I was doing some stuff with Open Graph, and that was how the rest of this all started.
This is the Open Graph image, which I set up on that project. The next thing we’re gonna talk about is what Open Graph is, have to use it, and also some of the ways in which effectively Vercel, Next JS, and Cloudinary can combine to give some incredible capabilities. If you share that same post, or if you were to drop dynamic.photos into Slack, you get something like this.
Obviously this one is me dropping that link into into LinkedIn. Interestingly, when I did a re-share of the post that Sam did for this webinar it actually accidentally, inadvertently gave us an example of what does what something that isn’t good, looks like. I’m trying to avoid saying bad, but fairly what bad looks like.
So within [00:21:00] post re-sharing, within LinkedIn, it doesn’t allow you to have control over your own Open Graph. Now, I would argue that frankly, a big blue box doesn’t really do a great deal to entice you in compared to what you can do from an Open Graph perspective. This is a protocol. It is available effectively.
It’s just typically attributes that go into the head of your html by and large. There are some fundamentals that you should always try and have things like title and types. The type could be videos or images. If it is an image, then you want to share a URL to the image. So in the case of the one that we saw a moment ago, the image that was shared effectively here is a completely different image.
It’s one that you would never see on the webpage itself. So if you scroll up and down in here, at no point will you see that image. It is within, inside the head. So it’s within, inside the metadata of the page. It’s only used by other systems or other services or other processes. We worked with Colin for a while.
And ultimately Colin is amazing posts on this as well. So it’s also called [00:22:00] micro browsers, or it can also be called link confirming sometimes as well, but the protocol behind all of it is ultimately Open Graph. My intention is I think Sam and I are gonna find a way to share some links with everybody afterwards, but some great resources.
In this case by Colin, there is also one by one of your colleagues Colby.
Sam Brace: Yep.
Ben Seymour: Tons here to be researched into. Frankly, it isn’t just what we’re talking about today. Today, it’s just the tip of the iceberg. There’s a lot in there that you want to consider from customer acquisition, from social engagement from SEO.
There’s a lot of business benefits to be explored. The final thing in this sequence is I actually was using Cloudinary in one of my other projects. So I have a storytelling platform that I’ve been building for a while and ultimately behind the scenes I was using before you and I met each other, the first time I was actually using Cloudinary to do some very complex image manipulation.
So ultimately within inside the page itself, there’s nine different images. They’re all completely independent, and as you can see, they are varying aspect ratios. Some of them are quite [00:23:00] wide, some of them actually both of those happen to be quite wide, but there we go. Some of them are more square behind the scenes what I did with Cloudinary was, and you can see it just here, it’s actually, it’s a fairly complex command. It’s a multi-layered command, is ultimately I’m taking a variety of different aspect ratio source assets, and I’m doing intelligent cropping on each one, and I’m doing a complex layering sequence to make this single.
So this is a single composite image, which is effectively built from nine other images. I think the most important thing to mention about the Open Graph thing a moment ago is effectively, you get one image. What you do with it is very much based on the tooling that you have. So in this instance, you can obviously argue that Cloudinary allows me to do remarkable levels of image manipulation. But the end result, this is just a single image request and that’s the power where Open Graph gives you one reference, but what you can do with it is quite remarkable.
Sam Brace: It’s interesting because like Open Graph is something that I’ve been talking about, I feel like I’ve talked about for 10 years now, like I might be a little bit off maybe it’s more like nine or but it’s something where this isn’t necessarily new [00:24:00] technology that we’re talking about here. This is something that. I remember when we were teaching people about just running their websites back in like 2014, 2013, and we’re teaching them about this new thing that is coming from Facebook now meta and talking about Open Graph protocols and this is a way to make sure that you can start affecting the way that your metadata looks on social websites like Twitter and LinkedIn and so it’s something where it’s interesting that it’s still so powerful, but in my opinion, it’s still something that people are trying to wrap their heads around.
Because as you pointed out, many times when we are writing this new blog post or showing a new project, we don’t always think about the ways that people discover it on social media or discover it, as you mentioned, for search and optimization purposes. So there’s a lot of deep power with being able to just start thinking about Open Graph and what it means for your project that you’re trying to share with somebody, because pictures get people excited and they get people to click [00:25:00] through, and that should ultimately help in open rates and time on site and all the things that people care about when it comes to analytics. So I think what we’re gonna be covering here about how this is all done is vitally important for anybody that’s just trying to be able to get people to know about the work that they’re doing because Open Graph is a great tool for that.
Ben Seymour: I think the other thing that’s changed over those 10 years, while the protocol has pretty much stayed the same, is that social media has clearly dramatically changed in the last decade. So I think the way that we use our phones and the way that we use various platforms, I think this is the fundamentally different thing where, you know, this is a massive change if you look at the viewing stats between devices 10 years ago, 2014 to 2024 yeah, it is gonna be quite another a big change when you look at it.
Sam Brace: Absolutely. Absolutely.
Ben Seymour: Okay. This was last year where effectively we announced a new iteration of a project that we already had.
And by we I mean Vercel and by we I mean people who are far smarter than me and a variety of other people in [00:26:00] the engineering team. So we originally had, and this is what this blog post talks about, we originally had effectively a different architecture was using a totally different build system.
It was ultimately running on something that’s a bit more like a lambda, like a serverless function. It had various consequences, like maybe slow cold boot times. A variety of weight in the complexity of the library and the environment was being run and led to an amazingly powerful solution.
But which compared to what we released at the very end of last year, actually was quite slow in comparison. I suppose a nice way is to say that the new version is significantly faster, significantly more performant to the point where it’s, I thought what you can say there it’s effectively, I think it was like, 50% faster, even from a warm start.
And if it was versus a cold start, then it was a greater magnitude. So you can see that. Sorry, there it is. Just there. So it was taking maybe four seconds to generate one of these. The modern version is taking like hundreds of milliseconds. No more than that. There’s also a variety [00:27:00] of other things that’s also happened in the way that we’ve replatformed is we’re now using a effectively far less expensive compute, which means that you can start to consider doing something like a hundred thousand of these.
And not be that concerned about the cost that you’d have. If you scroll down to the bottom of this one again, we’ll share the links later, is that actually, for that conference you mentioned earlier, we actually did custom OG images for every single person who signed up for a ticket. So we made over a hundred thousand of these using the same technology, every single one, personalized.
Obviously, from our perspective, we wanted this to be something that was then shared socially on Twitter, everything else to also gain traction and also to gain everything else. So this was the digital equivalent of this thing here that I’m holding up to the camera. We also had for people at the in-person event, this is the digital version of that, and it went down very well.
This also massively helped with certain levels of engagement. People wanted to share it. People then were curious. Some people wanted to know how on earth we’ve done it. Other people and talk more about the conference. So there’s a lot going on behind the scenes. Part of the thing that [00:28:00] greatly helped this become feasible is I mentioned that in that October event we talked about going into a beta release.
We also are now at the point where this thing called edge function is effectively is now a ga. And this was just at the tail end of last year, which opens up a lot of different possibilities. So this gives us effectively a lightweight edge run time. No cold starts, but the bit that also I think gives it really interesting dimension is that it supports web assembly.
So you can take things written and C or rust and you can effectively start to combine all of those and then run them in this same environment, which is why yeah, again we’ve been able to get some pretty phenomenal outputs from it. So our general approach is tons of documentation. Obviously we try and give as many examples as possible.
Our goal is obviously to help everybody get hands on as quickly as possible, to learn as quickly as possible. There’s always a playground because not everybody likes read documentation, but I think the other bit I also love is that we’re massively open sourced. So effectively this is open source and public, so you can see plenty of forks, plenty of stars. And then the other bit is if you want to go and get [00:29:00] hands on, you can just come here and you can grab off one of our repos, a ton of existing examples that you can copy and paste as the start, as to what you do next.
Sam Brace: One thing that’s really cool about this, and I wanted to see what you thought about it. So we’ve, when we’ve talked about Open Graph with other projects in the past that developers have done, a lot of times they’re using systems like puppeteer, serverless functions that are associated. Maybe playwright is another one that I’ve seen come up that’s the same idea as puppeteer, but what, talking about advantages and disadvantages, to me this seems like a much more scalable option.
Like the example you showed of an Next JS Open Graph that you had for the conference is that if you have to create a ton of OG content quickly, this seems to be able to generate that much faster than constantly having to spin everything up from a cold boot, everything that you have from just like basically spinning of a whole browser to be able to just handle this thing. But talk to me about that, cause I, I feel like I don’t [00:30:00] fully understand like the competitive aspect of that.
Ben Seymour: I think you’ve nailed the core points though, so effectively this is a review of the old system that had been built by the team three or four years ago compared to the new version.
So, the old version was using chromium in a serverless function, the new version effectively doesn’t require even a headless browser. So we’re doing it a lot closer to native, which obviously gives you It’s far faster and far cheaper and far quicker. So, normally what is it… Fast, good or quicker? Whatever it is. Pick two. Effectively, we just went for all of them from outside.
Sam Brace: Yeah, you kinda did. I agree.
Ben Seymour: So, we kinda just went for everything. What, why choose two? Two, which you can have the entire lot. So this is ultimately again, Sartori itself is open source. You can grab it and if you really want to, you can go and try and implement it yourself.
We have then ultimately implemented this as a core primitive within, inside of the kind of the cell ecosystem of cell platform, and Next JS is a framework as well. So you can by all means, go and, [00:31:00] follow your own path. Obviously, we think we’ve done a pretty good job and you can probably save an awful lot of time by using ours.
But we also know that people like to go and noodle around for themselves as well. Yeah you nailed it earlier, massively fast, much much cheaper, and much more performant to get those first responses back as well. What I did then was I actually grabbed some of those examples just to show a few running ones.
Shall I have a quick wander through these?
Sam Brace: Yeah, absolutely. I would love to see some of this.
Ben Seymour: Smashing. So, this is yeah, as you can see, this is a fairly simple little bit of code. Ultimately, I literally just grabbed one of them interesting actually, I should have updated these. I mentioned earlier that this this edge is now it’s now in stable release.
Some of these code examples when I first made them, which is was the tail end of last year, actually was still using that version one so I could come back and make this stable these days without using experimental version. One of the glorious things is, from a frontend perspective, if you [00:32:00] imagine we built a website.
It’s mostly frontend skills that have gone into that. Obviously, people who know, html, css, probably tailwind these days. A variety of things in JavaScript may be using Next JS or anything that you like, and yet when it comes to the OG image, The kind of tooling in many cases for a lot of people might well be doing something like Cloudinary manipulation, but a lot of people that I met with were generally building something in Photoshop.
Sam Brace: Yeah.
Ben Seymour: And then doing an export as a static object and then trying to put that somewhere it could be pointed at. I think that step between modern frontend and Photoshop, and I used to work at Adobe and I love Photoshop, but it’s not by any means the same skillset or the same workflow or the same process.
In this sense, the joyful thing is that we’re using html and css tailwind to effectively determine what the layout looks like. So the exact same people who are building frontend experience are gonna be really familiar with how all this works. So hopefully html, css image references can come in.
What [00:33:00] comes out the other end is, this is what’s produced. This is effectively just an image. So you get an image response back. This is me using this one up here – the Vercel OG library and that’s pretty much it actually. Obviously there’s a little bit of a try catches for errors, but this is all you need to do to start your image generation process.
Now what I do as I wander through this next thing is this one here was hard coded, which obviously doesn’t certainly scale. So in the second one, I just chuck a bit of stuff in that says, maybe don’t have a look at this query strings. If there’s a career string parameter in the right name, then let’s start using that to dynamically change things.
This is where it’s slightly tricky with the smaller screen, but in here, this is literally me saying, breakthrough from your constraints. Whatever we put into here, will then be dynamically generated at request time. So this is how you can imagine, you can start to do very dynamic generation of everything.
So you could have one of these automatically generated for every single blog post that you ever do and it supports multilingual. So you could have one of these for every [00:34:00] blog post that you ever do. In the right language for the region where you’re gonna serve it into. So this becomes immensely powerful.
You can start to you can hear, start to couple up your content management system. Your send headless CMSs into your production systems as well. So I think this is tremendously powerful. Next step in here was, let’s bring that one back over to here. Thank you. Next step is let’s use some custom typefaces.
So between these two here, you’ll notice it’s starting to look a lot better. Bit of typography goes a long way. So at this point I’m making a reference to some true type and also to woff. We’ve also got some other very interesting font optimizations for your live website. But that’s, For another time.
So, in here I’m pulling in font file references. So if you happen to be the kind of business that has your own custom font recommended you end, you can then start to make references here. Other than this, check the licensing on your typefaces. I’m also doing a little bit where I’m starting to do some tweaks to things like the background color.
So if you have a look at my blog, there’s a certain color palette that I use in [00:35:00] my blog. So this is where I’m starting to make this a little bit more customized. I’m using better typography. In the next instance, I just wanted to show, again, it might only be a, oops, come on. There we go.
Might only be a single media reference, but this is actually a. The media reference I showed you earlier. So the fact that Cloudinary is taking all of this and is doing the nine image optimization, cropping, manipulation, compositing, and serving means that single image reference is remarkably powerful.
So this is where I think you really start to combine both worlds. If I’d have needed to build effectively a different setup within inside of this this html to handle all of that would’ve been a lot more complex. So I think this is a great place where the two worlds really work very nicely together with each other.
And the next example is really this one that is one of the ones that started it. So this is where I grabbed an asset. I was experimenting with different color palettes and I just wanted to very quickly effectively reverse this. So what looks like if you invert all of the [00:36:00] colors effectively, And this is where I hit a snag, which thankfully again with Cloudinary in my back pocket allowed me to fix it.
So ultimately this is the before and after. So if I do nothing to that image, which effectively was a black liner that was on a transparent background, it’s actually an svg as it turns out. And if things like sanitize so one of the great things about svg is it’s immensely powerful.
One of the bad things about svg is it’s immensely powerful. You can hide just about anything in it. One of my favorite simple commands within Cloudinary, you can sanitize the svg, is to make them a fairly safe to reuse elsewhere. I actually was converting it, background, removing it, and also allowing myself to do things like color change.
So if I come over to here and then there we go. So this is, I think, a pretty beautiful outcome that would’ve been really hard to do without the combination of both those technologies.
Sam Brace: There’s so many good things that are, I’m you’re showing here because one, one showing the overlay situation that you’re able to create with the nine picture grid that you had there.
It does [00:37:00] show really great use cases. To be able to say, if I wanna take this image and that image and the other one, and combine them to create this Open Graph image, or just anything with being able to combine this into one piece of content. Cloudinary can do that with overlays, so I love that L underscore usage and being able to manipulate where the X and Y coordinates are and create that beautiful grid.
But this is also very impressive, what you’ve gone shown here with the overall picture that we was basically black against a black background because again, this is showing the ability to colorize being able to do all of this on the fly, but also programmatically because let’s say that you have this happening across 50 Open Graph images.
This is where, thanks to what Vercels doing, you can scale that, but also you can simply apply some of these parameters into the overall images and you can have them now immediately all affected where back to previous software that we mentioned, it was where that’s not as easy to automate. You would have to go in and [00:38:00] manipulate each single image, do an upload, be able to then pass this into a place where it, so it’s just, this is a very simple approach to being able to handle something that’s very complex and I really love these overall demonstrations you’ve created here.
Ben Seymour: No worries. I do have a few more. If you’ve got a bit more time.
Sam Brace: I would love, I love demonstrations. Keep it going. Keep it going.
Ben Seymour: So, this one is again, ripping on the theme you saw earlier. I’m not gonna show the code. I think you can. I think most people figure out what’s going on behind the scenes.
I’m gonna show the Cloudinary commands that I use behind them. So this is where we started. The idea is we start with a single image. It’s a glorious image that I I found somewhere. The limit with this is effectively, it’s a big rectangle. It’s a big rectangle with a certain shade of blue.
And, the subject in question is the turtle, obviously. But one of the things I really love is this command here. So I use Cloudinary’s background removal in this instance. So this [00:39:00] is me taking that same image. I’m not doing anything to it, frankly. All I did was add another command and then Cloudinary does it for me.
And then I can start to do little bits of tweaks. So this is where I can start to take that existing initial media and I can start to experiment with it. I can start to break it free from those foundations of being in that fully in a big rectangle. I can now make it feel like it’s a part of the rest of everything else.
It doesn’t be like text next to image anymore. It feels like one item being drawn next to each other. And then can do other treatments. Everyone experiment with color palettes. This is gray scaling. Final one for this sequence is one that is frankly, one, again, one of my hugely favorite things, which is Cloudinary has colorblind assist effectively. So it’s this command up here. So if you imagine the kind of work that you end up doing as a frontend web designer in terms of color contrast, when you’re thinking of accessibility from a visual standpoint, this is the treatment that allows you to do something very similar to your images.
As well. And very few people I think, actually remember to do about this. So if you look very closely, what you can see, and I’ve done it in the black and white one, to make it slide more obvious [00:40:00] effectively, it’s overlying overlaying lattices, where the color contrast is different in the image. So if you were somebody who had a colorblind weakness, you may not see those boundaries, and this lattice just means you can more easily start to see the definition of it.
This is one of those things where I wish more people would consider doing this. I have four brothers and two of them are colorblind and they really struggle. It means I get to win at Snooker slightly more easily. But other than that it’s hazardous.
Sam Brace: Oh, I love it. But no, but you’re absolutely right, and that’s the wonderful thing about being able to have all of these thousands of transformation opportunities is that if you want to be able to say, I need this to be gray scale, or if I need to flip the image once again, you don’t have to be going into separate software to do it, it’s just changing the URL or changing the overall parameters you’re calling for that image. So, it’s simple and it shows a lot of the power that Cloudinary is providing to be able to create these Open Graph images. So, I think these are excellent examples.
Ben Seymour: Okay. I already think I [00:41:00] know you well enough to know that you’re gonna quite like this one as well.
So this one is if you ignore the crudity of the mockup, this is a Photoshop file. So we said earlier, this is where a lot of people start their work, especially on the creative side of things. Behind the scenes is a Photoshop file. If I was to change this to be psd ultimately it’s not gonna load because browsers don’t support them.
It’s gonna offer to me to try and download it. At the end of the day, it probably is gonna be 10 meg 20 meg. I’ve seen Photoshop files that were 50 plus meg. So the original asset in here is a very common protocol. Photoshop files. PSD files. Ignore the design. That’s just me. I’m not a designer, unsurprisingly.
So the original file is how many creative teams work, but it’s in a format that really isn’t, particularly helpful for the web industry at large. The joyful thing here is eventually I can just drop a different file extension, Cloudinary does that change for me. Another thing that I really love is this is where I can reference different layers.
So I can actually say which [00:42:00] layers within the Photoshop file to turn on and off. And then I can start to do extraction. So it’s a bit like that background remove from earlier, but it’s also a completely different workflow because this starts with a multi-layered composite that’s probably had a lot of care and attention paid to it, and in the end it allows me to take this same asset and to reuse it.
The investment typically from creative teams in making these assets in the first place, the photography, the photo shoot, the touching up later on to be able to repurpose subsections of that in every other format. I think this is rather wonderful.
Sam Brace: It is.
Ben Seymour: Also, again it’s a different use case, but it’s a very different part of the business that I think we can then start to work more closely with.
Sam Brace: And I think you said it well. I think the fact that with Cloudinary, you can be able to change really any format into another format. And I can’t think of a reason why I would wanna change a PNG to a PSD, but in most cases you would want to go PSD to PNG as you’re showing, or to WebP your JPEG or something along those lines.
But being able to expose details based on clipping paths, [00:43:00] based on layers, that’s something where it’s very helpful because you can give your creative team. The ability to say, put your file on as is. You don’t have to optimize it, you don’t have to export for web, export for screens, give it to me as is and then as a developer you can go and create any type of output off of it, including as we’re showing here, Open Graph content. So this is fantastic.
Ben Seymour: Okay, I have one last thing.
Sam Brace: Oh gosh. Let’s see it. I would love to see it.
Ben Seymour: There we go. One last thing. And we were quite fortunate here cause frankly this only got released two weeks ago.
Sam Brace: I love it.
Ben Seymour: So ultimately, You can imagine doing your local testing. You can imagine dropping into your own WhatsApp and having a look at what comes out the other end.
But one of the things that we always wanna know is what’s this gonna look like to our own customers? So about two weeks ago, if you come into your dashboard, again, this is what you saw earlier. So this is a variety of the releases that I’ve been doing on this particular account. If you come into any one of these, including the preview deployments, we now have a new tab called Open Graph.
[00:44:00] Now, ultimately what this does is this is, there we go. So even against what is exactly a branch, So it’s an experimental release, potentially. This is me and being in a position to see what would this look like to a Twitter user. So it’s all well and good as thinking it’s good, but being able to see what it looks like on Slack or on Facebook or LinkedIn I think is immensely powerful.
It also gives more of a breakdown for more of the aspects within the Open Graph protocol, and it also very helpfully tells us when we’ve maybe forgotten something. So in this case, I forgot to put effectively the URL reference to the canonical link into it. So, I think it’s a great way of verifying that what is about to go out the door is what we hope it’s gonna be. So rather than having to do again that round tripping, there were a few other validators that were sometimes workable. Frankly, they would tend to be a bit hit and miss. There was like a validator on. twitter.dev or dev.Twitter.com.
But this gives all of these in one place, straight into your project, and it also allows you to really run experiments, do a branch run experiment, have a look at this straight in the same place, and [00:45:00] then let’s face it, what you hopefully want to go and do is, if you’re very happy with the results.
You could literally then come along and have this as part of your deployment step. So in some cases this might be that where you go, we’re now happy that even the OG image is ready. Let’s promote this to production. Something like that.
Sam Brace: Well and the key thing I think that you said to me that I was like, oh, yep, that’s why this matters, is that it’s about things that are not in production yet, these are things that will be in production, and a lot of these testers that I’ve have found when it comes to Open Graph, it’s a way to validate something, but it’s already been pushed live because you’re able to scrape the URL. And this is where, based on what you’re showing here, this is something where it’s not deployed yet and you’re still able to test a lot of these various aspects against the way that these services like Twitter and Slack would interpret the Open Graph data that you’re giving to this before everything’s published -everything’s live- people can see it, and that way you’re not having to retroactively say oops, we made a mistake. You can check literally everything about the deployment before you deploy.
So this is a really big win in my opinion. [00:46:00]
Ben Seymour: Perfect. I think we’ve covered everything that I had in mind. Again the potential I think is limitless. That thing at the beginning, which is our goal is to help help developers to create at the point of inspiration. I think there is so much that you could do here.
I think it’s like you said it’s a massively, if we just look at this one segment of what you can do in terms of the way that your business or your project is expressed I cheated, by the way. So for the how to contact me, the easiest way for me was actually was to actually use one of these tools very quickly to chuck it up there.
Yeah. This to me is quicker than frankly, opening the slides tool and adding it in there in many cases. So I think that created the point of inspiration, experiment, local iterations. The faster you can move, the faster you can find what works and what doesn’t work. The faster you can get feedback, the faster you can do that next cycle.
I think this is the way that we ultimately find our organizational and our team health, if that makes sense. Let’s face it if I [00:47:00] think of the number of changes that happened in our industry in. We talked about in the last 10 years in terms of the growth of mobile and social tool intensive purposes.
But I, I think kind of 2020 through to 2022, obviously there were a lot of health challenges that caused a lot of the biggest changes to all of our everyday lives. The ability to developers to be able to go and figure out how on earth to help their business survive in that environment, I think that’s something that, that we can both greatly help lots of people with and hopefully help them be very successful and their business is healthy as well as they go.
Sam Brace: Absolutely. Absolutely. I, and I think the biggest takeaways that I’m seeing here is that one, the image gallery situation that you in showed to me, it has a so much applicability to, I would say, lots of different businesses because the example that you gave. That it makes perfect sense. You were trying to do a summary of content that happened around an event, which was Next JS conference, but I could also even see this applied for e-commerce purposes, where if I’m trying to show a collection [00:48:00] of all of the shirts that we’re gonna be debuting and have that, where now I have a developer say, Just point to this folder and now we can display all this and then give this out to the media or to an agency and they can be able to see all of this.
Its ways to take a lot of the concepts that Cloudinary has done with collections, but make sure that they’re being able to show hundreds of them and also in this nice gallery format. So it’s one way to take additional steps forward with that. So I think there’s if I was watching this.
Even if I wasn’t a developer, I would be able to see there’s a lot of use case behind that image gallery that someone can bring into the business today. With the two businesses, of course, helping along the way.
Ben Seymour: So the thing that if you ever invite me back, the thing I’d like to talk about next time is that effectively the latest version of Next JS went into stable last week.
Sam Brace: Okay.
Ben Seymour: And it allows us to have, so in the version we looked at earlier, it was the page level data fetching the latest version, which is called [00:49:00] the app reactor effectively allows us to have independent components. Within a page, each of them doing their own independent data fetching. So what I showed you earlier was this page, let’s refresh this page every hour, whatever it was.
In this instance, we can say, the top section the nav and the footer will not change or at least will not change for a long time. And you can then have independent boundaries. This is all of the back of I think all React server components that came out. React 18. This allows us to have completely independent pockets or components, or you might wanna say composable architectures, which would allow us to effectively, take everything we’ve just seen right now, but make it effectively at the component level. So now we can start to have everything we’ve just seen, but as being a subsection of your page and then reused across different pages as well.
So I think this is where I imagine we’ll find that a lot of traction is found. I think so.
Sam Brace: Oh yeah. Cause now if you think about it, like you could have multiple galleries, if I’m understanding that correctly. And then it’s [00:50:00] where you can, if so many brands have these brand portals or they have these like media rooms where we could say, here’s a picture of all of our CEOs and here’s all of our brand assets, and then here’s like our latest press releases, all that stuff.
If you had them where individual pieces and you’re all able to say, point to this folder, point to that folder, point to the other folder. And it just keeps getting updated. That’s huge. And that gives people an immediately developer friendly media portal that they can work off of. Ben, that’s pretty slick.
Ben Seymour: I love the idea. And we got, we have got a minute left, haven’t we? So I love the idea of e-commerce website a PDP per detail page. There’s a component lower down, which is like the product in use. Which effectively is customer uploaded via a load of the Cloudinary tools with auto moderation turned on.
But then allows us to fairly streamline the entire, that workflow, which then would couple in with the kind of the automatic recognition tools to then allow us to go, this component should be [00:51:00] anything that is being tagged as being suitable an on-brand of the right product, and then it gets pulled in.
So your product in use is effectively, almost like able to update kind of day-to-day as people post things onto social media or if it’s a big event. Obviously, we we had a big event in the UK a couple of days ago and lots of people wore interesting clothes. This is the kind of event that then gets a lot of media attention if you have to be a brand that is trying to totally relate in that world, having those very up-to-date components of project and use or, social usage.
I think it’s massively difficult to do. Without the right tooling but also massively powerful as well.
Sam Brace: Oh, absolutely. Absolutely. And I think the other big thing that I’m standing out to our, and it’s not the first time we’ve ever said it, but it’s where I think the way that it’s been positioned in this episode is that when you’re thinking about a project and releasing it, truly like what are all the components of this?
One thing that development teams should be asking for and seeing how they can help with is, Open Graph is before we push this thing live, before people are gonna [00:52:00] start consuming this, do we have Open Graph content for it? And I think with the power of that Vercels developed with all of the OG image generation, it makes it that’s something that actually happens.
It’s not where you now have to go off to a creative team. You have to go off to somewhere else and say, go make this for us and bring it back. Or just bring through the header of the post, which sometimes is not correct. So it’s to say no, we’re gonna create new, unique content, but it makes sure it happens with every deployment.
So I think that’s really big and it’s something that I hope more that are tied to project deployment start thinking about as this is a necessary component of the process and the project.
Ben Seymour: So this is my blue sky email. Twitter, yeah. Do we have a way of getting links out to people? So can we do follow ones?
Sam Brace: Great question. And it’s a great segue, Ben, because at the very end of this episode, of course, we’ll always be able to release this out to the various networks that we happen to be on. So that’s gonna be [00:53:00] on YouTube, Spotify, Cloudinary Academy, of course, other places, and we’ll always include deep show notes so that way all the links of things that I’ve referenced that Ben has referenced, they’ll all be available and that’s a great way for me to bring it back to be able to explain that.
All of that, of course, is on our cloudinary.com/podcasts page. So as you can see, looking at a previous episode where our friends, Amy and James from Compressed.FM podcast. You’ll see that we have lists of all the places where you can reference the details. We have full transcripts of all of that.
And one thing, I don’t know if, Ben, you’ve seen this, but I love showing this off, is that these are all little JavaScript calls. So if I click onto this, it’ll actually jump you to that particular minute mark of the episode. So if you’re seeing something like, when did they talk about that, it’ll go straight to that portion.
So lots of nice little usability details that we have when it comes to the ways that these podcasts are debuted. But yes, all links will [00:54:00] be available once this is live past the live stream.
So I would say this was good.
So Ben, thank you for being part of this program and of course we’ve given lots of people, lots of ways to communicate with you, whether it’s through your email, whether it’s through your Twitter account. I’m of course you’re very active on LinkedIn as well. Is there any other places where people can communicate with you? I know that you have a really nice personal page. Is that one that was mentioned on that?
Ben Seymour: There is also benseymour.com as well, but yeah, lots of places there. But yeah for everything else, we’ll share the links obviously. There’s me personally, there’s also Vercel
there’s obviously an entire team that will help answer any other questions that we have. And if it turns out that we need to get other people involved, we can always get either the DevRel team involved or some of the community people and other people as well. Amazing.
Sam Brace: Wonderful.
Ben Seymour: Thank you, Sam.
Sam Brace: Wonderful. Ben, it’s been such a pleasure to have you here and thanks again for being a part of this and for everybody that’s watching and listening. Thank you for participating and [00:55:00] enjoying this program from Cloudinary. And we hope to see you watching listening to future episodes of DevJams. So take care and we’ll see you soon.
Ben Seymour: Thank you all.
2023-11-27
Serving Optimized Docusaurus Images with Rehype, Markdown and Cloudinary
In this Cloudinary DevJams episode, open-source software engineer John Reilly shares his plugin for the React-based optimized site generator Docusaurus. It uses Cloudinary for serving optimized images! Using Rehype and Markdown, the plugin fetches images from their original source on his blog’s server. Then it optimizes them by updating the URL structure to be served via Cloudinary and its associated content delivery networks. Cloudinary’s Customer Education team takes a closer look at how John is using Markdown and his plugin to improve the way images are served via Docusaurus. Whether you’re new or experienced with the associated software and frameworks, join us to learn more about ways to streamline your website optimization efforts, so you can focus more on your content.
Sam Brace: [00:00:00] Hey everybody. My name is Sam Brace. I am the Senior Director of Customer Education and Community, and you are about to watch and be part of the latest DevJams episode.
So in this episode, we are going to be talking with John Riley. He is a developer that’s typically been doing lots of things in the open source space. He’s tied to software engineering. He’s done some great stuff for his overall brand, understanding what he’s doing in the development space, sharing his learnings with people on his personal website.
And what we’re gonna be talking about today is work that he’s done with a platform called Docusaurus, which is a great way to be able to create sites, which is a React based site generator. And a lot of companies are moving to it for showcasing your documentation and being able to build that in quick ways.[00:01:00]
But what he’s been able to do is create a plugin with rehype and be able to incorporate Cloudinary into his overall Docusaurus presence. So this is a way that he can start being able to deliver all the images through Cloudinary so that way they’re optimized. They’re also delivered through the content delivery networks that we work with and many other amazing things.
And John, of course, is one of many that we’ve profiled on this overall DevJams podcast, which is where we talk with developers who are doing inspiring, innovative, interesting things with overall development. And of course, probably tied to images and videos because they’re gonna be using Cloudinary for those.
That’s why we’re here. So joining me for this episode is Jen Brissman. She is a technical curriculum engineer at Cloudinary and a prize team member of my team. So Jen, welcome to have you to the program and talk a little bit with John.
Jen Brissman: Hey, thanks for having me.
Sam Brace: Jen, talk to me about why you think this is gonna be a good [00:02:00] program. Tell me about why you’re excited to talk to John today.
Jen Brissman: I’m excited to talk to John because he’s using Cloudinary in a pretty simple way, but it’s a way that I found to be really creative and it’s not one that I’ve seen very often. So, I think this is an episode where it’s not such a specific use case. So many people can watch this and take their learnings and apply it to what they’re doing. So, I think this will be a really helpful episode.
Sam Brace: I agree. I agree. And this isn’t the first time we’ve dived into markdown and to rehype and some of the concepts that we’ve covered and we’ll cover in this episode. But it is to say there’s a reason why we’re covering it again because. Markdown continues to be an amazing thing for people to be able to do, to be able to author HTML and be able to work with it in certain ways. Rehype is an excellent way to be able to start handling a lot of the processing parts of it.
And Docusaurus seems to be one of the more interesting up and coming products that I’m seeing in the overall space because it does make publishing so lightweight. So it is to say that there’s a lot of cool things that he’s gonna be [00:03:00] doing with Cloudinary, as you’re saying, not necessarily pushing the edges and boundaries at what our product can be doing, but it is making content authoring and content publication much more simple because I think with the techniques that John’s showing, it’s gonna make it that much easier for people to really focus on the content. And not focus on necessarily optimizing every single thing in a manual way. Just set it, forget it, it’s done. It makes it simple.
Jen Brissman: Absolutely. Yeah. And he’s really just hard coding in using Cloudinary as the domain, and I just hadn’t seen that before, so I know we’ll, I don’t wanna spoil anything. I know we’ll get to it, but I’m really excited to welcome John to the episode.
Sam Brace: Absolutely. And so one thing to point out before we jump into our conversation with John, of course, is that this is not the first time that we are doing our DevJams podcast.
In fact, we’ve been doing this for years now, and you can see all of the great content that we put out with developers like John and many others at [00:04:00] cloudinary.com/podcasts, as you can see on the screen here. So simply going through, you can go through all of the various archives of the content that Cloudinary provides in the podcast space.
And if you want to continue discussions and meet with developers like John, who are active members in our Cloudinary community, you just pop on over to the Cloudinary community, and that’s gonna be at community.cloudinary.com for you to be part of all those discussions. So you could ask questions, get to meet new people that are probably dealing with similar things that you are, which is working with images and videos and digital media.
So we recommend those two spaces. If this is starting to tickle your interest a little bit, some of the things that me and Jen are talking about today. So without further ado, unless Jen, do you have anything else before I pop over to our friend John here?
Jen Brissman: No, we’ve been building it up, so well, John, we’re ready for you.
Sam Brace: Excellent. John, welcome to the program.
John Reilly: Thank you very much. Hi, I’m John.
Sam Brace: John. Good to see you. Good to see you. So [00:05:00] John, tell us a little bit about yourself. I mentioned open source, I mentioned software, I mentioned plugin development, but of course those are just little parts of the overall probably story that you have.
So tell us a little bit about John.
John Reilly: Yeah, sure. My name’s John. I’m a software developer. I live in London. I work for Investec, which is a bank, which does some pretty cool tech stuff. And I’ve worked in open source for probably more, more than 10 years now I’d say.
And a lot of what I’ve done has been like around like the language type script. I was a very earlier adopter there. And like I’ve worked on a number of projects there that are particularly have been useful as part of a type scripts journey. Like definitely typed and ts loader, which like brings together like webpac and type script and things like that.
But yeah, one thing that I started doing also, around at the same time that I started like open sourcing was I started [00:06:00] blogging and like originally I started using blog spot, which was like, I think Googles like a blog platform, which was out there. And it was super easy to use.
And I used that quite happily for many years. But actually interestingly probably influenced by some of the stuff that we’ve been doing investing, which was like, we are a very infrastructure as code-y type place. I was doing like infrastructure as coded like my day job and my blog was still this just html on someone else’s website.
And I was like, oh, I should own my own content. And so I had this, and also I’d really got into liking markdown, like the gears of back down, the open source minds. Not that I I wrote like markdown, like a native, like better than I wrote anything else. And so it was just like, it was the obvious me way for me to write stuff.
And so I started like reaching around looking for a way that I could take take my stuff and move it like literally into code. And there was lots of things like around, at that particular time that seemed to be like filling that [00:07:00] gap. And but the thing that was like most notable was Docusaurus.
Partly because it, like it fit like really well. But also because oh I looked at, it’s wait a minute, I’ve seen this before. I’ve seen like lots and lots of Docusaurus sites like out there. And you realize that just like tons and tons of like sites that you know and use let’s say temporal site for instance they’re built using Docusaurus because it’s a very simple tool that allows you to build, like it was originally designed for the purposes of documentation. It comes out of like Facebook, out of meta. Like it was built there as an internal docs tool, but it kinda evolved and became more, and the reason I got interested in was it because it has like a blog component to it and that mechanism just like works really well.
So lots of people use it like for that as well. So yeah, so I started using like Docusaurus and although like a personal rule for myself for like many years, I was like, I will not, I’ll just focus on things that I’m writing about. I won’t like fiddle with the mechanism of writing it. Like [00:08:00] I, I couldn’t resist it.
And like I I’ve fiddled with Docusaurus is aware of, I’ve contributed it like a number of things. Back to to back to Docusaurus I’ve written, so the thing that we’re gonna talk about today, like plugins for Docusaurus, which which are useful, and I use on my blog.
Sam Brace: I think it makes sense what you, how you came to Docusaurus based on what you’re describing. And it also makes sense why you’re using Blog Spot. Probably at the very beginning. I feel like we’ve all gone through that journey where we started a blogger or we started a blog spot, or we started a WordPress, or we started that and then we find that maybe that worked, but maybe it’s also where we found something that fits us more personally.
And as someone that is an open source contributor, to your point, like if you have the ability to do pull requests and contribute to the growth of something that seems to fit who John is, in my opinion. So I think it makes perfect sense why you would land on that as your platform for blogging and brand presence.
And once again, very [00:09:00] astute, you should own your own brand because if suddenly Google or WordPress decides to take something up or down, then it doesn’t matter because you still own your domain. So I think there’s a lot of wonderful aspects to what you just described there. Now, one thing I did wanna ask you about with this, with Docusaurus was from a developer side of things or a programming side of things, is there anything that really stood out to say, this is why I should use Docusaurus?
Because in my research I, of course it’s React based, as you mentioned, it was coming out of some of the work that was coming from meta, which makes sense because React did too. But was there anything that kind of tickled your brain when you’re saying, oh, that’s why I should be looking at it, particularly other than just the open source nature of, or the temporal usage that you mentioned earlier?
John Reilly: Yeah, it’s interesting you say that, because I was intentionally not looking, I never planned to do any playing with it at all. My plan was I want to use a thing that will just allow me to write markdown. That was my goal. I wanna write markdown and I want it to be pretty, [00:10:00] because I can’t make things pretty, I don’t have that in my wheelhouse.
So I need something that will look good from default and this looked good, and it allowed me to write markdown. And that was the way it was set up by default was like super straightforward. Like it’s just text files on disk, like in folders. There’s not much to it like it… technically, like it’s probably someone who has some, like engineering smarts is gonna be using Docusaurus. But it really, you don’t need to like, like vanilla Docusaurus and just text files and you’re off to the races. You have a website that looks great, that looks presentable, that is easy to maintain.
Those are the things that I was looking for. It was a surprise to me that that that I ended up like digging into it and contributing like back to it.
Sam Brace: And I gotta tell you, you could see on my screen it looks great. It’s if this is how, if this is vanilla Docusaurus or like without a lot of work…
John Reilly: Pretty much.
Sam Brace: It’s clean, it’s easy to read. And if it makes publishing fantastic for you, then [00:11:00] it’s a fantastic tool. So I think this is really nice. And you can see here, your domain presence is for everybody. In case they’re like, oh wait, where do I go? Just to make sure we’re clear. Everything we’re gonna be talking about is tied to your domain, which is johnnyriley.com. So if people are falling along or if they wanna see any of the posts, this is where everything’s gonna be based out. All right. Okay, so I’m looking at this. So we’ve chosen Docusaurus. Markdown, that’s something that would be good for us to unpack just a little bit. So why was markdown so important to you in the publishing process?
Because obviously, in my opinion, as we’ve said, markdown is an easy, fast way to be able to author content because of just the way that it works with html, it also makes sure that, in my opinion, one of the biggest reasons I like it is it makes sure that things are very modular. Because markdown is here, it’s the same markdown there.
So you could pick it up, move it, it’s gonna work. So if you ever decided to move things out of Docusaurus, for some reason it’s still markdown. So it’s a huge benefit to it. But what was the reasonings, why you said because of markdown, [00:12:00] this is why I chose Docusaurus?
Yeah. That’s
John Reilly: a good question. So, I think it’s slightly like two things, and like one of those things, one of those things is I just like markdown, Yeah. It’s I like it. I know it, and it’s simple. And like the other thing is I feel like it was like a Douglas Adams quote or story or something like that that he was talking about, like how like one of the things that like slowed him down in life was like the invention of the word process processor.
Because he like, loved like technical things. And but previously he’d only had a typewriter. He was hammered away on his typewriter and all, he’s got all, he’s got a key presses and ink on paper. That’s all he has just the keys that he can press.
But now he’s got like a word processor and he’s got these, all these options in front of him. He can hear for, he can have like line breaks. He can have which [00:13:00] font do you use and what size font, or maybe it’ll be bold or maybe it’ll be underlined. And all these type they’re just options. Like you’re blinded by options.
And options are actually, constraints are actually a really useful thing because they allow you to focus on doing something. And markdown is constraints. Markdown like you’ve got you can have text, you can have something like five or six types of headings. You can have bold, you can have italic you can have strikethrough and not much more, to be honest.
There’s very little that you can do with that. And it’s like a personal rule I had around writing generally was that you want to remove all the things that like distract like from you. You want to just be able to focus on doing the thing that you’re doing, and if you have like options, you are gonna explore those options and you’re actually gonna do the thing that you really want to do in the first place.
Markdown is a great way to make sure that, that doesn’t happen. Like you are working, like just on doing the thing that, that you want to do. And [00:14:00] that will hopefully mean that you are your productive, right? You’re actually like writing a blog post rather than thinking about like the way that you could write a blog post and the CSS that you could apply to it and all of these things.
Does that make sense?
Sam Brace: It does make sense. As somebody has young parents, I’m always a big believer in limiting the amount of choices that I provide to my kids. So if I want them to choose between, let’s say, a quesadilla or pizza, I’m only gonna give them those two but I give them like a whole menu.
They become overwhelmed. It’s actually less than comforting. And then of course, and no decisions are made. So I think to your point, like if you have a limited set of things that are possible it allows you to focus on the tool and make it really good and focus on, as we said earlier, focus on the content, not the tool, not the tactics.
So I think it makes tons of sense why everything is aligning the way that it is. The story is making sense to me.
Jen Brissman: Yeah, not only is this a great metaphor for life, but this is also something that John, you have in common with a lot of developers is [00:15:00] go for the easiest, most simple way to do things, and it seems like that’s the way that you found Docusaurus, and that might be part of the way that you found Cloudinary, and that seems that’s also the way that you like markdown.
Sam Brace: John, I’m interested, so can, we’ve talked about Docusaurus and I’m anticipating there’s a world where now you’ve signed up, you’ve got everything running with your Docusaurus site. There is a period here though Cloudinary is not here yet. So how does Cloudinary get introduced? How does Cloudinary get brought into this overall process?
John Reilly: Yeah. I’m definitely a fiddler and so yeah, so I’m always like noodling around on something and I really like optimizing stuff. I really like taking a thing and seeing how I make it like slightly better because then it’s like better for everyone. And [00:16:00] I had my blog going and it was working and it was fine and lighthouse scores like was a possibility.
Like lighthouse scores. For those that don’t know lighthouses at all. It’s I think it originally comes outta Google. It’s certainly built into Chrome, and it allows you to like, evaluate like how your website is doing along with various like metrics. Like it tells you how you’re doing for like SEO, it tells you how you’re doing for accessibility tells you how you’re doing for like performance and like other things too that I can’t always remember.
Yeah. Awesome. And I’d plugged light. I’ve been running my lighthouse against my blog, like here and there and looking at the numbers, that’s quite interesting. And I worked out a way to get lighthouse running on my blog every time I made a pull request. So actually I should back up a little bit further.
So, my blog actually wasn’t originally hosted on it was originally when I went to Docusaurus, I was using [00:17:00] GitHub pages, which is like the built-in like hosting mechanism that exists on GitHub and it’s great. You got like this free website basically. And I was using that initially and I really liked it.
And then I became aware that I would make a change and I’d see that change. Like locally, but sometimes there might be a difference between what it was like locally and when it was deployed. And I thought it would be nice to see what it was like deployed before it was deployed. Netlify were out there to offer various, like jam stack-y things, and they had like a mechanism called deploy previews, I think, for a while I used that and I really liked it. And what happened with deploy previews was that every time you every time you submitted a pull request, it would automatically generate a new version of your site and put a preview link in one of the comments, and you could click on that.
You could click on that preview link and you could see your site and you go, “Oh, yeah, okay, it looks like that, looks like this works like this. I’m happy or not”, [00:18:00] and then make a judgment call as to whether you’re gonna merge that pull request, and that was like, just like a really nice thing, I liked that a lot. And like time went by and, but I didn’t I wasn’t using Netlify to host my thing. I was using GitHub pages to do it. And I think Netlify was quite expensive. So I landed on using Azure Static Web Apps which is an offering that that comes out of Microsoft and is very similar to lots of the things that Netlify is doing, It’s basically a static web app.
Sorry, I’ve just said that it’s…
Sam Brace: You’re good. You’re good. I’m following.
John Reilly: It’s html, CSS, and JavaScript, right? Yeah. That’s what it is. And it’s and it works really well. And I started using that and one of the reasons I started using that was cause like, It worked really well and I quite liked it, but also it had the equivalence to Netlify deploy previews, and I can never really remember the name.
I think it’s called Staging Environments or something like that. But it’s the same deal, right? You’d make you change your code, you raise a pull request and [00:19:00] on that pull request automatically in the background an environment would be created and “BLAM”, you get the link, you can click on it, you can go look at, it’s great.
And now I’ve got this mechanism that’s working and it’s working. I’m hosting using static web apps and I’m doing a deploy previews using static web apps. So I’ve got these two things like in tandem and with that in place that like it was… Now extra things are possible now that I’ve got that in place.
And that’s when I plugged like lighthouse in there and I was immediately dismayed because the numbers were low for my performance. I was good on most of the scores, but the performance one I was just like less good at. And and this got me thinking about like, how can I make those numbers better?
Becasue every time you submit a pull request, you see the numbers and it’s “oh, I want that to be less orange or less red. I want it to be closer to green”. And so yeah that’s the thing that started me like in the direction of of like ways to tweak that. And like initially I was, okay, I’m going [00:20:00] to I’m gonna like manually take each image and I’m going to optimize them, which was very boring.
But I did that for a while, and then I got a mechanism for making images somewhat more optimized. I scripted something, which was quite good. But it was I was also getting I was getting improved scores, but like not amazing scores and it then occurred to me though the Cloudinary, which I had used in the past for like different things was there.
Oh no, it wasn’t it. A friend Howard is behind Azure Weekly works for endjin is one of the founders of endjin. He was telling us how they were using they were using Cloudinary for their images, for the endjin blog, I think.
And that got me thinking, “Oh, wait a minute. I’ve used that before and for other stuff”. And I yeah, I just got started reading up on it and and the more [00:21:00] I read about it, it was very obvious that there was a possibly very straightforward way to, to plug into it. And it felt like there was a possibility there, which I dug into, and that’s what ended up with me like starting to use starting to use Cloudinary, like for my blog.
Sam Brace: I love it. I love it. And, I think it makes perfect sense because that is a main reason that people do come to Cloudinary, at least it’s one of the main reasons, is that they’re looking at ways to optimizing their website, making sure things load quickly.
And sometimes that is tied to Lighthouse. Sometimes that’s tied to Core Web Vitals, essentially indicators that are telling people, this is how good the user experience is on your overall page. And by making sure that yeah, you’re, tweaking, you’re trying to get things to go right. But it’s also to make sure that when people are going to your blog and reading a post, they wanna have an optimal experience.
They don’t want it where there’s something slowly loading through because you decided to put a three [00:22:00] megabyte image in there and you’re not sure why the scores are low. So it allows for that to take place. It, absolutely makes sense to me.
John Reilly: Yeah, I’ll be on my, I’ll be on my phone like on, on a bus or something sometimes, and I’d go to my own site to check a thing that I’d written and “oh no!” – do you know that experience?
Sam Brace: Oh, yeah. Everybody’s had that experience really. You’re suddenly surprised about the how was beautiful on a desktop and everything loads so quickly and I’m my amazingly fast internet. And then, yeah, you’re now out and about and you’re like, this is not optimal. So I, I totally know what you’re talking about completely.
John Reilly: “You did this. You did this.”
Sam Brace: “It’s your fault”. Exactly. I know, I totally know what you’re saying. Okay, so we know the reasoning now. So you have this pain point that’s happened. You’re saying, “okay, I want a better lighthouse score”. I want a better user experience that’s coming through.
So you’re seeing Cloudinary as a solution here. What I am very intrigued by is how you went about this because you created a plugin [00:23:00] with rehype or for rehype, or I’m not sure exactly the right way to phrase it, but essentially a rehype plugin that is going about the process and adding all of these to your Cloudinary account images that you’re working with on your Docusaurus side of things and making sure we’re delivered with our CDNs that we work with, and also applying some optimizations too. So how did you start the plugin process? Why, or even why did you start the plugin process this way?
John Reilly: Sure. So the reason like why, like I got the idea in the first place was cause there’s Clarity is like a ridiculously nice API for for doing this, which is and you’ll probably know the proper name.
I don’t, maybe it’s called the fetch API or something like that, but could…
Sam Brace: Yeah..
John Reilly: But it’s like… Here’s the thing, you’ve got like an image URL and you can just like basically prefix your image URL with a Cloudinary CDN, something type like prefix like that’s it. You’re done. [00:24:00] It works like you…
Like when you do that, you get like what happens is the request like snakes off to Cloudinary and like behind scenes Cloudinary is gonna pick up the image from your site. It’s gonna optimize it and serve it. And that first time, I’m guessing there’s probably like some kind of like slowness.
Cause it’s doing that, that hit for the first time. But after that you’re off to the races. You’ve got this optimized images going through all of your clients and it’s just it’s just fast. And like the simplicity of just like plugging that in was just like really attracted me.
So cause I’d imagined maybe Howard told me this is how it worked in the first lesson I forget. I’d imagined that if I was gonna do something like this, what we probably need to do is I’m gonna stack out, I’m gonna write some kind of script that crawls my blog post finds all the images.
I’m gonna have to like, some kind of mechanism to upload the images to the thing, and then I’m gonna have to go back through the site and I have to change all the references. And I was like, that was, yeah, I was open to that as an option, like incidentally. But it was like you said that to be way simpler.
I like [00:25:00] didn’t have to do that. I can just instead flip a URL and I’m done. So the simplicity of knowing that I could do that made me start like fiddling with like Docusaurus and looking into is it possible that I can do that? Cause I didn’t, I don’t think I necessarily knew at that point how that portion of Docusaurus like works.
Like I knew that you could put in markdown this side and out this side comes like html. I wasn’t totally sure like what was in between, and as I had a little read around and chatted to the to the the people who work on the project a bit. Like it turns out that it’s like this, and I might get this in the wrong order.
I’ll try not to. Docusaurus takes markdown and it uses a mechanism called re-mark plugins. And and that converts the… That takes the markdown, I think and converts, sorry. It takes the markdown and converts it [00:26:00] into html I think, and then or Jsx. And then you’ve got that, and you’ve got these two places like the re-mark step and the rehype step.
And in both places you’ve got the ability to like hook in and Docusaurus, like allows, like it exposes those hook points as it were. And in fact, it uses those itself to to build itself. And so I did exactly that. And so I was looking, I’ve got this like re-mark like hooking place and I’ve got this like rehype hooking place.
I wonder if I can use this. And like the initial thought was like, okay, maybe I’d maybe do with like re-mark cause that’s where my images are and it’s like super simple to go with. But actually it turned out that The rehype was the was the like the more obvious choice. Cause that’s like closer to the image generation point of view.
Cause don’t wanna jump too far ahead. So the way that the you ended up handling like the images is that you, would, you end up with this I’m probably gonna get to the [00:27:00] code. You end up like walking through every like node inside the html every tag, html tag, what, whatever it’s that, that comes through.
And some of those are like image tags, which are obviously images. But some of those are JSX tags. And those JSX tags are like React things. And inside the JSX you have to do a little bit of parsing inside there to discover like the image that sits inside the JSX, and you have to swap it there as well as the near things.
You’ve got two places where you’ve gotta do the the swapping and because Docusaurus it, it allows you to do like markdown, but also if you wanna let break out and do something like JSX, that’s, you’re often you’re fine. You can do that too. Like this mechanism made more sense in the context of rehype because it would cater for both mechanisms, I think. I think regardless of whether you are using markdown or JSX, I think both of these things ends up playing through that.
Sam Brace: Which is [00:28:00] fantastic and the end result you, as you can see here, so this is the title image of the post that went through this. And you can see some of the things that you talked about.
If you look at the overall URL that was generated through Cloudinary, you can see it is using that fetch method here.
John Reilly: Yes.
Sam Brace: And what you would see, let’s say you just had uploaded this to your Cloudinary account, of course I would say upload in this case. So it’s really tied to the overall delivery.
So this is fetch delivery that we’re showing you here. So to your point, it exists somewhere else and then we’re porting it through with fetch. So that way then we’re able to apply all the various transformations and you can see exactly where it was coming from in the first place, which is from your domain, the assets, images, this is your title, and to be rerouted to Cloudinary.
And then of course delivered through Cloudinary in this overall process. And this is all done through the magic of the plugin that you did, which is fantastic because yeah, as you, as we’re big believers of, Jen can attest to this, we’re big believers of you should set it and forget it. Meaning that [00:29:00] you should allow all the automation, all of the behind the scenes to do the behind the scenes stuff.
And this is doing that where when you publish something to your overall presence via Docusaurus, it makes sure it’s doing all of this work behind the scenes for you. So this is great to see.
John Reilly: I think the image that you’re looking at there sound like that’s PNG I think, and I think that one of the things that you get with Cloudinary, one of the things that I quite liked about it was that it would take your PNG and it would turn it into something that was like more optimal for the clients. Like it may possibly even does it, depending on the type of client. I’m not even sure but…
Sam Brace: Yeah and very astute what you’re showing here. So let me see if I can show my screen on that real fast because you’re dead on. So what we are showing you here is I’m gonna quickly bring over a little bit of a behind the scenes here. So you can see in this case, this is using what we call Cloudinary’s Media [00:30:00] Optimizer or Inspector, Cloudinary Media Inspector.
And it’s just a quick Chrome tab that I can be able to click on. So I pull this up and it gives me all these details. And as you can see here, yes, you’re, you serving this as a PNG originally, where while you’re deliver your, this is a PNG originally and Cloudinary is serving this as an AVIF, which is AVIF file, which is pretty cutting edge stuff.
But Chrome can deliver that. And the reason why that’s happening is of course, this little guy right here, f_auto, which is indicating automatic format. So what it’s saying is serve it through our server here so you can see it’s choosing Fastly in this case. So it’s coming through the Fastly CDN, and in this situation then it’s coming through as an AVIF, and if we just do a little bit of comparison ever before, I am a hundred percent sure that our PNG originally is much larger than the 17.82 kilobytes that is being served [00:31:00] as today thanks to f_auto. And as you can see, if someone knows Cloudinary transformations the way that me and Jen do, maybe not, but it is to say that there’s no resizing happening.
This is the original size of the image. You’re not you’re not cropping it, you’re not changing the width, you’re not changing the height. So essentially you’re taking an original image and you’re saying, all I’m doing is applying the f_auto the q_auto there is a w_auto that’s here. So that’s meant for resizing purposes and responsive situation, but we’re serving this image as is against my size.
So it’s just serving it as it’s original. There’s no changes there. And same situation with DPR is gonna depend there, but it is ultimately to say, a lot of optimization is happening just with this transformation set you have, and then it’s not even where you had to upload them all to a new location and deal with migration.
Everything’s kept with your Johnny Riley overall space. So everything can still live within your domains and your overall path that you have of assets, images [00:32:00] there. So a lot of good things are happening right here behind the scenes.
Jen Brissman: And just to add to something, Sam said, the image is actually a smaller bite size, but it’s not made to be visually smaller. So yeah, it’s optimized. But I have a question for you John. So basically, as we know, Cloudinary is gonna fetch the image from the original source and serve it to you. And in this case as we’ve just looked at optimized, but I happen to know something about you, something that you’ve said in another blog, which is that you’re “more of a fetch guy”.
You, you are a self-proclaimed “fetch guy”. So you like fetch. So this is. You said this in a blog just about a month ago. Another blog about Cloudinary where you were comparing to someone else’s blog and you wanted to be able to do it with a fetch.
John Reilly: Possibly. Yeah. Quite possibly. Yeah. Very possibly. Do you know which, which post it was like, I…
Jen Brissman: Yeah, yeah I do. So it is let me find it here. It’s [00:33:00] uploading images to Cloudinary with fetch.
John Reilly: Oh yeah.
Jen Brissman: It wasn’t as recently. It was actually a while ago, but it was in March, a couple years ago.
John Reilly: Yes. This was the, this was cause this is the I got the name confused. Yeah. So this is the first time that I used Cloudinary, I think for that one.
Jen Brissman: Yeah.
John Reilly: And that one I. Gosh, it was, man, it was some years ago actually. Yeah, with that one I was using the fetch API in the browser to upload. So yeah, it was I was using the fetch API in the browser to, to do an upload to and I think maybe even when I wrote that post, like the fetch API was still felt relatively new or something.
Like it hasn’t been around for like forever as it were. I do, yeah. So yeah, prior to like fetch there was the xml http what it thing Horrible. Okay. Fetch is just like a very nice API. But yeah I dunno if the fetch in Cloudinary has a relationship to the fetch in the browser APIs or not, or it may be that they are related things [00:34:00] or they’re different things. I don’t know with similar names.
Jen Brissman: Well, the reason I ask is because we don’t see a ton… I mean, people use Cloudinary in various ways, but the way that you’re using it is very fetch specific. And when we get into the code in just a moment, we’ll see that you’ve hardcoded in that it’s a fetch. And that’s part of, so I was gonna ask, is part of the reason you chose Cloudinary because you wanted to be able to fetch the images? Or is that just like the way you started using Cloudinary and that’s how you’ve always thought of Cloudinary?
John Reilly: Oh no, it’s more cause like I’d imagined when I was thinking about this in the first place, that I would probably be using the fetch API in the browser to do uploads like to Cloudinary or have some kind of like script that would be doing it.
Jen Brissman: Yeah.
John Reilly: And, but the thing that would, the thing that would. Vaguely niggle slash worry me about that. It’s what if I fail to upload something like properly? And the idea of it not being my responsibility, I just hand it over to Cloudinary and say, “Hey, you go find it for me”. That meant that like I thought [00:35:00] Cloudinary would probably do a better job of that than I would necessarily, so I, I had like greater trust in it. If that makes sense.
Jen Brissman: Yeah. Yeah. Cool. Okay. Interesting. All right, let’s take a look at the code and see how you made this all work.
John Reilly: Sure. Should I share my screen?
Sam Brace: Yeah, that’d be great. Absolutely.
John Reilly: Cool, cool. And let me know if I need to change sizes and I’ll certainly do that.
Sam Brace: Sure.
John Reilly: Share screen and here we go. So, hopefully see see my screen here. All Docusaurus sites have like a Docusaurus conflict file, which is just as the name suggests, the way that you configure it. And so we’ve started here inside inside my blog and we are going and we are importing the [00:36:00] plugin that I ended up publishing to do this.
In actual fact, if we look at the like the website itself, you’ll see that it started out slightly differently, but shall I show you the code of the plug? Sorry. So I ended up publishing a plugin, but before I did that, I had this, like an inline file that, that sat like inside the blog post before I was like, certain, this is like a useful thing.
And I’ve got like a one like that in place right now. So this is a different rehype plugin that I wrote that just lives like locally inside my blog. And a thing you can see that’s significant about this uses JS doc, which is like type script in the form of JavaScript comments.
And that’s, the code looks slightly different. So you’ll see down at the bottom we’ve got like a module exports. And you’ll see that we are using these funky comment things which have like types hidden inside them, but this is actually like a vanilla JavaScript, and that’s how the plugin started out.
If you look at the blog post that is associated with this, you’ll see if I tab [00:37:00] over to this guy here you’ll see inside here that I’m like, this is what I’m building here. This is like a JSX. This is that. But when it came to to deciding that the thing that I’d written in the context of a blog post was like, okay, this is a useful thing.
I flipped over and I decided to use to write a plugin and publish that plugin. So let me go back to here. And actually let’s do it inside Chrome itself. So if I go to to the plugin here, and I’m definitely gonna change the size on this cause this is not gonna be big enough for you. So it’s plus that.
Sam Brace: There you go.
John Reilly: And it’s mega simple. It’s one file like this guy here actually couple of files. I exagerated, index.js like here’s the roots. Obviously there’s not much in there. Not very [00:38:00] exciting. Otherwise this big enough for you before I start talking?
Sam Brace: Yeah, absolutely. This still looks great.
John Reilly: Cool. So the actual, like guts of it test. Yay. Inside the plugin here we import a type our our image or JSX node data. But the actual guts of it is this. So this is what’s called a transformer a rehype transformer. And this thing is exercised again and again as Docusaurus, like walks the tree of your nodes, basically.
And so this code here like invokes a cloud name. And this cloud name by the way, is that’s like the name of your account on Cloudinary. So in my case, its priou, which has been one my mother-in-law’s maiden name. And for reasons and the base URL of your [00:39:00] website.
So in my case, that’s that’s johnnyreilly.com and then every time it comes through, it exercises this visit mechanism for our little visit down here. So you see we’re creating. We’ve got a visitor factory here, which we make our visitor, and then we invoke that visitor on each of the elements that comes through.
And we’re interested in like a subset of things being potentially transformed. So we want elements to be transformed and that’s like an image tag or or a paragraph tag or something like that. Obviously we’re interested in transforming the the images, but we’ll filter down to that later on.
And JSX also. So these are the two things that we’re gonna play with. So now we get to the actual, like where things like happen. So here’s the this is the factory that we evoked above, and this is the thing that it makes, and it makes this visitor. So the visitor is gonna be hit like again and again with a different node each time.
And it’s gonna look [00:40:00] at that node and it’s gonna say, “okay, if you’re an element and if you’re an image and you’ve got some properties, then we are, we’re interested in doing something with you”. Okay. So this is this, the equivalence of a typical, open, curly, open angle bracket. Is it? No it’s an image tag and can never remember again, which one is.
Sam Brace: You’re good. You’re good.
John Reilly: Thank you. So it looks at this this image tag that it’s got and it says, okay here’s the here’s the src the URL basically of the image. And we’re gonna take that and you can see how simple like using like Cloudinary is here. Cause all I’m doing is I’m literally hard coding here. rescloudinary.cloudname, in my case, priou mom’s maiden name. And here’s the transformations that applied and then the URL of the image itself. So this it’s just string concatenation. Like it’s no more than that. Like it’s way simple. And this [00:41:00] is what happens for image tags and it’s the same thing that happens for JSX. It just looks a little bit nastier cause JSX is a little bit more complicated. So if we step down here we’re gonna see the same thing happen, but essentially whereas we’re dealing with a nice, clean structure here.
It’s just like type elements, tag, name, image, property, source. Inside here we end up with like a type of JSX. And inside here, here’s what the thing actually looks like. As you see, there’s like lots of things in there. So we end up doing a little bit of regex to work out like where the image is inside there.
And if we find a match, then we we just update. We do node value replace and we replace the the source thing that we’ve looked up with. Again, the same thing here. So we’ve got the same thing that we’re doing here down here. It’s just a little bit like noisier cause it’s in the context of of JSX.
But don’t think about that too much. It’s just string concatination. [00:42:00] That’s all that’s happening. And this is that’s the end really. Thank you.
Sam Brace: Very eloquent. And it’s very understandable what you’re doing here because now you’re bringing in the cloud name, which of course is your variable.
You have your base URL, which is your variable. Everything else, Jen, to your point you’re hard coded in the resource type. It’s always gonna be an image, you’re always gonna be fetching it, you’re always gonna apply these transformations. So there’s no reason for any of that to be variables in any way.
So it’s a pretty sustainable process. Unless for some reason we stopped doing f_auto, which I can’t imagine a world where that happens then this is absolutely future proof too. So this is great.
John Reilly: Yeah, and it’s it’s been like, like zero maintenance for me in terms of so I maintain like a whole host of open source projects and many of them require like a fair amount of ongoing maintenance to keep them like up and running. This thing, like I built it like I created it off the back of Josh Goldberg’s template type scripts, like things. So I didn’t have to think about that too much. And like I [00:43:00] haven’t changed it that much since. It’s just there, it just works. It’s really nice. I’ve written some tests for it, which just to just so I, I felt better about myself, but it’s I haven’t done too much. I haven’t done too much.
Jen Brissman: Yeah. I’ve seen a lot of people do the same thing in a much more complicated way. So hats off to you for figuring out a really straightforward way to do this. So I wanted to ask you about so as Sam said, you have hardcoded an image. Have you tried any other type, video or do you really not using video on your blog? So it’s not necessary?
John Reilly: So I, that’s interesting. So I actually, I didn’t know that you did anything with video. And I do have some videos on my site, so if you go to, if you go to my blog, you’ll see like a single number of like talks that I’ve that I’ve done. But there’s not tons of them and they’re all on YouTube.
I dunno if that would have bearing on it. And [00:44:00] yeah, but I, yeah, I don’t do, I don’t do tons with video at the moment, so yeah not really. Okay, but what do you do with video then? Does it, is there do you have the equivalent of a CDN for YouTube or…
Jen Brissman: This is a really fun.
Sam Brace: Yeah.
Jen Brissman: I was gonna say Sam can go into it more, but the really short and fun answer to what do you do with video is pretty much everything we do with images. So that’s like a fun one sentence answer.
Sam Brace: Yeah, exactly, and Jen’s right about that. Good example is like those transformations that you’re applying to the images, like f_auto, q_auto, w_auto those are all things we do for our overall videos too. So as an example, let’s say that you’re serving something as a mp4, but we see that it would be better as a webm based on what that happens to be.
John Reilly: Oh, sure.
Sam Brace: There’s things like that. Same thing with the quality side. There’s all sorts of fun things you can do, but a good example of why it would make sense for actually for you to possibly use here, and I’m [00:45:00] sorry to point this out. Is this video unavailable watch on YouTube situation from the types of London… because I have to physically click in and go to it. And if you were to say, “oh, great, I’ve always have it, delivered from all the CDNs that Cloudinary uses, it can, it’s reliable as dependable, it’s using their video player”. It would prevent that from happening. Of course, you could always put a link in there saying- also watch it on YouTube, because some people prefer that. Yeah. There’s nothing wrong with that, but it is to say it’s something that’s there. So anyway, a long story short, images and video are possible with Cloudinary.
John Reilly: That’s cool. By the way, if there are any YouTubers like watching, I’m pretty sure that we are looking at like a bug on YouTube. Like when I was embedding these things here, like I decided to use the, like the privacy protecting auction, which is like YouTube without cookies. Yeah. And yeah if you look at the source of the things, it’s like YouTube without cookies, but, and I think if I use the YouTube with cookies then like that wouldn’t happen. But I don’t know.
Sam Brace: It’s all good. It’s all good.
John Reilly: It bothers me. It bothers me, but [00:46:00] yeah…
Sam Brace: Absolutely fine. So going back to the plugin, so now that we’ve seen the overall process that’s taking place within the plugin, what I’d love to be able to walk through, if I can understand it correctly, is really when it comes to the authoring and publication process, because you’re writing these blog posts, as we’ve talked about, set it, forget it. What does that actually look like in practition?
John Reilly: Yeah, sure. Probably the easiest way to do that is remember back earlier on we were talking about pull request previews. So if I write like a blog post like that ends up being a pull request. And so like in this case, I’ve just I’ve just raised a pull request with this like a marginal change.
And I think I’ve tweaked the README file or something like that. But what you get off the back of that is is this thing here. And actually before we dive off to that, let’s have a quick look at what what the code for this looks like. So I want you to see just how simple it is to like to author [00:47:00] a blog using like Docusaurus. It’s just way easy. So here’s the blog websites in a blog folder. And we see I’ve been blog there for quite a long time. But yeah, any one of these folders is is a blog post. And I thought I’d open up the one which is related to… where is it? No. This one. This one. Hey! Found it. Oh, we did on Boxing Day. Yeah. So, this is the blog post that we are looking at that I wrote in the first place. And all it is this this markdown file here. This and there’s a little you get a little front matter thing at the at the top, this thing here which is just like, has some like metadata basically around the blog, post author tags, that kind of thing.
And you have the images that sit in the in the same folder. So these things, oops. Back. Okay. Weird. Yeah, these images sit alongside here [00:48:00] and they’re there and they work. And when you do the the pull request it spins up the version of the websites for you and gives you a link, which I’ve got just here.
And I happen to have opened this up previously. And if we go to this page here, you’ll see here’s my my delightful GUI featuring URL. But this is the preview of the website. And this is the actual website. And you see they look like identical, right?
Sam Brace: Yep.
John Reilly: But they’re actually not exactly the same thing because this guy here, the pull request preview, doesn’t use Cloudinary. The actual website does use Cloudinary. And the way that you can see that is, is like mega simple. And I dunno how this is, let’s if I need to zoom then do tell me. If I’m gonna hit inspect on this particular image. And let’s see if I can make [00:49:00] this big enough. I think you can do command plus inside here.
Let’s find out. Hey, so you can see maybe I can make it a little bit bigger to Plus. Plus. Oh, too big. There’s an art to this, I haven’t quite learned it. So here’s here’s our image.
Sam Brace: Yeah.
John Reilly: This is our little title image there, hero image if you like. And a couple things to notice about it.
The most important one being the source. So it’s looking, it’s using a local image. This thing here, you can see it comes from the, from this domain, from the same domain that it’s as the website lives on. And it’s just this PNG, not much to say about it. It’s also like worth noting that it’s got loading: eager, and fetch priority: high.
Those are just little cues that you can give to the browser so that it makes sure that it loads this image like fast, which gives you like a better performance with like Core Web Vitals [00:50:00] and whatnot. But significantly, you’ve got the image here and it’s a local image.
So if we now hold that in mind and actually maybe hold the file size in mind. So it says it’s like 28k there. I’m guessing that it’s gonna be slightly different when we go to the other one. So we go to here. And do the same thing and do inspect. And again, let’s see if I can, oh, let’s just remember where I am.
That’s delightful. So now if we look at the the src attribute, you’ll see it’s slightly different, right? So the the SRC attributes it’s got Cloudinary prefixed in there, and my mother-in-law’s maiden name and the various modifiers and behind that the image.
And so it’s not coming from my blog at all. This is coming from Cloudinary. And if you look at the the file size, it’s this is 18k. It’s compared to the other one, I think it was like around. 28, 30 K, something like that. So it’s about a, like two thirds of the size. You are getting benefit there, [00:51:00] also. So yeah, there’s kinda like dual benefit here. Like one of which is like there’s limitations like in the browser. I think there may actually be like less extreme these days. There’s limitations of the browser, like the number of resources that you can get from a single website a single time.
Like it’s like it’s bounded. But you can go to other websites at the same time, different domains and you can get from them. And that’s what we’re doing here. But we’re also getting the image which is optimized. So it’s gonna be loading faster. And I would also like, given that like Cloudinary’s raise in data is like images and also videos.
It turns out like it’s gotta be fast, right? So you’re gonna get that, that perf game too. It’s like that’s how it works. If you compare this to this, like the only difference is the URL.
Sam Brace: Yeah. I would think in terms of how this is also set up, let’s say for some reason you’re bringing over your markdown to a different spot and it’s [00:52:00] not gonna pull from the Cloudinary image. You always still have the base as a backup or essentially as a fallback mechanism too. So I think there’s just a lot of reassurance in using a plugin like this too.
John Reilly: Oh yeah. Like I really liked …because when you’re adopting like anything new, you’re like you wanna cover your back just in case something goes wrong. The idea that like, I could just turn it off and it still works. Like that was really like reassuring to me.
It wasn’t like I was moving all my views from here to here, and I was gonna have to like I was gonna have to do that on an ongoing basis to make sure the things synced up or anything like that. I don’t have to do any of that. It just, it works. And if for some reason, like I decide I don’t wanna use this anymore or something, I can just turn it off and it will, I will still have a mechanism that works. It’s just unplugging the plug in, I guess.
Sam Brace: And one thing that I wanna unpackage also is the concept of Open Graph, because I’ve seen you’ve done…
John Reilly: Oh yeah.
Sam Brace: Open Graph so well with your overall site. And Cloudinary is part of that too, because the way that, at least it seems to me that you’re doing your Open Graph tags, as we can see here with the way that [00:53:00] Facebook and Twitter and other sites are interpreting it, is that whatever you’re defining as like your header or hero image that you have for your blog post, it’s gonna be associating that. But if we even take a look at a generic Open Graph site that’s interpreting this, so Open Graph .xyz, you’ll see that with the metatags that it’s coming back with saying this is how it’s all working.
You can see it’s coming back with the Cloudinary version right here with all the optimizations tied to it. So it is to say that this has lots of ancillary effects when you’re not only authoring content and imparting inside experience, but also when you’re doing your promotions and telling people that you wrote a new post or you’re sharing it on Slack with coworkers or whatever happens to be.
So there’s a lot of benefits there too.
John Reilly: Yeah, Open Graph was like this mystery to me for the longest time, like I, I started seeing you paste a link somewhere this image would appear next to it. And I was like what is that? How’s that happening? It was some kind of, some deep magic, I don’t [00:54:00] understand.
And it’s obviously it wasn’t magic, like there was something behind it. It turned out to be this thing called the Open Graph like protocol, which I ended up like writing about. But like significantly it was it’s just like these metatags that sit inside websites. And and those things there allow like I think you, you’ve got a phrase Something browsers. Mini browsers.
Sam Brace: Oh, micro browsers. Micro.
John Reilly: Micro Browsers. Thank you. Yeah, it’s Micro Browsers like Slack and Teams and all these other things. They can use this to interrogate like the site and they can use you to like, to generate like a preview of what’s there so that you don’t have to, people don’t actually have to do the the immediate work of clicking on something to go there to find out what’s there.
They’ve got like some kind of clue that tells them like, here’s what’s there. And like Docusaurus had this built in already. So if I do again.
Sam Brace: Here, let me stop sharing so you can show what you’re showing here. There you go.
John Reilly: Oh, [00:55:00] sure.
Oh, sorry. Okay. So if I do inspect here and if I roll up to the to the header, so inside here, you’ll see, we’re interested in OG stuff.
Sam Brace: I saw the Twitter card above if you scroll back up.
John Reilly: Okay.
Sam Brace: Yeah, so, you see where…
John Reilly: Oh yeah, there you go Twitter card. Yeah. Yeah. Yep. And if I do OG image, there we go. So this this property here is the thing that drives like the image that pops up. And I think there’s other meta things they serve, I guess there’s a description and the title and all that kind of stuff.
I wanted to do those. Lost coherence there. I apologize. Cool.
Sam Brace: No, but I, it makes sense and also the way that you’re replacing it, because now you’re saying replace this image with one that’s gonna be fetched from Cloudinary.
It also makes sure that’s [00:56:00] working perfectly for the meta side of things too. So I think it’s an amazing example of how to weave it all together. And one thing that I’m really inspired by what you’ve done here, John, because as we said at the very beginning, you’re an open source guy. And if I go into your GitHub repos, I can literally see every single blog post, all the markdown, it’s there.
So if I wanna do a pull request on your blog, I can. That’s really cool. That’s really cool. So it’s back to you’re picking up what you’re putting down. You’re practicing what you preach. So John, that’s fantastic.
John Reilly: Oh, thank you.
Jen Brissman: And another thing is, you’ve made this rehype-cloudinary-docusaurus plugin and it’s on npm, so anyone can find this. So if you have the latest version of npm, you can just install it. It’s that easy. Like that concept will never not blow my mind. But part of being an open source developer like you are, is you’ve shared this, so you’ve weaved this all together. We’ve just discussed it [00:57:00] in this episode, and now you’ve let other people use this, too. So you’re really doing the good work there, John.
John Reilly: Oh, thank you.
Jen Brissman: Everyone should be very grateful and I know I am.
John Reilly: Oh, thank you.
Sam Brace: Yeah, absolutely. And to back up everything that we just said here, of course you can always just go to your GitHub.
So that’s gonna be github.com/ johnnyreilly, same as the domain. And you can access all of this stuff, including the rehype plugin, and start using it on your Docusaurus side of things. So if you are using Docusaurus, if you’re investigating rehype, if you like markdown, there’s a lot of things that you can ultimately apply for this, cause it’s not necessarily where the things that you’ve done here have to only work for Docusaurus.
It’s just, it’s meant for Docusaurus purposes. There’s a lot of learnings that work for other things too, if it’s markdown based or rehype based in some way. So this is exciting. This is really exciting. John, final takeaways, anything else that you, we’ve talked about with the project that we’ve maybe neglected or didn’t talk about, [00:58:00] or anything you just wanna summarize it in a nice, tidy way? What do you got for us?
John Reilly: Yeah, just a, there’s a few things that are worth plugging in as well, when you use this it’s like it’s called pre connect, like little like browser cues in there that you could do and that lets, like the browser know that your stuff is… you should go off and you should start fetching this stuff from from Cloudinary like faster than you would otherwise do.
Like these kind of things can like, make a slight difference to like speed things up as well. But yeah like anyone who wants to like play with, I’d recommend like just having a go cuz it’s like it’s mega easy to use and there’s there’s no commitment to it either.
If you don’t like it, you can unplug it. It’s really, and it’s an easy on ramp and it’s an easy off ramp, which is I think anything that… I’m attracted to things that have easy on ramps and easy off ramps. But TypeScript, [00:59:00] actually, back when I was like using for the first time, like one of the attractions was that it was very easy to get started and also you could say, “Hey, it’s just JavaScript, we could bail”
and that was the thing that would get people over the line. Yeah. Okay. I’ll try it. Cause we could escape. We could escape. Fine.
Sam Brace: I love it. I love it so much. And so of course to plug your blog post, of course everything we’ve covered here, plus more, is gonna be found on your blog. So people hopefully, if they take the time to read it, they come to check out all work you’ve done on Docusaurus, and of course, as we mentioned, that’s gonna be at johnnyreilly.com. So John, this has been fantastic, so thank you for being a part of the program and we hope to see more of what you’re doing, maybe some video, so that’ll be exciting.
Thank you again.
John Reilly: Cheers. Thanks a lot.
Sam Brace: So, Jen, key takeaways. What do you feel here? We’ve covered a ton here, but what, what’s standing out for you?
Jen Brissman: Yeah, there’s so much, one of the main things is how helpful developers are [01:00:00] to other developers, you know? Like, John didn’t have somebody asking him to do this, and he didn’t have, some company or some boss saying “Hey, you really need to optimize your site”
He wanted to get that better Lighthouse score. He wanted to optimize, and even you could see, during the podcast when something wasn’t working, he said, oh, that bothers me. That bothers me about the YouTube potential bug. And it’s really, a lot of the reasons people come to Cloudinary is because they just wanna make things better.
And I don’t know. I’m just inspired. And the reason he made this plugin and shared it with other people to use is because he wants to make their lives easier. He tinkered, he figured it out, and he’s giving everyone a solution. So it’s like a feel good episode for me, for sure. And yeah, lots of other takeaways, another big one for me is: you only know what you know, right?
So in this case, John didn’t happen to know as anybody doesn’t know everything about what a product can offer. He didn’t happen to know that we work with video, but through coming on this podcast, he found that [01:01:00] out. Maybe he’ll use that. And in the same way that through writing his blog, we had Rebecca Peltz reach out and let him know about f_auto q_auto.
Now he’s using that and that was a big thing we talked about in this blog, which we were already interested in before he was applying f_auto, q_auto. So I think, there’s so many good takeaways. How about you, Sam?
Sam Brace: I’m just gonna echo it. It makes sense. Yeah. So you said a ton of stuff here. I agree with all of it.
And I think that this has been an amazing episode for someone that is trying to create a true experience for their overall brand in a lightweight way. Especially if you’re migrating from some of the sources that we’ve mentioned at the very beginning of the program, like blogger or other blogging software.
It’s a great place to be at. And as we show, Docusaurus is becoming a very widely used tool. Or at least it’s widely used within certain spheres. So I’m excited to see if this helps with overall adoption, with the great work that John’s doing to help people to be able to see the [01:02:00] power of all of these platforms together when it comes to content authoring and delivery. So that’s exciting.
Jen Brissman: Yeah. Agreed.
Sam Brace: To summarize all of this, if you want to be part of more of these podcasts that we are showing you here, of course they’re all gonna be at cloudinary.com/podcasts. That’s where you can see all previous episodes of DevJams. And the nice thing, of course, is that, if you are a Spotify person or you’re an Apple Podcast person, or Google, you can see all the previous episodes there and we have ’em all linked inside that case.
And of course, all the transcripts, all the details are happening to be right there as well, so you can follow along at your leisure. And don’t forget, we also have an amazing community at community.cloudinary.com, and that’s where you can be a part of all the conversations that are taking place in our overall community.
And if you’re also a Discord person, great. We also have an associated Discord server for you to continue the conversations as well. [01:03:00] And lastly, to help John plug his stuff, go ahead and check out Docusaurus. That’s gonna be at docusaurus.io. And of course, John’s personal blog post with lots of great material, not just about Cloudinary, but about many things at johnnyreilly.com
So on behalf of everybody at Cloudinary, so from me and Jen, to you, thank you for being a part of this DevJams episode, and we can’t wait to see you at future ones. So take care and have a wonderful day. We’ll talk to you soon.
2023-08-18
Reducing Image Delivery Bandwidth with Cloudinary
Join Grant Sander, Vice President of Engineering at Formidable, in this Cloudinary DevJams episode! You’ll learn how Grant migrated images to Cloudinary and experienced significant enhancements for their website, such as next-generation image format delivery and support. Grant demonstrates the process and code that Formidable used to migrate images, resulting in an 86% reduction in image bandwidth for the site. Follow along with Cloudinary’s Customer Education team to gain a better understanding of the motivation and work involved in the process, from identifying the problem to measuring success. If you’ve been storing your assets in a code repository and creating your own optimization processing pipeline, but finding the process to be challenging, this is a conversation you won’t want to miss.
Sam Brace: [00:00:00] Welcome to DevJams. This is where we talk with developers who are doing inspiring, innovative, interesting projects when it comes to images and videos that happen to be the most development projects, and they probably are likely using Cloudinary for all of that innovative work that they are doing. My name is Sam Brace. I am the Senior Director of Customer Education and Community for over all Cloudinary, and I’m very happy that you are here today for this DevJams episode. This is gonna be a fabulous one if you are interested in images, but also making them as lightweight as possible. And we’re gonna be talking a lot today about bandwidth and how to properly reduce that using functionality available with Cloudinary, APIs, SDKs, and our overall transformations.
Joining me for this episode is [00:01:00] Jen Brissman. She is a Technical Curriculum Engineer here at Cloudinary on our Customer Education team, and I am very happy to have here for this program. Jen, welcome to the show.
Jen Brissman: Hey, Sam. Thanks for having me.
Sam Brace: So Jen and I are, we’re gonna be talking to Grant Sander, who is the Vice President of Engineering at Formidable, which is a firm that’s focusing on design and development for some fairly large customers.
That includes probably a lot of the brands that you’re very familiar with, maybe you’re purchasing from every single day. The overall development and design work that’s happening from them, a lot of those aspects are being handled by Formidable and he’s gonna be talking about their own website, formidable.com, and they’re gonna be diving into some of the ways that they were able to reduce the bandwidth and then of course, associate that for some of the work that they’re doing for their clients.
But Jen, why is that exciting to you? What’s getting you fired up about this episode?
Jen Brissman: I’m excited to have Grant here. We’re so lucky to have him because he’s [00:02:00] working with Formidable, one of our partners at Cloudinary, and we don’t always get the chance to talk to people who we work with as well.
And they use us, we use them. So it’s cool to see how everything works together. And we’re gonna get into that with Grant today.
Sam Brace: I agree. And what’s also wonderful about this is that I think what we’re gonna also talk about is a very natural evolution that we’ve seen companies take when it comes to maturity of working with images and videos and digital media essentially, where sometimes you might start off, you’re saying an S3 bucket where we’re gonna store everything in terms of a place for it to go.
It’s nice, cloud-based, centralized area, that’s enough for what it is. But as time goes on, you need to start thinking about what formats are we delivering those things at? Is that really the right level of compression that we want everything to be at? Is serving everything as originals, actually hurting our overall performance, rather than providing some type of variation or derivative of that file so that way it loads as quickly as possible.
So what I love about what [00:03:00] Grant’s gonna talk with us here today about is something that probably a lot of developers have felt when they’ve gone through working with images and videos on the web.
Jen Brissman: Absolutely.
Sam Brace: So Jen, One thing that of course, that we wanna point out to everybody is the fact that we are in lots of places. So if you are saying, okay, great, I love the concept of being on this live stream. I love that Cloudinary is talking with developers. Well, note that you can always go to cloudinary.com/podcasts for all the previous episodes because we’ve been doing this for about two years now, talking with developers like Grant and others that are really pushing the boundaries of what images and videos are in the web, and of course, mobile as well. So you can always go to cloudinary.com/podcasts for all of that. And we of course want to emphasize our Cloudinary community. So if you hear some great conversations that are happening here and you want to keep those going, you can always pop over to Cloudinary. So community. So that’s gonna be community.cloudinary.com, [00:04:00] and that’s gonna be at the main space where you can see all of the content that happens to be there. So let’s go ahead and bring Grant on and have a little bit of detail about what he’s been doing at Formidable and being able to optimize that content. So Grant, welcome to the episode.
Grant Sander: Hello. Hello.
Sam Brace: Grant, obviously I’ve been very impressed with all the work that you’re doing, all the work that Formidable is doing, but maybe people that are listening to this, this is their first time encountering you. So tell us a little bit about you, a little bit about Formidable.
Grant Sander: Yeah, so maybe we start with Formidable. Formidable is a digital design and development agency. We do dev work, design work, product work for companies of varying sizes, anywhere from like smaller startups all the way up to, fortune 100 companies.
So we’ve got, a wide portfolio and we do a lot, we focus a lot on modern JavaScript tooling. So we’re, we, were pretty early in the React space. We do a lot of work with Modern React, do a lot with [00:05:00] Next Js, React Native is another big one. We do a lot of like cross platform, mobile work on the engineering side of things, as well as all the fun design system, product type stuff.
So that’s like at a high level what Formidable does. We help companies build cool things and help level up their engineers to, to build cool things. That’s Formidable. I am just another engineer I suppose. Recently, I am now a VP of engineering at Formidable, which is a scary title.
But yeah I basically help client teams succeed, help with like client facing work, but also involved in partnership things, and so like you mentioned, Formidable and Cloudinary are partners. We’re an agency partner of Cloudinary, so do a lot of like partnership engagement and also
sort of help lead the open source initiatives at Formidable? So Formidable does a lot of open source software work and I help with that build tooling [00:06:00] around. A lot of times it’s tooling around what helps our client team succeed, which is nice because if it’s helping our client teams succeed, it’s often helping other teams succeed.
So involved in a handful of different things at Formidable.
Sam Brace: Which is fantastic because it’s where you have a lot of concepts of what’s working for your clients that you’re working with, what’s working well for the various partners, as you mentioned, working with Cloudinary and others. And then even on top of that, being able to understand the brand presence.
So you have a lot of hands and lots of pots, but that’s a great place for us to be at with a guest like you. So this is fantastic that you’re involved with all of those different efforts. One thing I wanted to ask you about, because you mentioned some of the programming languages that you guys are working with at Formidable, and you mentioned React you also mentioned React Native.
Talk to me a little bit about that. Why are some of these choices being made is, are you guys necessarily calling yourselves a JavaScript shop or is it where you’re focusing on certain frameworks because of certain reasons? What’s the intention behind that?
Grant Sander: Yeah. In [00:07:00] consulting it depends on what business you can get, although it’s a chicken and egg problem where you’ve gotta have engineers to staff things.
And so we’ve been, pretty early in the JavaScript that was where, when Formidable was a small agency, that was the type of work that we were doing. And we’ve just grown to be well known in the JavaScript community. So that’s been our strength for many years is, has been JavaScript.
And this predates my time at Formidable by a number of years, but Formidable is also early to React. I think, early engineers at Formidable kind of saw, saw that React was gonna be the next big thing. And so we, we did a lot of work in the open source community with React and helping some larger clients with React work that were also early adopters,
and we just rode that wave and then React Native came onto the scene and it’s been a, it’s been a great choice for a lot of companies allowing, allowing [00:08:00] us to help people build cross platform mobile apps, which is a pretty big deal. I mean ,that’s the selling point of React Native is you can have one engineering team building for both iOS and Android.
With React, there’s differences between web and mobile, but a lot of your React engineers that are doing web work can also get cross-trained onto mobile development as well. So those are the reason why, we’ve been big on React and React Native is that, that’s the thing we’ve been using,
and also just our, React’s got a big community. There’s a lot of client work to be done. A lot of larger companies are choosing React. They have been for quite a while. Reacts held the throne it seems like for quite a while now. We’re going where the market goes. We also like react quite a bit.
It’s a pretty pretty nice framework and makes our lives quite a bit easier. But in later years, TypeScript has been pretty big. So now we consider ourselves a TypeScript shop as well in terms of programming [00:09:00] languages. We do a lot of work with Typescripts, help clients migrate to Typescripts.
Which has been great. And we also have, we have engineers doing Rust and Go Lang as well. So we do some more additional languages. It’s not the bulk of our work. A lot of our backend work is still node. We do a lot of, like a lot in the GraphQL space. This is another space we’ve been pretty big in and early adopters is GraphQL.
And we, a lot of our like backend GraphQL type work is often in node. Node seems to be Node.js seems to have I think probably the most mature like GraphQL ecosystem and that’s fit well with like our expertise. So definitely, big JavaScript company, but we also do, Rust has been getting a lot of attention, which has been cool. And so we’ve been dabbling in Rust as well.
Sam Brace: I love the fact that, you have all of these different viewpoints. You’re touching all of these different frameworks because it really does show that you’re able to provide a wealth of expertise to the [00:10:00] clients that you are working with. And that’s fabulous.
And of course, I love the fact that Cloudinary is an arrow in your overall quiver too, that you can bring that in to all the discussions, which kind of brings us to your project. So as we know you, we mentioned that you have Formidable, which is a overall agency, working with clients on all sorts of design and development efforts, but then you also have your main brand presence, so formidable.com.
Talk to me about what your decision making was with the website and why you decided to maybe go in a different route when it came to the ways that you were working with images for that site versus what you’re doing today.
Grant Sander: Yeah, so a number of years ago we had migrated our formidable.com, like our agency website to a stack of, we were using React Static, which was like, now considered an older framework, but it was a way for us to generate static webpages, which is great for an agency site like ours that doesn’t have a ton of dynamic content.
We’ll change things like [00:11:00] every week, every other week, but that’s like a pretty low frequency, for changes, and we were working with a stack of Ref Static. We were using Netlify CMS for allowing our like marketing team to author content in a, like a GUI, a visual interface. And then when they would make those changes, basically what would happen is it would commit those changes right into our git repository.
So our entire website was totally git driven at at the end of the day, and so this was pretty nice for us, in terms of the development teams we have, that’s a pretty natural flow for us. But when everything is static and it’s just like a straight up React site and everything is handled locally through the git repository, images become a sticking point because carrying around a ton of images, like all the images you need for like blog posts or case studies or whatever other kind of content you have on your site and like we don’t even really have user generated [00:12:00] images and we still had a pretty, pretty hefty load of images.
And it was a burden to try to have, say like our content authors or whoever’s generating images be very like in tune with like, how many megabytes is your image? What format is your image? And that’s a lot to ask of a content author to, to be like super, concerned with the nitty gritties of their images that they’re uploading.
So we’ve been migrating our site to try well React Static is, has been at end of life for a more than a year now. So we were in the process of migrating off of that. Netlify CMS has been great also slowing down in this development. And we were looking towards something, we’re moving towards sanity, which is another CMS that has been great for us and allows us to provide content.
So we’ve been talking about migration. Images, were like the biggest baggage in terms of like our existing flow, and sort of the lowest, [00:13:00] like lowest hanging fruit to some degree. It was like the most bang for buck in terms of our migration, which is great, especially because like most websites are very image heavy.
I think images make up, I dunno, we could probably Google the statistic, but the majority of like web bandwidth is just images. And optimizing images is a great first thing to do in terms of, saving bandwidth, improving speed, things like that.
Jen Brissman: So was there an actual problem or what was the actual problem that led you to look for an alternative in the way that your images were handled?
Were you experiencing any downsides to the way you were doing it before? And how did you know, okay, Cloudinary is our solution?
Grant Sander: Yeah, so we. When you have 1200 or 1500 images checked into your Git repository, like pulling the repo down, like cloning the repo, moving things around, it gets pretty heavy.
It gets chunky. You end up with just like gigabytes of images that are in there. [00:14:00] And we had a workflow for basically using Sharp, which is a a node library, a very high performance like image transformation processing library. And so we knew that we wanted to deliver sort of NextGen images, and so we had a process for like turning our original image assets into WebP versions, which WebP is like a, NextGen image format.
Although now I’m wondering if it’s still considered NextGen or not, there’s some other players in the space, but we could probably loop back around to that. But we had a process for taking just a straight up jpeg, turning it into a WebP and it would get committed right back into our repository so that, because we were serving those images out, so we were now, if you had 1500 source images, we really had 3000 because we were creating these WebP versions.
That weren’t being resized or compressed at all. They were like literally just converting the format of them. We were, we had a workflow for trying to [00:15:00] reduce some image bandwidth on the site by serving WebPs where like you could, where there’s browser support for, that’s pretty good.
But yeah we were running into this thing where our repo had a lot of baggage and managing our images and getting everything to process our original assets into WebP. It was just a very clunky workflow. And when we were looking towards I don’t know, resizing images or using something like avif, like more, more like efficient image formats it was gonna be daunting.
It was gonna be like the multiplicative effect of now you’re gonna need, for every source image, you’re gonna need four generated images stashed in there. We were looking at just like totally bogging down our get repository. Also just like realistically wasting engineering hours trying to create our own subpar version of image processing and delivery, which is just, we try to avoid that at Formidable.
We often advise our clients to pick the solution that [00:16:00] requires the least amount of dev effort, which is generally like good advice unless you’re in like a very specific edge case. And so we figured, it was time for us to take our own advice. We would, we would probably never tell our own clients to check all of their images and to get, we would be pushing them towards image hosting solutions.
And so it was just a matter of time for us to get caught up on our own site
Sam Brace: Well, I think it’s smart what you did, because it’s something that we hear continually when we start talking about headless architecture and composable architecture. A lot of the conversations around choosing what they call best of breed, right?
Which is where there’s lots of vendors that do something correctly. Don’t try to replicate the wheel, don’t try, do something that somebody already is spending in. Thousands, if not hundreds of thousands of R&D hours in to understand. So as you said, serving everything as a WebP. Yeah, that makes sense.
WebP is ultimately something that’s meant to supersede jpeg, PNG, et cetera. But in the same sense, now you’re able to deliver [00:17:00] things as AVIFS or JPEG excels or whatever you wanna be able to use. So it allows for people to be able to say, we got the format situation for you. It’s okay. You don’t have to send all the engineering hours on it.
So I like the approach that you ultimately took with this effort to know that when do we want to really make that investment versus when do we wanna go with someone that’s already made that investment for us. So that very good choice on your part. What I would love to talk about Grant, as you can see here, we have a whole blog post that is written on the formidable site, which we also have linked here in the show notes.
And it’s gonna outline a lot of the things that we’re gonna be talking about here today. But what I would love for us to be able to do is take a look at some of the codes, some of the details that you have here that really breaks down this particular sentence right here. The fact that you were able to do some things where you were able to reduce that image bandwidth by 86% across 30 of your most front facing web pages.
So I’m gonna pop over your screen here and we can start walking through some of the stuff that you’re able to do it from middle to make this [00:18:00] possible.
Grant Sander: Cool.
Yeah, I think we could step through this blog post a little bit. I also have these code snippets from the blog post pulled out into a GitHub gist, which I will probably jump over to cuz it’s a little easier to read here. And we have line numbers, but Just wanted to talk first about like big picture idea of okay, we wanna migrate to Cloudinary.
What was our mental model for executing a migration of all of our images on our site. So this little image here sums this up where we took a four step approach of, and that might be a little small, but the first step was upload our entire image library from our Git repository up to Cloudinary.
That’s pretty low stakes and honestly, I botched it a couple times in the process, but was able to nuke my like folder and Cloudinary and then just do it again. And there’s a little bit of trial and error there, but uploading it [00:19:00] first was like, I could test it. I wasn’t actually changing anything on the website.
So that’s no harm, no foul. So step one was just like taking the images from where we had them and getting them into Cloudinary in a way that allowed us to do our migration across the website and all of our content. So the second step was migrating the image URLs in our content. So once our, once we have like the media library and Cloudinary’s DAM, their digital asset M is for what?
Management?
Sam Brace: Management. Management.
Grant Sander: Yeah. Okay. DAM Library, whatever we’re calling that thing. Once it’s up there, we need a way to, like all of our content was in markdown ,files. We were, we had a very markdown driven site. We needed to go into all those markdown files and change all of the image paths from like a relative path because everything was in the same like repository served outta the same bucket.
We were using relative image paths for all of our image tags, and we needed to update those to be like, fully qualified URLs pointing to Cloudinary, [00:20:00] and have it, point to the right image. So this was the hard part was like getting that migration and automating that out so we didn’t have to do a bunch of manual work.
So writing the migration script for that.
Sam Brace: So talk to me about that, because I agree with what you said. That sounds challenging. So how, what were some of the steps that you remember having to take when you were talking about that migration script to make sure that everything was going from the relative to the situation that you have now?
Grant Sander: Yeah, we could probably jump into some code if you’d like. That might be the easiest way. Maybe the easiest way to do this is just jump right into some code. Do you wanna start there or do we wanna start with uploading the library to Cloudinary?
Sam Brace: Actually, yeah, if you wanna take a step back and talk about the uploading part, that’d be awesome.
Grant Sander: Yeah.
Sam Brace: And then we can jump back and talk about testing once we go through the first two steps. Yeah.
Grant Sander: Yeah, that sounds great. And honestly, the uploading the Cloudinary was probably the easiest part I think. Cloudinary offers a lot of SDKs and even like REST APIs that are very easy to [00:21:00] use and. JavaScript, I mentioned we do a lot of JavaScript at Formidable we just wrote a little, a “JavaScript” as they call them, to migrate these. To migrate our images up. As you can see in this code snippet here, we are using the Cloudinary Node SDK, which is pretty great that, it made life very easy.
So we have a lot of like configuration. We had some baggage from our site where like over the years we had changed how things were structured and so the places where our images lived had changed over time. So there were some like weird edge cases that I’ll point out here, but I don’t want us to get bogged down too much in those details.
So we configured our Cloudinary SDK just, I omitted like our cloud name, API Key, API Secret. I also only ever ran those as a process arg, so you had to pass those into a CLI command so that I never accidentally commit those into Git, [00:22:00] even though Git respository is private. But, good practice not to commit your API secret into your repository.
Configuring that, this just got passed in through a command line argument. And that sets up the Cloudinary SDK, and then I just have this main function, which runs when I call the script. So I have, this is the bulk of things, but this is just a JavaScript file. I’m gonna scroll way down. At the bottom, I’m just running this main command. And so this is pretty, pretty common practice. If you’re writing a Node script, you just write a function, call it at the end, and log out an error if something bad happened. But, so this main function is the bulk of stuff. So one of the things that I’ve been bitten in the past is if you have a long running script that’s doing an operation over and over again, if something fails halfway through or a process gets corrupted and like your thing stops, it’s good to save your work as you go.
So you know what’s been [00:23:00] uploaded and what hasn’t been uploaded. So if you’re uploading 1500 images, keep track of the ones that have been successfully uploaded so you don’t have to redo those in case like something falls over or fails. Learn those from field combat of not doing that in the past.
So this is just like a status map where I just like literally had a JSON file that I would write to.
Sam Brace: Okay.
Grant Sander: That, so as images were being processed, you just create a record in a JSON file that’s just like the image name and then whether or not it succeeded or not. And then when you start the script up, we use that to check like which ones are already uploaded and which ones aren’t.
Not super important, but a fun little call out of if you’re doing a long running process, probably good to track your progress as you go in case you have to restart that thing.
Sam Brace: Smart.
Jen Brissman: Totally.
Grant Sander: So this is, this looks pretty ugly. It’s not super pretty code, but what I wanted to do was grab all the source images from [00:24:00] our repository and we, like I said, we had images living in different folders.
And so I have this configured in like a configuration file, but this asset roots is like just an array of like paths to the folders where images lived. So using this library Glob, which is a super cool library, I find myself using Glob all the time. There’s a lot of libraries in the space for globing stuff, but basically allows you to point to a folder and then just write like a glob statement like this where it says, “Hey, go ahead and search through everything nested under there and find me all of the files with these extensions.”
And so this is a pretty easy way to go find all those images. PNGs, JPEGs, SVGs, GIFs, the whole kit and caboodle there.
Sam Brace: Yeah, it definitely comprises everything that you would’ve had there prior to moving to Cloudinary. That makes sense.
Grant Sander: Yeah. And then once I have found all those from the folders, just flatten that out into a flat array.
And then there’s some [00:25:00] extra stuff here of this was just like cleaning up some stuff we didn’t want, we wanted to filter out the WebP generated files, which had a specific, like prefix on ’em. Also clean up the path a little bit, just removing like the prefix, so it doesn’t have like user: “Grant Sander – home”, GitHub, whatever.
Jen Brissman: Right
Grant Sander: Just removing the stuff from the beginning. And then this is the part where like checking against the status map where it’s okay, if it’s already been uploaded, don’t do it again. So we are only doing this on the images that are marked as needs upload. So we have all of our image files that we wanna upload.
That’s not too bad. And then what I’m doing is I’m gonna skip a couple things that aren’t super important. What I did was ended up like batching the upload. Cloudinary does have some rate limiting in place. And I tried to like upload 50 images at a time [00:26:00] and like I hit some rate limiting issues and I was like, okay, let’s just, I have time.
I can run this and go eat dinner, so I just batched it at size two. But you can control that. And so what I’m doing is uploading two images at a time. And so this is there’s some logic here for doing, like batching up some stuff, but at the end of the day to upload an image, it’s like literally just cloudinary.uploader and then there’s an upload method and you just pass in the path of the thing.
Sam Brace: Yep.
Grant Sander: And that’s pretty, pretty darn simple. So there’s some complex stuff here, but it’s only because the complexity of the repo that I was working in and like finding the images, but to upload like a single image, you just pass it, pass it a file path and give it a public ID.
One of the things we had to look out for was I had to take the path of an image and give it, like I had to follow some logic to give it a public ID which is how you’re gonna specify which image to like load. That’s like the key identifier. I had to make things [00:27:00] deterministic. And so there’s some cases where we had some stuff where I had to rename a couple files because like we had a, say like gen.JPG and gen.SVG like the, it’s the same file name, different extension.
And that was causing some conflicts when I was generating public IDs. So I had to do a little bit of cleanup around that. But generating out like a deterministic public ID based on the image path. And we’ll use that. You’ll see that again in the next step of migrating things. I also had a folder all these got uploaded into the same folder in Cloudinary.
Super easy just to specify that. And then I set the overwrite to true just in case it’s already there. I could just re-upload it in case.
Sam Brace: Yeah, and I actually, when I was looking at that little portion of it right there, line 70 about to 80 or 82 is, that was smart. The override situation, cause you don’t want any of your batch processing to get hung up because it’s saying it can’t override an existing file.
In case of what you talked about, where we do wanna override a file that’s been like sample.JPG. Okay, we do need to override that [00:28:00] from what’s there. So that was smart to make sure the batch continued and was processed completely.
Grant Sander: Yeah. And then status map once the image uploads, you set the thing on the status map.
And then I just, again, this is like not super scientific, but it works good enough. Every 10 iterations, I’m just writing out this JSON file. So it’s like hitting “Command + S” every time you upload 10 batches.
Jen Brissman: Totally.
Grant Sander: Yeah, again, like that, it’s good enough to save yourself some time in case something goes wrong in the middle of it.
Sam Brace: It sounds like we’ve all been burned somehow without hitting “Command + S” at some point. So putting that logic into what you’re doing here, it makes sense. So I like this a lot and frankly, in my opinion, if we’ve covered nothing else in this episode, and obviously we’re gonna cover more, but if we’re covering nothing else, to be showing a clear migration path from something to Cloudinary, which you’ve provided here, is amazingly useful for the million plus developers that are using Cloudinary. So this is fantastic information.
Jen Brissman: Yeah, even including [00:29:00] overwrite: True, and everything we just talked about, like line 70 all the way through your check to periodically save your progress. Like anyone watching, this is open source. You could probably take this or make a similar version of this.
I totally agree, Sam. If people only get this, it’s probably valuable.
Sam Brace: Absolutely. Absolutely. So Grant, so we’ve covered the point of the migration efforts. Is there anything else not the migration efforts, but the uploading, the library of the Cloudinary anything else that’s important to mention about this process?
Grant Sander: I think we covered most of it. The upload process, like the Cloudinary, SDK makes it just very easy. I think the big part was like, make sure your public ID- you’ve gotta keep your eyes on the public ID because that’s the thing that you’re gonna end up using. And so at some point you’re gonna end up using that public ID again.
So making sure that like you have some logic for generating, like deterministically generating those so that when you go to migrate your content, you can give the proper public [00:30:00] ID. So I think that’s I think this get cloud name is somewhere else in this gist. The details aren’t really that interesting.
It’s based on whatever your own setup is, but I think the public ID is another one just to keep your eyes on. But yeah, other than that, I think that kind of covers the gist of the upload process.
Sam Brace: Yeah. And I, and it is something that we push a lot in training where when we are talking to customers, to think about naming conventions for their files or their assets, and public ID is how we do that.
And I think your example was perfect where gen.JPG versus gen.SVG technically have the same public ID with the way that Cloudinary looks at it because file extension is not considered as part of that. Unless we’re talking about a widely different format. If it’s gen.MP4 versus gen.JPG, yeah.
We might be seen as different situations. So it is important for them to people thinking about how do I want my files to be named once they are migrated to Cloudinary? Do we want ’em to stay the same as local? Do we want [00:31:00] some form of randomization to prevent overwriting? There’s lots of ideas around that. So I think that was good for you to focus on that.
Grant Sander: Nice. Cool. So then, yeah, I …
Sam Brace: We’re moving to migration, right? So that’s step two of the four part process?
Grant Sander: Yeah. Yeah. Let’s talk migration, which I will go ahead and find that file. Let’s see.
Jen Brissman: Yeah, Grant, while you find that, I just wanted to air your tweet, which I, which really made me laugh where you said “Cloudinary is boss”.
When you tweeted about this blog, I really got a kick outta that. And I know that probably, as you said, the upload part is relatively simple and straightforward, and I’m looking forward to getting to the code where we talk about optimizations and where, what probably led you to saying Cloudinary is boss.
Grant Sander: Yeah, that sounds great. We’ll we’ll turn through this the migration part here to get into some more interesting stuff. Again, a lot of this [00:32:00] has details around like the specifics of how our repository was structured. So we’ll just touch on some of the like higher points, some high level points.
So again, we’re gonna, we’re gonna do some “globbin'” in here, which is great.
Sam Brace: Great.
Grant Sander: So a similar thing here of grabbing all of our markdown files. So you can see here we’re going in and we’re saying, “Hey, inside of the content folder, this is where all of our content files live. Give me all the markdown files.”
So now we’ve got all the files we want to inspect, and this is the primary place where we wanna update URLs. So like just looping through the files. So four constant files, just loop through one at a time and doing a Node file system, read file, and just reading out that file. So this is like taking a markdown file, just loading it into memory UTF-8 encoding, and so we can look at that and work on it like it’s a string. So at this point, file contents is like literally just a string, which is like the markdown content that’s in there, which is [00:33:00] nice because if you have a string you can do whatever sort of shenanigans, like string shenanigans, you want.
So I am a sucker for a good regular expression. And we have a nasty one here. I don’t, I think maybe all regular expressions look a little bit nasty.
Sam Brace: I agree, I definitely agree with that too.
Grant Sander: So, we won’t go too far into this, but you can pick out a couple things here where we’re looking for things that end with PNG, JPG, SVG, GIF, WebP. And they also start with, I mentioned the asset route before. Which is like the folders in which images would live in. So it’s going and saying, okay, if we see any, things that start with the forward slash and they have the asset folder name to start, and then they end in like a .JPG ,that’s gonna be a thing that’s referencing, it’s like a relative URL to an image that’s hosted in our repository. So we can use [00:34:00] that “r” this is not a great name, but I’m scripting and so I’ll give myself a little bit of grace here. Using that regular expression, and with a regular expression, you can pass that into the string replace method and you can actually do logic on these things.
So this gives us the match itself and there’s a lot of like regular expression stuff going on here, but what we’re doing is basically generating the Cloudinary ID. This is what the C ID is, and it’s using the GET cloud name that we saw before. And this is like the thing that like took a file path and turned it into a, deterministically, turned it into an ID for Cloudinary to use.
And here we are using it again because now we’re looking at the file path and we gotta say, all right, we need that file, or we need that Cloudinary ID to use as part of this URL. So Cloudinary has their own URL structure for requesting images. So we have, [00:35:00] we’re gonna use our project ID, image upload, I set a version number on these, which we could get into some details on there. Passing in a folder and then using the Cloudinary ID. So this is how you walk through each markdown file, you use that same function that generated the ID, and you just use that as the last part of this Cloudinary URL.
And then you just do a little swaperoo. You just swap that relative path for a Cloudinary URL. And you write that thing right back into the markdown file that it came from.
Jen Brissman: Question for you, Grant. Oh, go ahead Sam.
Sam Brace: No. Go ahead. You had a great question.
Jen Brissman: I was just gonna say in line 42, is that an exhaustive list of file extensions that it could be, or do you have a fallback in case there is, something hanging out in there that, that isn’t on that list?
Grant Sander: Yeah, this for our case, this was exhaustive. We didn’t have anything outside of PNGs JPGs, SVGs, GIFs, [00:36:00] WebPs. Theoretically it’s not exhaustive. There’s other image formats that could have been in there. And so for our case it was good enough. But like you would probably, like if you were using, what are some other image formats?
Jen Brissman: AVIFs…
Grant Sander: Other some other images. You might also wanna include those in there. But we had, just the vanilla image format, so it was a little easier for us. But yeah, this, you would wanna update this to cover all of your image extensions.
Jen Brissman: And I guess you wrote the logic anyway, that if something were to break, it would stop and have saved that batch. So there you go.
Grant Sander: Yeah. Yeah. And we’ll, the next script is actually like validating that images didn’t break. And so I had a little bit of a fallback in case, we had an oopsie.
Jen Brissman: Yeah. Cool.
Sam Brace: A couple I’m ask you about here and I think you’re highlighting it, so yeah, we’re saying the same thing or Grant, but yeah. So talk to me about your decision to add f_auto and q_auto to this overall process. Cause I, [00:37:00] obviously, I know what f_auto, q_auto is. You know. Jen knows. But talk to me about your decision making on what and why you decided to add those transformations.
Grant Sander: Yeah. So with Cloudinary’s image URL transformation syntax, you can pass in these transformation parameters that transform the image.
So if you left out this part here, we deleted this part out, Cloudinary is just gonna serve you back the original image asset. And that’s okay, but we mentioned earlier that a lot of times serving up an original image is not the most optimized, it’s almost never the most optimized solution.
Sam Brace: Correct.
Grant Sander: Cloudinary, this is one of the things that I think makes Cloudinary so powerful, and makes this sort of thing low hanging fruit, is this f_auto parameter is auto format, which says, “Hey, your browser requests the image, Cloudinary looks at information about the requesting browser, says what’s the best image format to use for this browser?”
So if it’s Chrome, it’s probably gonna be like an AVIF. If you are [00:38:00] like, for some reason on Internet Explorer 11 or something like that, it’s gonna choose something else that’s not a next gen because you’re using a 20 year old, 10 year old, browser. And it just serves the best one. So this is, you don’t have to think about it.
Cloudinary’s magic just serves the best format for you. So that’s nice because now you don’t have to specify and you don’t even really have to care too much about the original image extension. You just say, “Hey, Cloudinary, gimme the best one. Whatever. We trust you to give us the best one.”
Sam Brace: And then q_auto, to double down on that real fast, like when we were talking earlier about your original format situation where you’re converting everything from JPGs to WebPs, I think your Internet Explorer one is perfect because as we know, Internet Explorer and WebP don’t really get along because of WebP was becoming more of a format as Internet Explorer was starting to get phased out, and Edge was becoming a thing for Microsoft.
So it does help for those backward looks as well as those forward [00:39:00] looks. So I think it was really smart to make sure that you’re looking at it from that sense. And yes, you’re looking at exactly what I was gonna recommend is, caniuse.com. This is always a great way to see the latest and greatest and what types of browsers can serve certain formats.
And yeah, as you can see here, like older versions of Chrome, older versions of Firefox, they can’t handle AVIFs. If we pull up WebP would be almost identical Yeah. In some of those cases too. So it’s nice that you have something that can constantly format to every user’s various browser choices, cause probably there are still some IE users out there that are using IE 6, in my opinion, which is crazy, but it’s true.
Grant Sander: Yeah. Yeah. And even I think even, AVIF, as an example, has pretty good support, but Edge doesn’t support it, which is interesting to me. I would’ve thought they would, I believe Edge does support for WebP and and it has for quite a while, actually, since very early on.
So the nice thing there is okay, AVIF is great. It’s probably better than WebP in a lot of [00:40:00] scenarios. It’s gonna use that most of the time. But like Edge users, we can’t forget about them. Edge is a good browser, so let’s serve them WebP, which is pretty good. And then fallback to something else if you’re for some reason running IE 11.
Sam Brace: Yeah. And if you are, I strongly suggest not, go ahead after your browser like I said, all strokes for all different types of people. So it all makes sense. So it’s already to jump out of the f_auto, q_auto situation, but I love the choices there.
But what about q_auto?
Grant Sander: Yeah, so f_auto serves you the best format, so like image format, which is great alone for bandwidth because a lot of these next gen formats have better compression ratios. And so you can send smaller images, which is really good. But the q_auto is auto quality, which allows, basically it allows Cloudinary to choose the right compression.
And so if you take an original JPG, you can say, all right, let’s save this as 70% quality so we can shrink this file size quite a bit. So there’s always like a [00:41:00] balance between file size and image fidelity. That’s like the trade-off here is okay full quality, you have the highest level of fidelity, but you have the largest file possible.
And so like moving the needle on that lever a little bit, it’s like a balance of what’s the best thing to serve here. So q_auto just allows, again, Cloudinary is magic to pick where to put that needle for you. You don’t have to do it. It’s just what’s the best ratio of fidelity to compression ratio here and file size.
And so again, this is like an easy way just to use the, the thing that Cloudinary does really well is like doing that for you. And just not letting not burdening our content authors with making that choice. Like they don’t have to worry about it. It’s just gonna be a good one.
Fidelity’s gonna be good enough. It’s gonna reduce image bandwidth as much as you can without [00:42:00] making images look super distorted. So I see f_auto and q_auto as going hand in a lot of ways of just like a good default for not really thinking a whole lot about image stuff, like to, to a large degree.
You can just forget about the nitty gritty of the image delivery and format and stuff and just be like, yo, I want a really cool image of this thing. And then Cloudinary handles like serving it well.
Sam Brace: Oh my gosh, you said it almost words that I always say when I talk to peopleabout f_auto q_auto. I always talk about it and in terms of set it and forget it, like it’s where it’s just let it do it’s magic and handle it.
Cause you’re always going to make sure that you’re getting a 200 when you’re serving something. You’re always getting it where yeah, the image is gonna come through. You’re not gonna be like, As you were pointing out, like if I tried to serve an AVIF today to a Edge user, I could potentially get a 404 or not be able to display content, some type of something that we don’t want.
This guarantees, deliverability, it [00:43:00] delivers it at the right bandwidth, the right compression, the right format every time. So yeah, set it, forget it the way you put it. Just set it and leave it whatever people want, but it works nicely in that case.
Jen Brissman: I was gonna say line 31 is why I would venture to say Grant tweeted “Cloudinary is boss”, because f_auto q_auto – we’ll say it till the cows come home, that is Cloudinary’s special sauce, our magic, and I’m glad that we all agree and if anyone’s just listening and not watching, they wouldn’t see the big huge smiles on my face and Sam’s face as Grant was saying all of that before, because it’s like Sam said, that’s basically like a script that we say in training is everything Grant said. So he really couldn’t have said it better, Grant.
Sam Brace: We didn’t coach you ahead of time, grant, so you’re
Jen Brissman: Yeah. Seriously no coaching.
Sam Brace: But, one thing I wanna ask you about, cause if this is interesting to me, so line 32 where you’re declaring the version number here, what was your decision making there?
Because I can see it’s a very specific version number. What [00:44:00] was your choice there? Because that’s something that I haven’t seen a lot in people’s code and it doesn’t mean it’s wrong. I’m just interested in what you were doing there.
Grant Sander: Yeah. I’m not gonna make a strong argument that you should do that. Honestly I think it was partly coincidental from grabbing one of the images that I uploaded.
I’m guessing that’s where that version number came from, was like the first image I uploaded and grabbed the URL for. There’s also another reason that I’ve, I left that in there was because for regular expression reasons, the fact that you can have folders, like you can have like a nested folder structure of your Cloudinary id, and you can nest things with slashes.
It can be. A little hard to figure out where your like parameters start, like your Cloudinary parameters. So like after upload you, you add in your Cloudinary parameters.
Sam Brace: Yeah.
Grant Sander: And then you can add your version number in there and then put in your like folder and path to the image. Without a very specific, like v [00:45:00] with a bunch of numbers, it can be hard to figure out from a regular expression standpoint where to inject in the parameters.
And so like we I set up some automation to take any Cloudinary URL and check to see if it had f_auto and q_auto. And if it didn’t, it would automatically inject it in there. So if people were like picking a Cloudinary URL, it would just be like we would, we had a GitHub action script set up and it would automatically add ’em in there.
And it was hard to do some of the automation without the version number there. I may have been able to do it, but, yeah, I like it.
Sam Brace: It makes sense. It makes sense.
Jen Brissman: That’s the first time that I’ve ever heard of someone using a version number, sort of as like a pipe or a place to look for. So like in your code, did you have it look for “/v” or something? Or, how did you have it?
Grant Sander: Yeah, so I guess I don’t have the code pulled open right now, but if we opened the console, like if you were to do something like you look [00:46:00] for something like “v” and then you could do like digit, multiple digits, and then you could test something like this.
I don’t know if you can see it. Let me blow that up a little more.
Jen Brissman: Yeah.
Sam Brace: Absolutely.
Grant Sander: That doesn’t pass, but if you have something like “v123”, it’ll pass that. So it, it was just a way to do like regular expression stuff, to figure out where things go. And there, again, I’m not saying, I’m not fully sold, that there’s no way to do this without the version number.
It was just the path of least resistance for me. A lot of these older images, we didn’t need to do a ton of versioning on them. And so at some point, leaving the version number out is nice because then. Cloudinary just uses the most up to date one. And yeah I would’ve to think more about I’m not a hundred percent convinced I would advise people to leave the version number in there.
It’s just something I did out of the migration process and making life a little easier. [00:47:00]
Sam Brace: And the way I look at it, Grant, is this is once again showing a real world scenario, and it worked perfectly for you. So it is to say if someone ever had issues when they’re trying to migrate things over under using regular expressions or regex, then this is a reasonable outcome in my opinion. So this is good. So now that I’ve seen this, so I feel like we’ve accomplished two steps now, but the third step, and we didn’t dive into it deeply, cause of course I backtracked this and let’s talk about code. But in the same sense, the third step was testing this migration. How did this work? So talk to me about the overall testing process.
Grant Sander: Yeah, let’s, we’re gonna run outta time at some point, so we’ll go through this one pretty quick because I think the fourth step is maybe a little more interesting. But the migration validation was pretty cool. So it was like, I wanted to make sure I didn’t totally botch things, which is good.
It’s good to validate, it’s like writing a test for your migration, which is nice. And what I did was basically built our [00:48:00] static site, which then dumped the entire built site out into a public folder, is the name of the folder, but it’s basically just like building your static site and it’s just dumping out all the HTML files for your static site.
Got it. So what I did was, again, it did some globbin’ and grabbed all of the HTML files out of the built site and another status map, because this was a process that took a little while. So saving my progress as I go. But what I did was loop through each HTML file from the build output. And I use this thing called, let’s see, Broken Link Checker is the actual name of this library, and Broken Link Checker has, I have it pulled open here.
It does a handful of things. It basically allows you to find broken links, missing images, et cetera. It’s whoa, that’s what I need to do. I need to make sure I don’t have any missing images in here. So what I did was, [00:49:00] I used this library. I just read each HTML file from the build output, and just configured this HTML checker thing to look for images.
And if an image was missing, it just pushed it onto an array, I wrote that thing out into a JSON file, and then I could just go look and say, “Hey, are there any images missing?” And if there were, it would tell me what the actual source was. And so it was really easy for me to just do a like global find in the repository to say, “all right, here’s where we missed the thing. Like what happened here?” And this was actually pretty nice because I did miss a couple images because in the migration I only migrated in the markdown files. But we had some JavaScript files where like our React code lived where we had like images, like a header image, or a footer image that was not in our content, it was like part of our actual code, like the JavaScript code. And so this was actually nice. It actually caught a handful of pretty important images that were like, not content specific, but more like header and footer images. [00:50:00] So this was an easy way just to go in and check to make sure, we didn’t miss anything.
Sam Brace: Yeah. And excellent. I like the “all good, no bueno” captures there. Fantastic work there too. Okay. So I understand the testing process and honestly, once again, this is really good playbook material for anybody that’s going through migrations when they’re going through this overall process. But then we’re now to the final step, the big one, right?
Which is where everything is live and we’re able to start going through and seeing results of this overall process. So talk to me about that.
Grant Sander: Yeah, so at this point we’ve got all our content migrated, we’ve got our image library up in the cloud. We’re ready to go. We’re ready to merge the thing and ship it live.
One of the things I did before that was just do a quick check. Like I knew we were gonna be saving bandwidth. Like it’s pretty, pretty obvious. That’s a strong word, but it was somewhat obvious that, that was gonna be the case. I didn’t have any doubt. I [00:51:00] wanted to figure out “okay, how much actual savings are we gonna get?”
Cause I did a spot check of a couple pages and I was just like this seems like quite a bit. Are we really that image heavy? Were we really overserving that much? So what I did was wrote a script. Let me go find this. To basically automate, the way I checked it was I would open a webpage, open my Chrome dev tools, and so let’s go to formidable.com, open my dev tools and go to the network panel.
That’s really big. Let me refresh this. You can select the image tab and it just shows you all of the images that load on this page. Pretty standard, dev console stuff, but it also shows you like how many bytes are being sent to this page of just images. Cause I had the image filter on, but you can do the same thing for like JavaScript or CSS images.
So what I did was just did a quick spot check on like our homepage, a couple other important pages we had up for the time. [00:52:00] And I just did a little bit of napkin math and computed, we were having savings around 75 to 80%, which I was like, maybe I should just check a bunch of pages.
But I don’t, I didn’t wanna do it manually and I wanted to be able to tweak some things and make sure things were right. So what I did was just write a script, and again, I gotta go find this, wrote a little script to basically automate that exact thing that I did using a tool called Puppeteer. So Puppeteer, just for those who don’t know, Puppeteer is a pretty cool tool.
I believe it’s out of Google.
Sam Brace: Yes.
Grant Sander: And it’s a Node library, which provides high level API control to chrome / chromium over the dev tools protocol. So basically what it allows you to do is create and automate, like controlling a Google Chrome instance. It’s basically what it is. So you can spin it up, point it to webpages.
It’s almost like a little robot driving your little chrome browser. And have a lot of APIs for doing different things. So [00:53:00] you can do a lot of pretty cool stuff with Puppeteer.
Sam Brace: Yeah, and we love puppeteer over here. It’s interesting this, you’re not the first to mention this on even a DevJams episode because we had it where people were taking screenshots of code and using that for puppeteer purposes.
We had a developer that was developing open graph images for his blog posts and doing that with some Puppeteer aspects. Fabulous tool. Can’t recommend it enough for things like this. Once again, good word, Grant, using awesome tools. So good job there.
Grant Sander: Yeah. Another interesting one that there’s better tools in the space now, but for a long time, like generating PDFs was a pain.
And so I remember like early days of using Puppeteer, you’d build a webpage that was like 8.5 inches by 11 inches. Point Puppeteer to it, do a basically simulating a command P to print the thing out and generating out like a PDF from the page. And it was like a really good way to use like web tooling.
And it was like you were designing a PDF using all the web tools that you knew, and then you just used Puppeteer to automate [00:54:00] generating those. So dynamically generated like receipts or like inventory lists, things like this. You could use Puppeteer. So a lot of really cool use cases with Puppeteer.
Sam Brace: For sure.
Grant Sander: So with what we did here for measuring images, this was tough. This was a tougher use of Puppeteer than what I’ve done in the past, but there’s some setup around getting Puppeteer up and running. But basically what we do is: launch Puppeteer. I did headless false, which shows like the actual view.
So you can see it like scrolling through pages and stuff, which is cool. I created a single page within the browser instance and just set like a viewport with- the viewport size isn’t really super important on this case- but there are some, there’s a way for you to actually create a CDPSession, which gives you like access to a dev tools instance.
So this gives you a way to like programmatically access chrome dev tools from the like robot run, [00:55:00] Puppeteer instance that you have.
Sam Brace: Okay.
Grant Sander: And then you can send signals. And this is, I found a lot of this like from guides on the internet, things like that. But one of the things you do is you enable the network functionalities of dev tools by sending it this network enable symbol.
And then there’s a lot of code here and, we’re gonna run out of time, so I don’t wanna go through all the details of everything. But one of the things that basically I did was you could tap into a couple events. And so network response received was an important one where we listened for image responses.
And so image or binary octet-stream as the content type. And then you store those because we also have another event. There’s some like coordinating that we have to do here. I won’t go all the way into the details of this, but when a loading finished, you see if it was one of those images that we caught earlier and we go and say, okay what’s the image count?
We’ll just keep track of that. And then I [00:56:00] don’t, I’m not convinced this is the perfect way to do this, but a decent indicator of the image size is the encoded data length property. And this matches up pretty well with what Chrome gives you as well, but. My impression is this this might not be perfect, but it’s pretty darn close.
So it is like good enough for us to measure. It matched up from the pages that I spot checked, it matched up like perfectly with what I saw. So for me it was good enough and it’s a consistent measure across control and treatment groups. So my opinion, it was good enough. So then I basically just had- there’s some math here.
We won’t, we don’t need to look too much at the, like dividing some stuff, but basically, it is pretty standard comparison like percentage stuff. But I have a control URL, which is was at the time our production site and then a staging URL where the new Cloudinary version lived.
And so I have a control group and a treatment group. And for each URL that I wanted to test, I would point Puppeteer to [00:57:00] the URL for the production one. And then for the staging one, measure all the stuff. I did a scroll, too, to basically scroll down the entire page to get the lazy loaded images to load.
So that’s, pretty common for images to load lazy. Wait for the network to idle so that you can capture all of the like loading, finished events to make sure like all the images load in, and then just return back the like total, which was like the total number of like encoded bytes. And then I wrote all that into a JSON file, did the percent calculations, things like that.
And the results I know we’re, we’ve just got a few minutes, but the results were pretty, pretty amazing from, just from like our homepage, for example, 27 images, percent saving was 48%. We had a lot of these that were like 86 to 90%. All of our image heavy pages. We have case studies that have these beautiful graphics and these ones we saved a lot.
A lot of these, the average across the 30 pages was a about 80. It was a [00:58:00] little over 86% bandwidth saving, which was…
Jen Brissman: wow.
Grant Sander: Quite a bit more than I was expecting. It was a surprising amount.
Jen Brissman: Yeah. Amazing.
Sam Brace: One thing that I wanted to ask you about, because now that we’ve seen the overall process and, it’s great, because as I’ve said a few times now, this is giving people a real world view of how they could actually accomplish a lot of these tasks with the tools that you’ve gone and shown.
Of course, they may not have your expertise, and so they needed some help to be able to go down this path, but you’ve given it to them. But to wrap this all up, so as we have talked about the very beginning of this conversation, Formidable is doing a lot of development and design work for clients for large companies.
You also said small startups, but people that need design and development help. With the learnings that you took through this project to help out the Formidable site, how are you now applying some of that to your client base?
Grant Sander: Yeah, I think one of the big things is we’re very eager to [00:59:00] recommend services like Cloudinary early, like upfront in the development process, so that you can just avoid having to migrate at all. Because migration comes at a cost, like you have to do the work. And so one of the things is just here’s an example of how much you can save by using a service like Cloudinary. Just use it upfront. If you know that you’re gonna have a lot of images, user-generated images, a lot of content, visual heavy content, just start with Cloudinary upfront.
So I think that’s our recommendation to our clients now, is like you said, best of breed. Choose the thing that’s gonna get the job done the best and this is a good showcase of that.
Sam Brace: And I would also even say, I appreciate you recommending Cloudinary, but it’s also, I think even in strong message, that’s not as about us, is just you really do need to think about your images and videos and how they’re gonna be displayed, how they’re gonna load.
It’s a very important part to how users experience these websites. So I think the fact that you’re addressing Cloudinary at the beginning is also stating to [01:00:00] them, you need to have a strategy when it comes to how you want your images and videos to be loading and how you want the user to receive those and be actionable with that information.
So I love the fact that you’re making your clients think about media more, which is great.
Grant Sander: Yeah, absolutely.
Sam Brace: Jen, final thoughts here. What do you think, is there anything that’s burning in your brain here about what me and Grant and you have covered here today?
Jen Brissman: Yeah, the biggest thing is we’ve talked a lot about images today. And especially with client work, my brain was already going to “okay. What about other types of media?” “Is Grant, are any of his clients asking about 3D or audio or video?” We’ve really focused on images today, but Grant, do you think this would apply to everything?
Grant Sander: Yeah, I think video is at least as complex as image is and we have, for example, our Puma team has been doing some exploration with using Cloudinary’s programmatic video generation and delivery. And so we’ve been doing some [01:01:00] exploration on the video front where we have, either like content author driven videos or even user generated videos, and figuring out how to like programmatically handle those in a efficient way. So we have been looking. We haven’t done a ton in the 3D space, but video is definitely something that’s on our radar and especially with like video becoming a pretty popular medium right now.
A lot of places are moving into the video space and allowing for user generated video stuff and so definitely on our radar.
Jen Brissman: Absolutely. Yeah. Video and mobile and everything like that. And I actually find that Cloudinary is incredibly powerful when it comes to q_auto with video. The results are pretty mind boggling in my opinion.
Sam Brace: Exciting. Thank you so much for being here. This was fantastic. We appreciate all of your time, we appreciate your insights and obviously you’re doing some great work over at Formidable, as well as the entire Formidable team, so keep it up. This [01:02:00] is fantastic work.
Grant Sander: Yeah, thanks for having me. It was a blast.
Sam Brace: Excellent. And so of course, Jen, as we have pointed out right at the very beginning, but it’s worth stating again for everybody here, that all of these episodes, if you’ve enjoyed this one or wanna see what else we’ve talked about, because we’ve mentioned with some of these technologies that Grant covered, we’ve covered them in other episodes as well.
You can always visit all of those at cloudinary.com/podcasts and dive into all of the various episodes of podcasts that Cloudinary produces on that site. And of course, if you have other things that you wanna discuss around what Grant has covered here, the best place to do that is the Cloudinary Community.
That’s gonna be at community.cloudinary.com. And you can see that we have forums for people that wanna have more of a threaded conversation, and ways to keep track of things a little bit easier. But also we do have a Discord server for those that are Discord users, and to have that as a real-time chat option as well for the overall community.
So absolutely make sure that you [01:03:00] guys are diving into all of that content. And as mentioned before, everything that we covered in this episode is also covered in depth in Grants blog post, which is found on formidable.com, which we do recommend that you read for more deep details of everything that was in this overall episode.
So Jen, before we let everybody go, any final thoughts before we say goodbye to our friends and family here at DevJams?
Jen Brissman: Well, lots of thoughts, and that was a really interesting episode for sure. But one of the main takeaways for me is how creative you can be with the givens. So for instance, just something like version number, it’s not something, all of our customers use or that would apply to every use case.
And Grant was using it in a unique way and it just really goes to show you can be creative with what you’re given and yeah I wonder if anyone watching might do something like that now after, after seeing what Grant did.
Sam Brace: I agree, I agree. Absolutely. And amazing takeaway, Jen. So on behalf of everybody at Cloudinary and of course those that were involved with the overall [01:04:00] program in this development, thank you for being part of this DevJams episode, and we are excited to see you at the future ones that we do produce.
Take care and we’ll see you soon.
2023-07-11
Building a Publish Extension for Canva and Cloudinary
With Canva being one of the hottest tools for creative and design projects, Cloudinary’s Igor Vorobeychik decided to build out a Canva-Cloudinary connector to help streamline work for those who use both platforms! This allows people to create their design in Canva, then publish it to Cloudinary for delivery onto websites, mobile apps and more. Cloudinary’s Customer Education team will be walking through Igor’s Canva Publish Extension to show how he built it, and better understand how to create deep connections between mutually beneficial systems via code. Together, we will dive into his scripts that use Cloudinary’s Node.js SDK, Express, and more.
Sam Brace: [00:00:00] Hey there. Welcome to DevJams. This is where we talk with developers who are doing very interesting things. Maybe they’re projects that are pushing the boundaries of what’s possible with image and video management and delivery. Maybe they’re looking at things from a different perspective. Maybe it’s just things that we got really excited about here at Cloudinary, and that’s where we’re gonna be talking about the intersection of where developers are building awesome, amazing projects and how they’re incorporating Cloudinary into those projects.
My name is Sam Brace. I am the Senior Director of customer Education and Community here at Cloudinary. And in this DevJams episode, we’re gonna be talking with one of our very own employees, one of our solutions architects, Igor, and he has gone and developed an amazing project connecting [00:01:00] together Canva, one of the best, most widely used tools when it comes to creating content, specifically, maybe slides, maybe graphics, all sorts of things you can do with Canva.
It’s a tool that I personally love using, and I’m very excited to show how he created this connector between Canva and Cloudinary to really make sure that there’s a space for creating this overall content inside of Canva, and then making sure that it can be optimized, delivered perfectly for websites, mobile projects, and other various needs via Cloudinary.
Joining me for this episode is Becky Peltz. And Becky Peltz, of course, is somebody that you’ve seen in almost every Dev Jams episode, and she oversees our overall curriculum and learning opportunities at Cloudinary for our developers that are using Cloudinary. So Becky, it is wonderful to have you here for this episode.
Becky Peltz: Hey, I’m excited to be here. I used Canva as an instructional design [00:02:00] student for many years, and I was always downloading it from Canva, uploading it to Cloudinary, and so I love this project and it’s great to be here.
Sam Brace: I completely agree. What’s wonderful about this, as you’re pointing out, is that is a flow, but not only you have faced and I have faced, but it’s probably something that millions of Canva users have faced, is they probably have certain times where they say, I would love to have this delivered as a URL, and not only as a URL to make sure it’s optimized of all of the various things to make sure that it loads quickly and efficiently on people’s devices, on people’s browsers.
So it’s to say that this is not just a niche use case, and it’s something that excites maybe a portion of the population. To me, this is something that every Canva user can benefit from the work that Igor is gonna be showing us here today. So I’m very excited by that.
Becky Peltz: Yeah, and I think for developers we have a lot of integrations with a lot of [00:03:00] different tools, headless tools, image video tools.
But I think it’s interesting to be able to see how an integration is created, and in Igor’s process, he worked with the Canva documentation, and to just of see how how this integration is done using a node server. So I, there’s many different ways to integrate and this is an interesting one..
Sam Brace: Exactly. And I gotta tell you, if you’re a developer that is trying to figure out ways to connect two like-minded systems together, you’re gonna find an absolute amazing learning resource in this. But if you’re just a Canva user or a Cloudinary user and you’re trying to say huh, I’ve always wondered if those two systems can work together, there’s all sorts of things you’re gonna be able to extract from this.
So should be a great conversation with Igor. One thing I do wanna point out before we bring our friend Igor onto this to start talking all about his project, is we do wanna point out that all Cloudinary podcasts, including the one that you’re part of here today, which is DevJams, that is gonna be found at [00:04:00] cloudinary.com/podcasts.
And as we can see here on the screen, that is where you’re able to go through and review all of the previous podcasts that we have gone and issued across the many different programs that we do have. And of course you can dive into the episodes and watch them and listen to them as you so choose. And similarly, you can enjoy these on any of the services that you we happen to be on.
That includes our own Cloudinary Academy, YouTube, also in listening only mode for various services like Spotify, Apple Podcasts, Google Podcasts and more. And we’re gonna have some great conversations here today. But if you wanna continue those conversations, pass this episode, know that you can always head over to community.cloudinary.com and be part of all of those various discussions that are taking place so you can meet other users maybe those like Igor or maybe those that were previous guests on DevJams, or people that have never been on DevJams, but possibly could be because they’re doing great things with our overall service and pushing the [00:05:00] boundaries of what’s possible with image and video delivery and management programmatically.
So want to make sure everybody is aware of those things before we jump on over to talk with Igor. Igor, let’s have you come on to the program. Great to have you here.
Igor Vorobeychik: Hi there.
Sam Brace: Igor, let’s get a little bit of context here. So I gave you the audience some details saying you’re a Solutions Architect that works at Cloudinary.
I didn’t give anybody much more detail. So go ahead, give us a little bit of flavor about who is Igor and why are you here today.
Igor Vorobeychik: Thank you. Thank you Sam. Thank you Becky. And yes, I’m a new, relatively new solution architect in Cloudinary. Even though almost a year within the Cloudinary. And I’ve been in the industry since year 2000.
So been sometime in different roles as a web developer, team lead, as a managed [00:06:00] professional services, integrated lots of different systems during my career. Excited to be part of the Cloudinary family. And this is more or less my background.
Sam Brace: And what’s great about what’s happening here is that, of course, you’re a first guest that is really coming from the solutions team. We typically pro profile people from the outside, people that have done something with no ties to Cloudinary before, other than maybe reading the documentation, maybe being inspired by some of the training courses we have, and they go and build something. But you of course work with us and we get the chance to interact with you on a daily basis.
Tell us about why you decided as part of the getting to learn Cloudinary phase, being within Cloudinary and understanding what it’s about. What inspired to do this project that you have here today, connecting Canva and Cloudinary together?
Igor Vorobeychik: Sure. First of all before even I decided to join [00:07:00] Cloudinary, I was excited about Cloudinary onboarding process, right?
Which sounds for me, unique. Some companies doesn’t even have such a process. And part of this process was actually, that was clear to me from my manager, is that I will have to build some sort of a project. The project should be something real, not some, imaginary and unusable project project should be maybe even blog, something facing our customers. And I said, this company probably does something right if they want their own employees actually use the software, try it. And they actually later deliver it to the clients and customers. And I was excited already in this part. I was sold pretty much in the beginning. And eventually due to my background in [00:08:00] some building some online editors or involved in lots of integration, when I saw one of the projects or possibilities to build something with Canva, there was an easy choice for me.
Sam Brace: Well, and I think the great thing about being able to do this, is that, as you’re saying, it’s real. It’s code that people can use today to be able to bring these two systems that don’t have direct integrations, official integrations, together, but you are able to create something that really is gonna benefit so many users and also give essentially developers an answer when someone says, can you connect these systems together? You’ve given ’em a very clear pathway, which I love that was part of your graduation project as a good term that is out there. A way for you to say, I’m putting my work out into the world. This is my first way to tell people I’m working at Cloudinary. And be able to do that in an excellent way. So that was fantastic that you’ve been able to pull this off. But what inspired you to look at Canva? Was there ever [00:09:00] experiences working with it or seeing it out in the wild? Maybe personally, professionally? What got you to say I should link this to Cloudinary?
Igor Vorobeychik: So for the past 15 years I was actually working a lot with the a lot of Adobe products, right?
InDesign, Photoshop, a lot of personalization using InDesign servers and et cetera. We had lots of requirement from users to have something as powerful as Photoshop. Maybe not necessary as complex as Photoshop, but for the wide variety of customers, and have it online, right? And I would say about already maybe four or five years ago, the Canva, everybody was talking about Canva. I said, I need to look at the Canva. And by the way, my own previous job we had our own proprietary online editor. When I saw the Canva, just blew my mind. And this is a unique [00:10:00] Australian company which developed something unique.
And when I joined Cloudinary, I saw parallels that Canva was the best at what they do in the design space, right? And Cloudinary is the best of what they do with the media. And and for me it was interesting to combine those two. And actually I think you started your podcast with with something that millions of users are using Canva.
And I actually today Googled, I think I found that, again, it’s a bit old article, but in 2022, the projection was that they were gonna hit about 1 million user mark. So an amazing, so I always, I had some commercial way of looking at one new build, [00:11:00] right? One one way is to build something which can be useful, but that if our developers can also make it out of it, a successful product.
So I think to this connector can expose them, can expose their Cloudinary, maybe to a millions of users, right? It could be a business to business, it could be a B2C. So it just gives them ideas of how they can actually help millions of users to deliver media. And that’s what’s exciting, I think about it.
Becky Peltz: Yeah, I think this is interesting too. I was looking at the documentation from Canva and I noticed that we’ll be seeing movement from Canva into Cloudinary, but you can actually move both ways. So here you have these two kind of headless media companies able to exchange with each other and then of course other websites if needed.
So it’s just a really cool integration [00:12:00] between these two companies and their product.
Sam Brace: Absolutely. So Igor, let’s do a quick walkthrough of this so that way everybody understands what this is. Cause I think we’ve talked about conceptually enough where something’s happening in Canva, content creation, and then it’s gonna be delivered by Cloudinary.
But let’s see the overall flow of this thing. So I’m gonna bring your screen in here and maybe we can do a quick demonstration.
Igor Vorobeychik: Sure. Absolutely. So here I’m in Canva, right? And I want to create my design. Let’s assume it’s some Instagram post maybe, right? I can choose from variety of different designs, like templates, right?
And I don’t know, maybe this is an HR type of post like we are hiring or some other stuff. Maybe I want to to [00:13:00] customize it, right? Once I customize it, I would like probably to publish it, right? And this is where the a lot of customers will say, okay, what do I do? How do I make sure that it will be delivered in most optimized format?
How I will actually use this CDN also, so it’s gonna be cashed super fast and et cetera, et cetera. So millions of users can see this fast and et cetera. And this is where the integration. So all they need, if let’s say they have already a Cloudinary account, and they have an integration, then they just, in this case, I have this already integration in place.
I’m choosing the Cloudinary, it’s already connected to my particular cloud, right? And I can choose maybe some folder where I want to maybe organize something [00:14:00] like that. Maybe I can choose the format, one of the formats that’s available for me to save this. This is, by the way, configurable by your extension.
Maybe provide some message that can be used later on there, and save it. If all went well and my extension is up and running, first of all, you’re gonna get back already a URL, which can be shared, right? The version which we just customized, right? If those of you who know Cloudinary, you will see that this version include f_auto, q_auto, meaning is optimized format, optimized quality.
And again, we can go wild here and add more transformation even on top [00:15:00] of this asset, and if we will go to the Cloudinary, and let’s say go to this folder, we will find this asset now. And we also can notice that I applied some contextual metadata. I applied some tags to it, right?
So that can be also searchable within my my let’s say asset library to find something that has certain tags something that maybe has a contextual metadata we scan by id. So I can basically not only publish it, but also organize it in a certain way within the Cloudinary, right?
And obviously this [00:16:00] published URL now can be served in any systems can can be used on any website. So that’s the overall workflow final workflow which we see.
Sam Brace: It’s incredible and I think what’s amazing about it is that you’ve able to done do a few things that you’ve pointed out really is that if you wanna make sure that this is now easily searchable for inside of your Cloudinary system, you’ve now shown how adding something into the comments field be as searchable content that when it makes its way into Cloudinary as an asset.
I think it’s also where we didn’t have to wait long. This is a real-time demonstration. This wasn’t taped prior or anything like that. And then you add something where you created in Canva, you delivered it in to Cloudinary within a minute, if less it’s incredible what you just pulled off here at Igor.
Becky, I didn’t mean to interrupt you. You had a point there.
Becky Peltz: No problem. But yeah, I was struck by the, same thing. We’ve taken an [00:17:00] image that had really no context, no metadata, and made it into, put it into a place where it can be, have a high amount of context and be pulled in from many different data identifiers like the tag or the context metadata.
So I think that’s something to look for as we see how you implemented this Igor is how did you get that context associated with those images that you are pulling in?
Igor Vorobeychik: Yeah, absolutely. So this is where we can, we will need to already get in the bits and bytes of the integration. So I guess that would be a natural progression.
So for those that would like maybe later go a bit more detailed I do have a blog that you can find that describes how to build Canva extension give you pretty much [00:18:00] all the information you need. This is just like for your reference, right? So have you detailed here.
We may not be able to dive into all the aspects here. For this particular project and also the project that was facing the public, I decided to use Glitch. Glitch is a very easy way where you can create an application. You do not have to use any desktop id you pretty much, any student can use it.
He doesn’t have need to have a very powerful computer or any proprietary software. He can create a very powerful application. I use the, in this particular express framework. This is for for, to create my REST API influence that should [00:19:00] satisfy Canva publish extension.
We’re going to get into details a bit more. So I use Glitch as a platform where I develop the poc and also also something that is actually the, where I published my endpoint, right? So this is a development environment plus actual my endpoint resides on this system and can be accessed, right?
So it’s self-contained. Some of you may use some IDE Visual Studio Code. They maybe gonna use git or GitHub to, for their PUT versioning and eventually they may use, I don’t know, let’s say AWS to actually publish their lambda their endpoints. But this is more like self-contained.
A bit easier to understand. But I also love Glitch, its [00:20:00] an awesome company, which was acquired by Fastly, which is also a Cloudinary CDN partner. This is what I used for this particular project.
Becky Peltz: Hey, just not to interrupt you, but excuse me, Igor, but for this extension, now I, as I understand it, you need a base URL. So, whatever code that you, however you package it up, whether in Glitch or in serverless functions, you will need a base URL. So you get that automatically from Glitch, right?
Igor Vorobeychik: Exactly. So your like a unique name space, right? You call it a domain name. You obviously have a more robust version and pay for your CNAMEs and have but yes, it was [00:21:00] very easy to use because I got all my domain names, everything set up for me pretty much, right? You getting it. And it, it was very easy. Now, Canva also has tremendous documentation. And I actually when I look, looked at Canva documentation, look in Cloudinary and saw how we both create a very unique content in a very professional way.
So it was so easy for me being a new SA within Cloudinary just by reading some of the documentation, try the samples, right? Be able to achieve what you see here in, in a very few days. Literally.
Sam Brace: This was new to me because, like I’ve always thought, this is my ignorance, is that I [00:22:00] always thought of Canva as being a very UI based tool, but as I started going down the rabbit hole and being like, oh, but have great developer documentation and seeing this area, it was very enlightening for me to be able to see this project, but also to see the various layers that Canva has created to be able to create these types of connections that you’ve gone and showed here.
So I can see here on your screen the way that they’re calling this is a publication or a published extension. So what they’re ultimately doing is it’s getting added to the published menu of Canva and it becomes an app just like you chose it from in this space. And that’s what they’re encouraging developers to be creating.
Igor Vorobeychik: Exactly. So Canva has lots of out of the box extensions, but it also allow developers to create their own. And there are several types of extension. There are content extension. For example, one of the next steps maybe would be [00:23:00] bringing assets from Cloudinary, and that would be a content extension, right?
So this is, would be probably on the left when you do upload, that’s what it called content extension. Where you’re taking the extension from your asset from right where you selecting your asset. Not necessary. You start from design. Maybe you want to bring in us another type of extension is this is where you publish and it’s a publish extension.
So here you see my extension, but if I do more, you will see that a lot of connectors are already there. And those can, some of them are written by well known companies like Instagram and et cetera, right? But some of them, like mine was written by developers, right? So there is lots of extensions and there is a great [00:24:00] developer documentation that allow you pretty much, very quickly read about extension you want go with a quick start user guide, right?
There are examples here, and I, by the way, I choose Glitch, not just because it was also one of the easiest choices because I pretty much maybe get a project that I could have just click remix, right? And then start develop my own.
Becky Peltz: So its like a quick start here, huh? They’ve given you kind of a quick start for doing your extension.
Igor Vorobeychik: Exactly.
Becky Peltz: Giving you a sandbox.
Igor Vorobeychik: Exactly. Yeah. So maybe this sample is much simpler than the one that you see. Or actually, my example would be a combination of lots of samples that you will, you may find, and obviously a bit more [00:25:00] customized for Cloudinary needs, right? Or for, with the Cloudinary in mind.
But definitely the quick start user guides here, and by the way, on Cloudinary documentation, you will find a lot of also quickstart user guide samples also that use Glitch and some other systems that just allow you to play with the code, how you implement I dunno, Product Gallery Widget of Cloudinary etc…
So it’s today is very common where developers can quickly progress from documentation to some online sandbox where they can actually play with a tool before they, let’s say, purchase anything or before they decide or use this library another. So they, yeah, the, there is a very short path today from documentation to [00:26:00] actual actual sandbox and the prototype which our developers can build and that’s very exciting.
Sam Brace: Now, Igor, one thing that I know is a big thing that Becky and I always talk about in training, especially with Cloudinary, and I wanna address it in your project because I think you did a good job with being able to handle it well, is something called environment variables. And then basically making sure that’s not exposed to the public users in any way through something called a .env file.
Can you show me how you maybe did that? Maybe how Canva looks at that concept inside of your project?
Igor Vorobeychik: Yes. In order for us to build the extension, we need at least a few things. One of them obviously if we want to push asset to Cloudinary, we need to store Cloudinary application keys, right?
Basically how we execute the APIs. So in [00:27:00] my particular case, what I was doing, I was using the .env library, right? Which is using env file that allowed me to store pretty much different keys. So this is where I stored my keys. Now the interesting thing is if you will come here and and remix this project.
To make it of your own or you trying to view it as a different user, you will not going to see this information. You see it’s stripped out for you. To be honest, I was a bit worried in the beginning. That’s why I created, and I think in the blog post I created a, what I called public endpoint just for blog purposes where I [00:28:00] actually, in the instructions tell you create a .env I just given an extra layer of security there. I was afraid to store it there, but Glitch takes care of it, right? No worries. There, let’s go back to my Cloudinary endpoint, and let’s talk about the second key. Why do I have a, another value here is the Canva client secret.
So, Canva build with security in mind, right? When you start developing your application. And this is already, I already created, I can create new app right there in the Canva UI so you will see that one of the things is verification, and this is one of the actually things I really like, so your end point, Canva actually wants to ensure that whatever [00:29:00] you will develop be secure for its users, that endpoint will actually will implement the security measurements. Even if you can run the security tests and they actually will submit various client secret timestamps.
They will try to fail you and you should actually, your service should return a proper http response. If you do not, you will not be able to, let’s say, publish such extension, stuff like that.
Becky Peltz: Now, I noticed too that there’s a regenerate button there, so if anybody was trying to copy down your key when you showed it with the .env
Igor Vorobeychik: Obviously. Yeah, good point. Obviously right now…
Becky Peltz: Cloudinary has the same thing.
Igor Vorobeychik: Yeah. Obviously right now everybody will see this key and we are recording it, so obviously this is not something, so after the call will regenerate a new one and [00:30:00] then I will be able to use. But yes, the security in mind, this is great. This is by the way where I point to my own endpoint which is on Glitch.
And basically your project name will be the entry, right? The URL for your endpoint, right? And again awesome awesome very on one hand is simple, but everything in Canva is very so first of all you noticed that I had some user interface where I selected the folders.
Now since Canva wants to control kind of user experience, right? They don’t want that different plugins or [00:31:00] extensions look slightly different. They want some sort of unified look and feel, right? So they provide you pretty much with the user interface.
You just need to to write couple of endpoints to feed the information to the…
Becky Peltz: You’re gonna start out with an endpoint that is gonna go get you something, and then therefore they’re gonna have some UI that has lists or a single item.
Igor Vorobeychik: Yeah. And yes, Rebecca. Absolutely. So when you said word get, and this is exactly, actually, almost the name. Find and get the endpoint name. So even from the names of the endpoint, which Canva ask you to actually to write, it’s very easy to, it’s not some, special names. So for publishing, they using upload by the [00:32:00] way, I found that the upload endpoint. Is very similar to Cloudinary upload, right? So it’s an upload, which is mean published, and this is exactly what you do when you so a lot of similarity in terminology you say .And then yes, there are there is a find that’s basically something which loops through directories, right? So I used here a couple of Cloudinary APIs. In this case I used the sub folder API. And then eventually there is a get, once you find what you want, basically you are passing back the exact sub folder that you decide to place your item there, right?
The final URL. Now that was developed before Cloudinary I think had dynamic folders. Now we have dynamic [00:33:00] folders that maybe would do it differently, but again, the concept of structure or place your designs and organize it within the DAM still applies here.
Becky Peltz: Yeah, and it looks like inside there go and you get these resources and then you map them in your, I think it would be down a little bit from what I’m seeing, maybe line 120 or so where you were just, where you were at.
You, so down there at Oh, up a little bit. I see like line 115 there. So you take what you get out of the subfolder response and you map it to their object type id
Igor Vorobeychik: I will pass, yeah. All this information to their object so they can also build the UI, and eventually once something is selected, then they actually can already call the upload API, and pass what was selected because [00:34:00] it was done by different endpoint. The define and they get the actual path, let’s say, where you want to store it. And actually those few lines of code are responsible to push it to the cloud, right? And literally few lines of code as what we upload
I’m using the logs a lot in this just to debug and see what information is sent to me. That’s how I was able to understand exactly what type of let’s say body structure they sent to me, right? So I could access the URL of the asset, right? I can get a design id, right?
Canva, design id, which I decided using as a file name. And because I’m using a [00:35:00] default upload preset, even if I will reuse the same design id. But there is a unique unique characters are added by Cloudinary, so I do not override, again, I could have decided to override. It depends on the workflow.
Now right before actually I do provide some contextual metadata. I could have provided me maybe create structure metadata. Now right before, actually…
Sam Brace: Before you jump to that I wanna point out something that I love what you did there, because if you look at the context, if this is the connection of what we saw earlier in your demonstration where when you added in comments then how did those become searchable fields within Cloudinary when we were trying to find the files? And it’s because of its plus message that you see here, like the request body message. That’s that direct connection for us to know that we’re applying this as context metadata. So it’s, that was genius because you could see [00:36:00] people, adding lots of things, frankly, in the Canva UI to be able to explain what’s happening there and knowing that all of those become searchable keywords for people to find that asset later with Cloudinary. That’s a great feature that you added in there. It’s very smart.
Igor Vorobeychik: Yeah, thank you. And my personal favorite, actually, tags, right? Actually I had added just tags today. I when I joined the Cloudinary, I didn’t put much attention on the tags, but once I discovered the power of Cloudinary tags, it just blew my mind.
And also list APIs that are around it. Again, we probably need a different session on those, but that’s why I added this in another line here, just to add the tags. And obviously now in this case, you need to know the tag if you search by it, right? So if the design id is something generated by [00:37:00] Canva unique and basically has no particular structure it would be hard for you to guess that one, right? So you probably, when you are using the tags, this may be not the best field from design id from Canva to use. I would use here maybe something more more human readable or understandable or guessable, right? Let’s say some name or whatever.
But the idea is that you can apply tag and then doesn’t matter how many variations you will create of the same design, you can search by the same tag and then get all of those designs for you. So we can obviously very quickly demonstrate the same, we’ll just, let’s say create v2, right? Version two, right?
And then we will gonna share it again. And let’s say, I’m gonna put it even in the samples folder. I don’t [00:38:00] have to even put it in the same folder. Different message. By the way, this message in my case is required. You can make it not required. Just the configuration of the extension is on the published extension.
So now it’s saving. I want to show you, by the way, that when we saved all the information, I just put it in the log. Just easier to see. You will see here that I got all the information from Canva the file name, the type, the design id, right? So that’s the actual tag. And then I also store here response from from Cloudinary. Now let’s go back.
Becky Peltz: So just to [00:39:00] make it clear, you, this is where you’re calling our Cloudinary Upload API and pulling something from Canva, which is pulled in by its design ID into use as file name.
Igor Vorobeychik: I’m not pulling it per se. It’s more common when it calls the endpoint. It passes in the message that passes message body and message header.
The header is used for security to actually do some. You will see each method use validation of this post message. That’s what you use in the security. And remember the key which discuss Canva id and the body is a JSON body object that you can get an information from Canva take it from there and then pass it to Cloudinary.
That probably would be more accurate description of what happened. So if we go right now back to Cloudinary to [00:40:00] the, to Cloudinary and maybe go to, I don’t know, to advance search and maybe right now know the tag, but let’s say I’m just gonna apply the tag. So now I have two designs, right? Now this is v2 and this is actually marked as a new.
We see the nice preview here. This is v2, this is v1, right? Or basically our first creation, right? They have slightly different, I think message one has a test and another has, ah, they both have tests. I guess I, in both cases, wrote tests. But the idea is that I have two variations, right? But they all belong to the same design Id.
Then maybe later I can do something about it, right? Maybe in the future I will open up Canva from Cloudinary and load the design id, right? [00:41:00] Load design id, I just given the ideas where we can bring it to the future. The most important that you can tag, you can affect your file name.
You can do lots of stuff. You can organize your content and most important, you publish in it, in the multi-CDN environment of Cloudinary. And this later can be served in the most optimal optimized format and quality, any type of transformation.
Sam Brace: One thing I wanna do, let’s jump back to Glitch for a second cause I do want to unpackage one more thing that happens to be in your code that I think is gonna be very helpful for people when they’re working between these two systems.
Scroll down until we see resource type, I think it’s line 44 if I remember correctly. There we go. See it exposed. So Line 44. Resource type. So as we know, because we work at Cloudinary, This is where we’re saying, is this an [00:42:00] image? Is this a video or is this a raw file? And raw file could be any file tape that is not able to be transformed, meaning we’re not gonna resize it or crop it or change its format in other things that we can do.
There’s hundreds of things we can do with it, but it’s to say what I like that you’ve done here though, is you’ve called our auto resource type situation. Because when someone is working with a system like Canva, they’re gonna be bringing forward images like we saw. We’re gonna be bringing forward JPEGs, PNGs that were created in Canva, and then make sure we’re deliverable inside of Cloudinary.
But what’s also possible with a system like Canva is you might be bringing forward documents such as maybe a PowerPoint file or something that’s going to be, we consider them images the way that we work from the Cloudinary, but PDFs could be considered documents too. So it’s to say you don’t have to think about what’s coming from a system, it’ll just automatically detect it and make sure it applies the appropriate resource type.
So I thought that was very smart, once again to make sure this was future-proofing, this, making sure that all types of [00:43:00] users could benefit from this when they’re connecting these two systems together. So that was a good call on your code.
Igor Vorobeychik: Yeah. Thank you Sam. Yeah, and this was just for simplicity. You don’t have to think what type of the asset you have.
And as you saw in when we are actually posting something or let’s say, and sharing, we can decide on different type of format, right? And suddenly it can be become a PDF, right? And obviously in order not to have some if else statements or others, and maybe even on Cloudinary, you can use PDF as image and as raw.
So that’s where maybe you will need eventually get into the, those case or if statements, if you want really let’s say taking control, right? How you want those files be [00:44:00] accepted by Cloudinary, right? But if you don’t, then auto is a very good option to, to use. So now actually I’m gonna get back, and this is going to be in this case could be a PDF, but also we are going go to Cloudinary right now.
Let’s see, we’re gonna go through the Cloudinary and reload or refresh or now we have another asset, right? Image format, PDF, right? So, that’s just the power of Cloudinary.
Sam Brace: It is. Now one thing that I’m missing right now in the code situation and, I’d love for you to see it cause we’ve referenced this a few times, is this f_auto and q_auto that we keep talking about.
And of course f_auto means automatic format, so that way when you’re getting these as JPEGs or PNGs [00:45:00] from Canva, we at Cloudinary can deliver them in the most optimal format possible. So it may not stay as that JPEG or PNG, it might become a WebP as an example, or it might stay as that if we see that as most optimal.
But it’s allowing Cloudinary to help make the choice so that way the content is as lightweight as possible, but it’s only based on format. But, and q_auto is similar when it comes to the compression side, making sure that we’re providing the most optimal level of compression based on the person’s browser and and frankly, device as well.
But what I’m wondering is how are you applying this f_auto q_auto inside of your code? What’s making that be appended into the URL?
Igor Vorobeychik: Sure. In my particular, there is various techniques that you can use, right? I decided to use actually another Cloudinary method, right? That is basically the URL the method that allows me to [00:46:00] build the URL.
We also have a method that allows you actually to build the whole image tag, right? If we want the whole image tag, I use the URL here and within the URL, once I uploaded to Cloudinary and got back as part of the result, a public id, right? If you remember, I told you that I allow here to use a dynamic upload presets, which actually generates the unique name for these uploaded files.
It adds some characters. So I do not know, at this stage, what will be the public id. That’s why I need the response. Once the Cloudinary uploaded and I’m gonna get the public id. Now, once I get the public id, I can build the URL. And here again you can use any of your requirements. I do here very bare minimum,
I saying use version I don’t have to use version if I don’t want to. [00:47:00] I would like to use transformation. In this case, I’m saying I would like to use quality fetch format, which is auto, right? I could have specified particular format I want to use, right? I could have specified particular quality I would like to use, right?
I could have add all hundreds different transformations which Cloudinary supports and generate URL, right? So this is something that can be I’m not using here again, that was build when I just step into the Cloudinary world. You can use here name transformations, right?
Which is very powerful because then you actually give something of another like encapsulation. So basically let’s say if I would add here a name transformation, then I could have [00:48:00] used Cloudinary and build very complex name transformation, right? And give it to the no code user, right?
The user doesn’t have to write the code maybe later to change this name transformation, right? And use Cloudinary transformation builder for that, right?
Sam Brace: Hold on, Igor, I mean as big as you can make this, the fact that you are even able to apply just these two is so powerful too. So it’s to say yeah, you can always iterate, but this is pretty impressive in itself to be able to add f_auto q_auto to every URL.
And then Becky, make sure I’m understanding this correctly. So if I’m looking at this flow that we have here, we have it where we have the endpoint that’s using the Upload API. And then we’re calling, is this the URL helper method that’s taking place for all of this f_auto q_auto and URL generation take place?
Becky Peltz: Yeah. Yeah. So the Uploader, the API returns a [00:49:00] promise and Igor’s dealing that, dealing with that, using the, then so he gets the upload result back after the upload is successfully done and now he has access to the upload response, which contains lots of information. And some of that information is that public id.
So upload Result public ID is the unique identifier from Cloudinary upload result format was the original format that he used to upload version is the result version. So he’s able to pull in data out of the response and use that to generate a unique URL from the Cloudinary URL and there are other kind of, I call ’em helper methods.
This one builds a URL. There’s one that will build you an image tag. There’s one that will build you a video tag and they basically just produce strings. And then once you request that string in your browser, it goes through a lot of processing and eventually gets served off of a CDN. So [00:50:00] lot, a lot of things going on once you’ve got a Cloudinary URL that you can take advantage of.
Sam Brace: I love it. This is absolutely fantastic. Igor, you of course you wrote this or there’s so much we can unpackage, but whatever big things do we wanna make sure that people understand, like maybe was there any roadblocks that you came across? Was there any big learnings that you came when you were building this project that is worth unpackaging for the audience?
Igor Vorobeychik: Some little things which I found is maybe that I couldn’t actually find in documentation or wasn’t wasn’t clear. For example, when I used the subfolders API of Cloudinary the Cloudinary has also root folders of something API, which I didn’t want to use both.
And then I found the way, if I will just pass the back slash, that’s actually give me a route, the little things like that. [00:51:00] Also I found a bit not a clunky, but I spent some time on the not necessarily on Cloudinary end, but on the Canva around the validation, right? All of these validation of security which implemented here, which I advise to go and look at, right?
A bit more closely. What else? The rest is a, I wouldn’t say that other things are basically wasn’t that hard to implement. And again even if you new to node JS, if you are new to Cloudinary, new to Canva, you should using this blog and those few resources put this together in several days and already have your own Canva published extension. Now, my extension is not public [00:52:00] extension. This extension is of the it’s a team team extension, right? So when you publish it, you basically do not have to go through scrutiny of the Canva, which should make it available for millions of users.
Obviously there are there are some things that you will have to fulfill, but so it’s a bit easier to build your prototype to play with it. And then obviously expose it within your organization. So that’s what I was using here. I found this a very easy way of. If you, let’s say, building a new version, which you wanna point to, different end point.
Maybe this is fraud and you wanna point to staging, right? Or maybe you have pro too. Canva have out of the box, create new version. Now [00:53:00] it’s become draft of the new version, right? Which you maybe can repoint to some other place. You maybe even want to let’s say, remember I told you I’m forcing the message, right?
Maybe you don’t wanna force the message, right? Maybe you want to use different not allow, maybe PowerPoint whatever extension, right? Maybe you want to reconfigure it as well, right? And the interesting thing is using the same client secret, if you using the same endpoint, you just may be messing up with the descriptions with the UI, it doesn’t have to be changed within the code, right? So those type of things. And then you can even preview it. So right now I actually can maybe preview and you see now, I mean they have right now two [00:54:00] names I probably should have named the second one. This might be different. But if I’ll choose this one I by mistake, choose the designer, which I need to buy.
So let’s use something free and choose. And you will see right now that I don’t have this PowerPoint, right? Selected. I don’t have this message as something I have to use, right? And in this case, I’m using the same. So actually there is some error. I need to go dive. Maybe there was actually change in these secret key and et cetera, et cetera.
Sam Brace: Right, but you can test it and…
Igor Vorobeychik: Yeah, exactly. Exactly. And this is where the logs are coming into place. And there I should, or some public ID invalid name. So actually it was Cloudinary error. Probably not do doing a good job on the on these [00:55:00] naming convention. But again, this is how you are debugging the stuff actually intentionally wanted to show you.
So this is how you getting help from what are doing and perfecting your integration. And the great thing is the the Canva also makes it very easy for you to basically publish your draft. Now I have my new draft version, right? Which I can continue to edit, right? Or maybe I want to delete it, and once I’m done, I will be able to publish it and it’ll override my extension because this is a new version of v2.
So, again love what Canva did around extension love what they did around around security and even more excited about the Cloudinary, what we now, how we can help all these millions of Canva users to publish their [00:56:00] designs to deliver them across the globe in the most unified and optimized way.
Sam Brace: And to encapsulate everything. What I am really happy about of course, is that not only will people have this podcast episode to be able to reference, to understand all of the ins and outs of doing this, but you also have a fantastic blog post that’s published on Cloudinary’s main blog that highlights all of this.
It has clickable, usable links to be able to get access to a lot of this so you can remix exactly everything that you’ve gone ahead and built as anybody that’s working between these two platforms. So it’s a, you have plenty of resources available to the world to be able to make this Canva, Cloudinary connection, a real thing within their organizations.
So you’ve really empowered a lot of developers here at Igor. This is fantastic.
Igor Vorobeychik: Thank you. Excellent.
Sam Brace: So Igor, we’re gonna let you go, but have a wonderful day. This [00:57:00] is wonderful to have you here. And then me and Becky are gonna say some nice things about you. So yeah, have a wonderful one, Igor.
Igor Vorobeychik: Thank you, Sam. Thank you, Becky. Have a good day. Yeah, bye-bye. You too.
Sam Brace: Becky, what’s your key takeaways here? There’s a lot of things that we can unpackage of this project, but what are the things that are standing out to you?
Becky Peltz: I think the way that the documentation for Canva is set up, that they give you a Glitch starter.
You can take that and then just play around with all of the different, certainly Igor’s talk, generate a lot of ideas on built based on what he did and then what else you can do as far as you could maybe start bringing video in then you could bring, stuff from Cloudinary into Canva and just lots of different permutations there.
I think. It looks like a fun playground.
Sam Brace: I agree.
Becky Peltz: I would probably look into, building out some serverless functions [00:58:00] too, because as long as they all are posted at the same domain and you have that base URL, you can do that in a serverless mode as well. So lots of interesting paths that a developer might take with this.
Sam Brace: Yeah, I agree. And I think you’re touching on something that I think is really inspiring to me and it’s a move that I’ve seen Cloudinary starting to do with more quick starts, more ways to try it, exploring code. And Canva has something very like-minded where we have a lot of ours tied to Repl.it, which is a similar service with some differences of course, but similar service to what Glitch is providing.
And we have a lot of that in our documentation for people to try it out, to actually, let me quickly show our audience what I’m talking about here, but if we pop over to our documentation, you’ll see that we have quick starts, very similar to what they had here, where we can test out the node SDKs right from this area with a overall similar service to what they’re providing for this.
So people can expand and try [00:59:00] things out in a safe space. So it is where I like that Canva and Cloudinary are doing something very similar in that space, but it’s where they’re also encouraging everything that Igor did is they want more developers to create connections between this system and that system and the other system to Canva.
So if it’s inspired from a business perspective that they’ve embraced the creator and the developer within their overall product, which is very very cool to see.
Yeah. And I think a good developer experience is the one where there’s less code. So anytime they can supply you with a nice set of code that you can just put your specialty stuff on, that’s a good experience.
And they’re definitely in the right place as Cloudinary is too.
It is. And it was smart for Canva to use Node as a starter, frankly, because, think a lot of our coursework was written in Node intentionally, because it [01:00:00] is a framework, it is a way for people to be able to do things truly front end, back end because of the JavaScript connection between all of it.
So it is where it’s, if it’s a smart space for them to be in and, but it’s also to say that if someone were to try to replicate what Igor did, possibly in other SDKs, it might be possible. So version, there’s lots of connectivity there too, which is
Becky Peltz: Yeah. Just go home and talk to Chat GPT-4 and he’ll give you probably three or four ways to do it.
Sam Brace: Oh man, we like, it wouldn’t be a podcast if we didn’t mention Chat GPT in it, right? No, absolutely. But great stuff and to highlight of course, everything that we have talked about. Once again, on cloudinary.com/blog, you’ll see Igor’s post, we’ll have that of course in the show notes with all the associated links if you wanna follow along with everything that happened to be there.
So wonderful space for you to be at. And of course, before we do let our [01:01:00] audience go, we would do wanna point out that this is not the only Cloudinary podcast episode that has been out there. We have many, we have years now that we have produced of this. So you can always find every and all episodes of the podcast programs we produce.
There’s two: DevJams, as well as MX Matters, and you can see those at cloudinary.com/podcasts and that’s where you can dive into the episodes, watch and listen, and also have links to any of the associated podcast services that we happen to be subscribed to, such as Spotify, Apple Podcasts, Google Podcasts, YouTube, as well as our own training resource, the Cloudinary Academy.
And without making sure that we don’t continue the conversations, we have to continue the conversations and if someone has questions about anything we’ve covered at any program, or frankly, anything that is tickling their brain about what Cloudinary can provide, they can always go to community.cloudinary.com, where you’ll find our overall community forum and [01:02:00] it’s associated Discord server for you to continue with conversations.
So this is all good stuff now, Becky, any final thoughts about the Igor conversation?
Becky Peltz: No. It’s great to have Igor on and to be able to share some of the work that our own employees are doing. It’s, there’s a lot of creativity in the company and it’s nice to be able to pass that around.
Sam Brace: Absolutely. Absolutely. One last thing that we do wanna point out here is, this is actually somewhat of a bittersweet episode for us, because this is gonna be Becky Peltz last episode on DevJams. Becky’s moving on to some brand new adventures, which we’re really excited for her to be a part of, and it’s been amazing to have her as my co-host since we’ve launched this overall effort.
But it is to say that this will be the last time you have Becky on as our official co-host. Becky, I wanted to say thank you for the many years of helping our [01:03:00] developers, helping out the overall community to understand what is available with Cloudinary and expanding their knowledge. So thank you for being a part of this.
Becky Peltz: Hey, it’s been my pleasure and I’m happy to be here. I’ll have to check out what you’ve got going on next time.
Sam Brace: Absolutely. Absolutely. And that’s to say that we are still absolutely continuing the DevJams program. We’ll be out once again in the next few weeks with a future episode where we’re talking with another developer that is doing some amazing, innovative, inspiring things with the overall service.
So don’t worry, even though Becky won’t be with us, we’re still gonna be here. And of course, hopefully, Becky, you’re cheering for us from sidelines on this overall case too. Excellent. So on behalf of everybody here at Cloudinary, thank you for being a part of this episode and learning more about what our services can provide and we’ll see you at the next one.
Take care everybody.
2023-06-15
Front End as a Service (FEaaS) in a Composable Technology Stack
There are many different types of businesses and products that are a service. You likely have heard of Software as a Service (SaaS) or Platform as a Service (PaaS). But from the growth of composable and headless architecture, a new As-A-Service has been created – Front End as a Service (FEaaS). Since the front end is decoupled from the back end, this type of service allows developers to focus on the ways people interact with their sites and apps without constraints or blockers from the back end systems. Joining this episode are Rachael Hibbert and Pierre Martin from Front-Commerce, where they discuss this emerging FEaaS space. They will explain many details on how to use this technology to build, test, and distribute engaging front end experiences faster, better, and cost-effectively. Join the experts at Cloudinary and Front-Commerce for this engaging MX Matters episode, and learn how to construct your composable technology stack!
Sam Brace: [00:00:00] Welcome to MX Matters. This is where we talk about the trends in the overall visual economy, things that might be affecting the way that images and videos might be managed, delivered, displayed, and many times also the technology that’s behind a lot of that.
My name is Sam Brace. I am the Senior Director of Customer Education and Community at Cloudinary. And joining me for this episode and luckily for many episodes of MX Matters, is Maribel, who is our technology partner manager here at Cloudinary. Maribel, thanks for being here.
Maribel Mullins: Thanks for having me. I really appreciate it.
Sam Brace: Me and Maribel are gonna be talking about something that is tied to a lot of the concepts we’ve started to introduce in this overall MX Matters program, which is headless and decoupled architecture. And we’ve talked about it from a sense of maybe MACH, maybe we’ve talked about in terms of composable architecture.
But essentially, as we’ve said in a few of these episodes, it’s where people are taking a lot of the services that are gonna be on the [00:01:00] front end of a website or an application, and also the back end, and decoupling them. And we’re able to still be able to use a lot of great services together, thanks to the integrations and APIs that are able to be there.
But it adds a lot of flexibility for developers when they’re creating these various types of technology. And it also is introducing lots of concepts into this overall new composable front-end, back-end, decoupled technology stack. What’s ended up happening in this case though, is now we’re starting to see various companies, various services, starting to call themselves front end as a service, not just software as a service, or backend as a service.
And these are somewhat new terms, and what we wanna do is for those that are overall working in marketing, creative, e-commerce, whether you’re planning a technology stack revision or just trying to understand the technology trends, better understand what this means when we start to see companies coming out there and saying front end as a service, which [00:02:00] is fairly a new term, and then similarly backend as a service.
To bring in two experts in this overall field, we have Pierre and Rachel who work for a company called Front Commerce, and they do some amazing work for companies when they’re trying to make their front end flexible, modular, and part of their overall composable technology stack, and particularly those in the e-commerce space.
So as their name says, Front Commerce. Let’s bring them on in and get a little bit more understanding of what this means for all of those various audiences I mentioned. So Pierre, Rachel, welcome to the program.
Rachael Hibbert: Thank you for having us.
Sam Brace: Let’s just break down the term in general.
What exactly is frontend as a service?
Rachael Hibbert: So a front end as a service is where the backend and the front end of a traditional e-commerce platform have been decoupled. So they’re separated and once that happens, we can add a front end on that’s agnostic of the backend. So it’s completely independent in terms of how it [00:03:00] functions, although they are loosely connected together.
Pierre Martin: It’s also that the front end and the back end have very different life cycles.
And when you experiment, based on your user behaviors, you might be deploying and changing your front end faster than your backend. And sometimes you will need to re-platform and change services, based on your business and your IT constraint.
And then that will be the backend. So decoupling also ensure that both have their own lifecycle and also they use the best technologies for each.
Sam Brace: So why is this happening? As I mentioned, is this because of MACH architecture and composable architecture? How is this overall front end backend service, how did this trend, or how did this situation start to come about?
Is it because of that or is there other circumstances?
Rachael Hibbert: I think it’s growing because of that. It’s like a lot of different movements within this technology space, the increasing importance of user experience and the complexity of consumer demands have really led to a growing [00:04:00] demand for this kind of specialized service.
It’s important today for a brand or a retailer to be able to respond as quickly as they can to each of these factors. And if the front end is independent, it’s just a lot easier and a lot quicker to bring anything that he needs to, or she needs to, bring to the market as quickly as possible.
And then coming back to composable commerce, a composable project does need a front end. There are different solutions available. There’s the headless monolith front end. A good example is the PWA studio that Adobe have developed for the Magento stores and their Adobe stores.
And then there’s the do it yourself custom way. That’s a different route, can be very expensive, but it’s completely custom, which can suit certain retailers needs. And then we come back to front end as a service, which there are certain different ones available, Front Commerce being one of them, where the technology is outsourced, which takes a lot of pressure off for an e-commerce, but they do still stay in control in terms of brand image, the features and what they want. [00:05:00] And this kind of service really does allow for greater flexibility, which is super important today with the speed of the market, which is just going at an incredible rate.
Pierre Martin: It’s really the need to accelerate, be more agile and also due to the expectations of the users, and the way they browse online. And in commerce, the rise of mobile and maybe tomorrow, other solutions.
It really ends up being the motor, and the reason why people might go composable. And then in the end, it’s also the technology because you might not take risks with your backend solution that’s the core of your business and decoupling that to have a different front end will also help delivering faster and more often.
Maribel Mullins: Is there a good indicator to know when to switch to a front end as a service? Like I’m imagining most people may not have that now. Is there something that you do specifically, that a business should be like, you know, now’s a good time to change over and add this to our platform?
Pierre Martin: When you [00:06:00] might want to replatform your old stack, it can take a while and sometimes that could be also a first step towards these replatforming. First you remove the head of your backend, and integrate front end as a service solution with your existing backend. So all your business rules, your interactions with other services also remain.
And then you can start also removing responsibilities from this legacy backend. And ultimately later you can re-platform your whole solution. So a lot of people are starting to have a front end as a service for this reason. And it’s a first step that allows you to have a faster time to market and your users and in e-commerce conversion rates around that are starting to improve very quickly.
Another way is when you want to address new markets. There are lots of B2B platforms and [00:07:00] merchants that want to go and to have a shop for their B2B customers. Then you realize that all the information is spread across a lot of different systems. And when you develop that, it’s easier to start with a decoupled front end than it is to integrate all those data into a unified data source. So the front end has its role.
I’m also thinking about when you have a lot of different brands, or regional constraints also where in China, you may have some different constraints or the American region is more advanced with different rules.
Then if you move everything also to a front end as a service, you can handle the subtle differences in a easier way than what you may have to do if you have a monolith and everything in your existing backend.
Sam Brace: So one thing that I was wondering about when it comes to the front end as a service situation, because we’re using a lot of terms [00:08:00] that are tied to legacy and monolith, and I’d love to just unpackage that a little bit. What exactly does that mean? If we’re talking about legacy backend or monolith backend and saying that you can put a front end in front of that or you have a composable back, can you explain some of those terminologies for maybe those that aren’t completely familiar with this topic?
Pierre Martin: So a monolith is a software that does all the things. For instance, in e-commerce, it’ll handles your content management, create pages, also user authentication, managing carts, checkouts, product information also. So everything is there with the search logic. Everything is in the same system.
It has so many responsibilities. It does many things. And over time, any company has customized it and adapted it to their own business. So at some point, it could be difficult to update it and to upgrade it. And sometime it can[00:09:00] remain on old technologies, have security problems and become slower and slower. But it’s such an important part of your infrastructure and your total company, then in the end, you don’t want to touch it anymore. And that’s what we call legacy systems.
And that’s where you start decoupling that, and introducing the front end and removing the responsibility of displaying things to the user, is the first step towards removing all those responsibilities that were added over time to this system. And then for instance, you can say, I will use a search service also that does just the search part or an authentication service that will handle user management.
And in the end, you remove responsibilities from this old service and you are less dependent on it, and you can change it if needed because sometime editors stop also supporting this platform. So it’s really like [00:10:00] having just one single, very critical and important piece.
Rachael Hibbert: It’s also important to understand that how important it is to have a maintainable solution that evolves over time. And by going down this route, it’s much easier to embrace new technology. It’s much easier to look at innovating in terms of your web and user experience, and keep the pace with all the different changes that are happening in technical terms, and in the technology world by going down this route.
And it’s really the one of the best first steps to creating a fully up to date modern commerce experience.
Pierre Martin: And also to adapt to new trends, like what we’ve seen with ChatGPT and AI over the past few months is kind of crazy. And at some point, merchants or content writers, a lot of markets are going to evolve with that. And if you have already all the spaces ready and then there is an important term, which is API, meaning that [00:11:00] they have a way to expose the data and for you to reuse in other systems, then it’ll be also much more easier to take this new path of AI if you want new usages for that, or just to take an AI solution and add it into your front end at some very specific parts to improve the user experience and the people that are ready for that might have competitive advantages over their competitors.
Maribel Mullins: Can you elaborate on that? You mentioned if you’re wanting to get into the AI projects, but is there like a certain type of website that would benefit from using front end as a service?
Pierre Martin: There are many different projects that could benefit from it, mostly when you have a lot of different backends that you may want to use, because for instance, you have very specific use cases and very specific needs. Search is a good example of that. Reimplementing search and providing very accurate results to the user and personalized results [00:12:00] is a very hard task, but there are services that does that in a way better way than any solution. In that case, you might have an interest of moving to a frontend service to replace search with this service. For content management also, you may have different teams in your company and the marketing team that might prefer creating content in a very specific software that handles all of that.
For content creators that will be able to update images and really improve that part of your website. And sometimes those are not the same people. And also your expectations might be very different from services. Like if you if you want really perfect images, that works on all sizes of screen for a website, it’s very, very difficult to do that well.
So there are services that does that. And that means that any kind of websites really can benefit from it. We are in the eCommerce area, but content, also news.
Sam Brace: So if I’m [00:13:00] sitting here and I’m saying, okay, I oversee digital marketing and I wanna have the best, fastest website, I wanna make sure that when people go to it, it’s loading the content as quickly as possible, having an amazing user experience. What specific elements of front end as a service really push that in that sense?
Is it where I could do a lot of these things well with a legacy system, but it gets even better? What exactly is it that is able to push the performance elements of my website, moving to a front-end as a service solution?
Rachael Hibbert: I didn’t even know about that this kind of thing existed before I came and worked for Front Commerce a couple of years ago. And there was just so many different things that really pushed for it for me as a marketer, but not necessarily as anyone that’s really very technical minded. The fact that you can connect to nearly any CMS is absolutely incredible. You really can choose what you want and how you want it. The fact that when you want to make any [00:14:00] updates to what is being displayed, any kind of visual update, you don’t have to wait for the backend to be ready and to roll out a whole bunch of different things and updates and releases for it to be available.
It’s pretty much real-time display in terms of what we can do with the user experience and absolutely incredible the way that we can create experiences that are completely translatable across different kinds of devices is just super duper as a marketer. Adding in new channels when and as you need them is very quick and easy. It’s just amazing how quickly you can go and how you can update your experience in terms of what you wanna show and what you wanna say to your customers. The level of personalization that can go in place as well, it’s more than just a bonus. It’s just where things are going and what we want.
And it’s just so satisfying and it empowers marketing teams and digital teams and it takes a lot of the stress out of communicating with the backend teams and with all the different operational teams as well, [00:15:00] which just makes for a much easier work experience, as far as I can tell.
Pierre Martin: When you browse on the web and on the website, all the technologies are similar. In the end, it’s your browser that will ask an HTML page and that gets the information. And to do that, they do request through the internet. So no matter if you have a monolith or what programming language you’ve used, in the end, you serve html files to users.
However, browsers and mobiles, and even the web standards that allows these communications have evolved a lot over the past 10 years or even more. The way user browse online has also changed a lot because when you are on your mobile, and you are commuting and you have a poor internet connection, it’s really not the same way you browse the internet when you are with your laptop with fiber, with a high speed internet and 4K screen that displays a lot of information.
To cope with all of these [00:16:00] situations, so these different devices, the network speed, and also the fact that you always want more and more personalized content, you want to get information faster, all of that requires new technologies, and you need to evolve and cope with this fast pace of expectations and leverage the new technologies that’s available.
And to do that, usually those monolithic backends or legacy systems that we mentioned might be limited in that because this is not their core value. They manage promotions, pricing for commerce or search or things like that, but not all these new things.
So the front end became a responsibility on its own. That’s really important because it can leverage all of this and focus only on those aspects. So for instance, if you want a page to be displayed faster, of course it needs to be generated.
So the html needs to be generated as [00:17:00] fast as possible. But then also it depends if the server, so the computer that will give you this HTML is close to you, or if it’s at the opposite of the world. So there are systems that are named content delivery networks, CDNs, that allows you to have these pages as close as the user as possible.
So if you come from the US, you will have a server in your city that will provide you this information. And if I’m in Europe, I will get one in Paris, for instance. So this is also a good way to do that. But, technologies has evolved also around that. I won’t enter into too many technical details because I could speak for hours.
But again, now from these servers that are very close to the end user, you are now able also to include some personalization and change the content that you will serve to the user, depending on where he’s based. And you can do a lot of things like that. So those are examples of[00:18:00] what you can do to really deliver fast experience.
And also for images, if you have a poor internet connections, you may not want to deliver a nice, very high definition image because that will be a lot of data to transfer and user usually doesn’t want that. So there are a lot of personalization, and that’s important to really take each of this use case and handle this. And that’s the responsibility of the front end.
Maribel Mullins: And so as far as like tool sets that come with a frontend as a service, so you had mentioned personalization and CDNs, can somebody expect when they go into a front end as a service solution and that personalization capabilities are included or, maybe analytics, or APIs to work with CMSs?
Pierre Martin: For the technical part, usually you will have the front end. So either you use the front end as a service solution, or you can also create it, like there are a lot of [00:19:00] services that are just creating what we name boiler plate. So basically you take the code and then it’s your responsibility to maintain it over time. While a front end as a service solution, like Front Commerce, has regular releases with new versions, and you will update your software and benefit from the latest everything that I explained before.
So the latest technology standards and performance improvements. Then, usually you have an API orchestration layer or, in Front Commerce, we use a GraphQL as the technology, so a GraphQL gateway that basically allows you to have a unified access to all your data no matter where they are located.
And then, you might have an e-commerce platform we’ve already mentioned. And you will choose the search service that will match your needs. So with personalization, you can also have search services that are very good for internationalized content and global content.
Then you have also [00:20:00] hosting providers with CDNs.
Rachael Hibbert: So there are all kinds of different systems available.
Some of the bigger names that we hear about all the time are Contentful, Prismic, even WordPress. And they all have different features and functionalities, but what is general with each of them is that it’s possible to create dynamic rich content that, as I said before, is displayable across all different devices in real time.
And being able to do this really brings a different level of communication with one’s user. It’s possible to create experiences that touch them on an emotional level that are completely personalized. It’s definitely incredible today how much easier it is to have what you want, when you want it, even in terms of an e-commerce platform and how we talk to our customers and how we communicate with people. And it’s just, I don’t know. I just think it’s great.
Sam Brace: So I think the thing that I keep hearing and I’m trying to put like various hats on as I’m hearing these conversations take place, is that because this is new, front end as a service is something that at least I hadn’t heard [00:21:00] about in the past, let’s say two years. It’s relatively new as a concept for probably a lot of people that are diving in and we’re introducing a lot of new different types of services that are coming in, as a service concepts.
What are the reasons that this is starting to take hold? Like are we seeing market maturity coming in? Is there certain moments where people are saying, I wanna go headless, but I’m missing this component. What’s the thing that should be standing on in somebody’s mind saying, oh, I need front end service?
What’s that moment that you feel like a lot of people, maybe they work with Front Commerce, maybe you’ve had conversations with them in other places, but what’s that like normally that aha moment that says, I need this thing?
Pierre Martin: One of the first that we often heard is when people have started to go headless and to consume data from APIs of different services. Usually they try with a do it yourself approach. So they take boiler plate, for instance, headless [00:22:00] service have these examples or starter kits, and they start to create their whole user experience and the front end for that.
But then technology evolves. Developers might have left the companies and 10 new versions of the framework that we’re using have been released, and they never managed to catch that because it’s very easy to underestimate how much work this is to maintain that over time with the latest standards and technologies.
We see a lot of people that come to a front end as a service solution from this first bad experience and the fact that we are here to guarantee a migration path, and the fact that if you start your project today and that in five years, there is a totally different way to shop online. I’ve mentioned AI or we don’t know how people will browse and buy online in the next few years. But with the frontend as a service, we can [00:23:00] guarantee that we will release new versions that will allow them to go that path without investing in rewriting everything every two years.
Rachael Hibbert: You have to take into consideration today that even though we are looking at business benefits of this kind of service, the technical benefits are equal to a business benefit in the end because that’s just how everything works now. And backward compatibility, what you were talking about, is also really important because not everyone, not every service is able to offer that, reinvesting every couple of years in terms of budget and in terms of time in redoing your entire storefront is a huge undertaking. And being able to avoid that is a blessing really.
Maribel Mullins: So, you mentioned being able to replatform and that in itself can be a big investment. From your experience, how long does it typically take to decouple and then what other challenges an organization or developers may encounter by doing the decoupling?
Rachael Hibbert: I know at Front Commerce, the whole decoupling, going [00:24:00] headless, putting on the new front end, can take around 12 weeks, but I don’t think it’s any quicker than that.
Pierre Martin: Yeah, it really depends. Theoretically you start your project and you have a front end that works, but then it really depends on the level of customization that you want.
Sam Brace: Then I wanna make sure I understand. So let’s say that I have a monolith backend, something where it’s large. I’ve been in this system for years, and we know that sometimes things take a long time to replace that monolith backend. It seems like from what you’re saying, because I’ve separated front end from backend, I could essentially move very quickly with updating the front end, but still keep the legacy backend.
I can do things iteratively, essentially.
Pierre Martin: Exactly. And when you’ve done that, you can re-work your brand or the user experience, at least in the commerce ecosystem, it’s very important because you can have better results and more satisfied customers way faster because all those [00:25:00] backend, monolith things are mostly for your own stakeholders internally. But, when you are selling online, it’s always good to have more satisfied customers and increase your revenue also. So, yeah, this is a first step and then you really have the freedom to decide when you will continue the project of changing your backend and also maybe sometime evaluate new solutions while you are working on your front end. You can also start reevaluating business rules, have workshops, prototype a few things. And I think this is a good way to go because we often underestimate the amount of customization that went into a system.
And that’s when you start digging into the features, into the specific things that you realize all those things that were added in the software over the past 10 years or 15 years.
Sam Brace: To me, that seems like the right way to prioritize it. A lot of times when we’re talking about headless architecture, it can seem like this is a big [00:26:00] change.
And what I like about what you’re prescribing here is if I need to do this, it’s kind of like how do you eat an elephant? You do it one bite at a time. And so the way that you do this is like, okay, don’t try to tackle the whole thing. Focus on the front end first, because that’s the thing that’s impacting your users, your buyers, the people that are experiencing the overall application or the website.
And then as you’re saying, evaluate the backend. So I think it makes a ton of sense to do it iteratively. But it also seems in terms of prioritization, I would say I need to focus on the front end first and then focus on the back end because of that effort.
Does that seem correct to you where focus on front end and then go back end, rather than do it the other way around?
Pierre Martin: To me, it really depends. Again, as sometimes you may have like huge constraints on your backend and may want to change that, like, you have a lot of contents and it needs to be updated. You want to change the way you communicate with your customers. So here, the front end [00:27:00] might be okay to keep it and change the way you generate content, and you do search engine optimizations or things like that. But yeah, usually at least in Front Commerce, we really want to target merchants that are user-centric. Usually you first think about your users, your customers, the way they browse online and on your website, and how you interact with that.
And starting with the front end really go with that way of thinking and of managing priorities and projects.
Sam Brace: One thing I also wanted to ask you about is, we’ve talked about content delivery networks in different places in this conversation. We talked about CDNs, and to me, it sounds like when you’re thinking about content delivery networks, you’re asking for it to display everything that’s through the front end, through a CDN as part of this front end of a service solution.
Does that also apply to the images and videos that are coming through? Is that should also be coming from CDNs? Is that also where there’s maybe other elements to be [00:28:00] thinking about there, but talking about what we’re talking about, page delivery, e-commerce, is that what elements need to be coming through the CDNs?
What things should we be people thinking about when they talk about front end as a service and then, that part of that tech stack?
Pierre Martin: Yeah. Everything is a good candidate to go there.
And it’s even more important and easier to do if this content doesn’t change very often because if you have a product page and the stock is always changing or you change your price very often, sometimes it could be contrary to have that always in a CDN.
But for images, of course, because this is like on a website, images and videos, those are the biggest things that you will have to download when you browse the website. So this is the most important things that needs to be optimized on your website. So of course if it’s closer to you, then you will download it faster and also different solutions also have features towards delivering the best image or [00:29:00] video possible to the user. Again, when you browse from a tablet or a phone in landscape mode or from a big laptop, from a tv, from your car, you will have a different screen size, and screen density.
So the file you will download must be different depending on the size of your window. And also as I mentioned, if you are in the train with your nice laptop with a high, density screen, but you don’t have a good network quality, then it’s also better for you to deliver an image that is smaller in terms of size so you can view it faster.
So all of these services and delivery solutions for media are really important if you have a website with a lot of illustrations and images and videos.
Sam Brace: So let’s say that I am thinking about this now. I’m like, okay, great. There’s something here about front end as a service. I feel like I might need this for my company. How do you go [00:30:00] about getting buy-in internally for something like this?
Like, let’s say that I’m the person that’s gonna be making decisions about this, or maybe I’m helping influence the decisions that are going to be taking place at a company. What are the things that we need to be able to tell within the organization that helps people understand the need?
Pierre Martin: First, ensure that everyone in the company knows where the data comes. Like what are the systems? And ensure also, of course, that they have APIs, but if the front-end service solution supports it, most of the time it does.
And then you can start prototyping things. We do have several customers that try quickly to see what works out of the box and what will be customized.
And then you can also analyze how long it takes in your current solution to deliver new features, to iterate on the user experience and to change something on pages to [00:31:00] improve the user experience.
Most of the time it’ll already have been pain points internally, and this is a known issue and trying to highlight that to the stakeholders and discussing like the flexibility that you are missing and that might improve also your conversion rates can be also a good indicator of that.
We see a lot of people that detected over the past few years that most of their traffic has totally switched from desktop users, users on a desktop to mobile. And their website was maybe good on desktop, but on mobile it was terrible.
And they started to see their dissatisfied users and decided that they needed to improve this use case of browsing their website on mobile. So it could also be a good way to say, okay, look at our website on a mobile or on a slow collection, and you will see all those issues.
Rachael Hibbert: Yeah. So basically just an overall across the board good knowledge [00:32:00] of what business goals are and how the technology can improve those business goals, especially things like organic traffic, mobile browsing, as Pierre said, conversion rates. I mean, we have customers that have doubled their mobile conversion rate almost immediately after implementing front end as a service.
You really have to know what you want and go through all the different issues that you have within the business and work out how to resolve them. And quite often a lot of different issues can be resolved just with this update.
Like, well, it’s not an update, it’s more than an update, but, you know, just changing things around in the platform and bringing in new technologies that respond to what the consumer is looking for, which then responds to the business objectives in the next few years.
Maribel Mullins: And are there any other trends that you’re seeing for a front end as a service that you can let us know or give us some insight on?
Pierre Martin: There are lots of trends all the time in this space. It really evolves a lot, to be honest. Right now we are also seeing a [00:33:00] lot of work about personalization and really adapting a lot of things on a page and depending on many factors.
So, in the front end, that means a lot of technologies to be able to change that, and enables also a lot of new ways of displaying the content to the users.
I really think also that in terms of user experience and the way you provide information to someone that comes on your website, we are going to see a lot of changes and that will need to adapt your front end also and the way you display the information, where you get it.
I’ve mentioned AI as an example. For years people have said that, it’s important to have nice UI that works on mobile, and then there is ChatGPT with only a chat box that comes here. You just ask things and it seems to return information that makes sense without you [00:34:00] having to click around and change that.
And we see a lot of softwares that starts to integrate this way of being able to understand what the users want to do. And you can put that just in a small part of your existing website on your front end and benefit from a lot of other things. Or say that for instance, all the personalization of the product that are displayed or the content that’s displayed can change based on many different criteria that you will mention. And that could also be data mined by an AI for instance.
I really think that there will be a lot of interesting use cases towards for the front end space. But yeah, it’s moving very fast.
Sam Brace: And I think it’s a great way to look at it because as we said, this is a trend that’s emerging and I think there’s always gonna be new trends that are gonna continue to move technology forward, especially with this. And it’s not like people are gonna stop purchasing and doing things on the internet to be able to help with their own lives, being able to supplement it by [00:35:00] being able to find the best products, the best services. So it’s where it’s great that we’re able to address the trends that are tied to this. And Pierre, Rachel, this is great to see the work that you’re doing and helping our audience better understand front end as a service in general.
So this is great work. Thank you.
Pierre Martin: Thank you.
Rachael Hibbert: Thank you. It’s been wonderful talking.
Sam Brace: And Maribel, it is wonderful always to have you for this program. The insights you have working with all of our various technology partners here at Cloudinary, it’s fascinating. So thank you for being part of this conversation as well.
Maribel Mullins: Thank you.
Sam Brace: Absolutely. And of course, if you’ve enjoyed this conversation, make sure that on whatever service you happen to be listening this on, whether it’s Apple Podcasts or Spotify, all the different places we happen to be on, make sure you’re giving it a Like and Subscribe, so that way you know what is coming when it comes to the trends that are affecting the visual economy for future episodes of MX Matters.
On behalf of everybody at Cloudinary and the MX Matters team, thank you and we hope to find you at a future episode.
2023-06-08
Image Loading Enhancements with Cloudinary, Tailwind and Base64 Encoding
Kent Dodds is one of the foremost experts on JavaScript, authoring helpful blog posts and courses on the widely used programming language. He recently shared some techniques to improve his own blog’s image loading experience, which happens to use Cloudinary for several aspects of it. Becky and Sam from Cloudinary’s Customer Education team talked with Kent, walking through the processes he took to get a 100/100 on the “Cumulative Layout Shift” Core Web Vitals score for his blog. This conversation includes reviewing code scripts to understand his use of Tailwind’s aspect-ratio plugin, Cloudinary’s ability to load perfectly sized images and to handle Base64 encoding, and other important topics.
Sam Brace: [00:00:00] Hey everybody. My name is Sam Brace, and I am the Senior Director of Customer Education and Cloud community here at Cloudinary, and you are about to watch and listen to the latest episode of Dev Jams.
I gotta tell you, I’m really excited for this episode because in terms of JavaScript development, we have one of the, my opinion, the foremost experts in JavaScript development. Joining us as the guest for this episode, Kent Dodds, and if you’ve ever gone to Epic react.dev, if you’ve ever just seen overall talks in the space, if you’re even touched some platforms like Remix, you’ve been experiencing things that Kent Dodds has done and.
What’s very exciting is that Kent has an amazing blog and associated community that’s tied to his overall brand. But what’s [00:01:00] great about this is that he has gone through and developed some really great ways to handle what we call cumulative layout shift. And that’s done through low quality image placeholders, making sure that people have content that’s loading quickly and efficiently, but also doing it in a way where they can make sure that they know content’s even gonna be appearing on the page.
So those are all topics we’re gonna be talking about here today in this overall Dev Jams episode. Now, of course, with every Dev Jams episode, my co-host Becky Peltz, who handles overall curriculum management and program development for our developers that use Cloudinary. She’s joining me for this episode, just as we said on every single one of these.
Becky, it is wonderful to have you here for this conversation.
Becky Peltz: Hey, I’m happy to be here. I we’ll be learning a lot here. There’s a blog that we’ve all read that is, just wonderful at blending inspiration to solution. You [00:02:00] read through it and it just flows out this great idea and then how to solve it.
And then we get to see how he uses Cloudinary to to as a big tool in getting that solution.
Sam Brace: One thing that I love about it, and you articulated it well, is that the one thing that’s nice about having a guest like Kent on here, because as we said, he’s an expert in this overall space, is that he also is very good at being able to show the step by steps, the understanding, sometimes historical background information you may need to know, which I know we appreciate as educators, but it really does help to have a holistic view of why you might wanna be doing something or what this person experienced with the overall project.
Becky Peltz: Yeah. I know he’s an educator and I think that, programmers, we’re good at breaking down steps for machines, but I think when you get into educators, you get people that can break it down for people and it’s so much appreciated.
Sam Brace: Completely agree. So before we bring Kent on to be able to talk about all the great work that he’s doing [00:03:00] with his blog presence, and of course because me and Becky work for Cloudinary, there’s gonna be some Cloudinary things that we’re gonna talk about in this overall space.
But we do wanna make sure that you guys know that if you are the first time listener, first time watcher of this overall content, you can always go to Cloudinary dot com slash podcasts. And that’s where all of our podcasts for the two programs that are managed by the company. Are going to be. So if you ever have questions about what past episodes, what topics have we gone and covered, they’re all going to be in that overall space.
And of course you may decide to listen to or watch some of the programs on certain services like YouTube or Apple Podcasts or Google Podcasts or Spotify. We happen to be in all those different places. So if this is your first time here, welcome and of course we are very happy to have you here. And we wanna make sure that you know where you can be catching all of these episodes down the road because this won’t be the last conversation we have.
But it may be definitely [00:04:00] one of the best, cuz as I said, we are so excited to have Kent here today. Let’s bring Kent on and let’s get into the start of our conversation. So Kent, welcome to the program.
Kent Dodds: Thank you so much. And you’re right. Those were very nice words like you said at the start. Thank you.
I appreciate it.
Sam Brace: And also very true, very true. People that are not completely familiar with all the great things that you’ve done, all of the work that you did to get to the spot, give us a little bit of historical data. Who’s Kent and why
Kent Dodds: are you here? Yeah, so I live in Utah with my wife and four kids, and it’s a very snowy day out today.
It’s been a very fun winter if you enjoy snowboarding. And yeah. So I have been an educator since, like even before I graduated. I’ve been teaching people the stuff that I know, whatever it is. And I worked as a full-time engineer for [00:05:00] a number of companies, probably the one most people recognize is PayPal.
And then I decided to go full-time teacher because I was I just enjoyed that more and I can’t do it all. Went full-time teacher. That’s right around the time I built testing JavaScript and then I built Epic React. And then I actually built my website and lots of the stuff that we’re gonna be talking about today.
And then I, now I’m working on Epic web.dev which is everything that I know about the web. And this topic will certainly be included in that. And yeah I also did spend about 10 months working on remix, the sign behind me and the framework that I use to build my website as well.
Yeah I do plenty of stuff in the open source space and I blog a lot. So that’s me. [00:06:00]
Sam Brace: Kent, is that it? I mean that
Becky Peltz: Is that all?
Sam Brace: That amazingly historical data that you have there, and it shows the overall space that you’re in. It’s where being an educator, but also understanding a lot about how the web works, a lot of things that we’re talking about, of course, you’re tied to the React community, the JavaScript community. So it’s where you’re touching a lot of different places, but it’s where to say that you’ve, you have some experience working in this other area, so what you’re telling people to do or not to do there’s some credence to that.
Kent Dodds: Yeah I would say so. People follow my advice and then they thank me later. And then I don’t know if people follow my advice and it doesn’t work out. They just haven’t mentioned anything. But I do have experience in this space shipping apps to millions of users. And I’ve been developing for the web for almost a decade now.
So it’s yeah I’ve got some stuff to say. [00:07:00]
Sam Brace: When I’m seeing comments popping up from, people are saying like, he’s also the author of React Testing and off and a thousand NPM packages.
Becky Peltz: You’re being modest, in other words.
Sam Brace: Regardless of how people feel or not feel about this, it is to say that I’m very happy that you’re here today.
And what I’d love to be able to understand, so now that we can see this, you have your blog, you have your website, so that’s kentcdodds.com. What took you to the space that you started to say yourself. I wanna start working on some of the things that we’re gonna be talking about today as I mentioned earlier, cumulative layout shift, low quality image placeholders.
Why did you start to see the need for some of these things that we’re gonna be talking about?
Kent Dodds: Yeah, that’s a great question. My original website at kentcdodds.com, if you go to the web archive and look back in like 2015, the website was basically a white screen with text that says, I’m too busy to build my [00:08:00] website.
Here’s some links to my Twitter and whatever. And then at some point I decided, I would like to have a better online presence. And so I wrote my site in Gatsby and statically generated it. And that’s when I started writing being really active on my blog. And one of the cool things that I got out of Gatsby was it’s built in support for image processing.
So it was able to take my image, turned it into an SVG. And so when you landed on the page, you would see an SVG as a placeholder, and then the image would load in and it looked awesome. There were a number of problems with that not at least being that processing took a lot of time.
And so deploying my site, even like fixing a typo, would take 20 minutes. It was the worst. I hated that. And so you could add a bunch of caching and stuff, but yeah, that was not fun. And so when I for that and various other reasons, I decided to [00:09:00] rebuild my website. And it was this really big effort that I did.
Was that last year or maybe the year before? And yeah, in the process, I didn’t want to lose that really nice loading experience cuz my website has images everywhere. But like the biggest, of course, is my blog. Every blog post has a header image, and I wanted that loading experience to be as good as possible just because when I decided I wanted to make a professional website, part of the reason was because I wanted to illustrate that I really knew what I was talking about.
Especially when I am saying, “Hey, come learn how to build awesome websites with me”. If my personal website’s no good, then okay, you’re gonna teach me how to make like a website like yours, that’s garbage. I don’t want that. So my personal website needs to be very good. And so avoiding poor user experiences I’ve had cumulative layout shift.[00:10:00]
And that basically that, if you go to a website and you think see things popping in that’s bad cumulative layout shift. You basically want it to poof, there it is, and nothing moves, other than things that may be animated. Nothing moves. Yeah. That’s like in animations are a fun subject that we could talk about later.
But the idea is you don’t want things popping in place. And images are one of the biggest culprits of bad cumulative layout shift as well as banners that pop up that those are the worst. And yeah, so that, that sort of thing. Or ads, of course, like I, I don’t do any ads, but pretty much anything that you do that happens only on the client can cause cumulative layout shift. And the fact is that we’re not server rendering images. We’re server rendering an image tag that tells the browser how to load the image. So you can technically server render an image if you use Base 64, and we can talk about that. I [00:11:00] actually do that.
But for performance reasons, you typically don’t want to server-render your image like that. There are special considerations that you need to take into account when you’re talking about an image heavy site like mine.
Becky Peltz: Yeah. You definitely don’t wanna see big chunks of things moving around and at the same time, there’s a lot of options for those chunks. And I think, you have to pick a really good option. For, we’ll see how you figured it out. But just popping up a bunch of little tiny thumbnails isn’t really gonna be a solution because that’s gonna be just distracting.
Yeah, the user is looking for a continuous experience. It’s okay if it’s, if it changes, but it has to kind of transition. It can’t be like “boom” kind of effect. And I think as people who write frontend code [00:12:00] are really dependent on the device or the browser that they’re working with, they really have to like, understand it and work with what it can do.
And I think probably why Google is the one that is telling us about cumulative layout shift and how you’re gonna maybe lose your SEO ranking if you don’t, get it working.
Sam Brace: Now we’ve talked about cumulative layout shift, but I also know that’s an area that Google has started to look at when they came up with the concept of Core Web Vitals. That’s something that I started at least hearing about a lot back in 2021, I feel was the first time when someone said Core Web Vitals or Web Core Vitals or whatever they wanna, mix, match.
But something called me about this. Was that also part of the reasoning for it? It was tied to Core Web Vitals and the scores that are associated with that?
Kent Dodds: So I actually do have metrics for my Core Web Vitals, and they’re actually even public. You can find it on, if you [00:13:00] scroll down to the bottom of my website, there’s a transparency link.
I think it’s, do I call it transparency? I, it might be mission or something. Yeah, “My Mission”, if you go to that that’s my transparency page. And on there’s a link to both my analytics as well as my metrics for my site. So anybody who wants to explore that a little bit. So I do keep track of the Core Web Vitals, but I never look at it.
For me, especially since I’m not actually selling anything on my website, I’m selling myself. And the investment that you’re offering me is your time. That’s really it. And also I suppose your email address. Of course I link to to courses and stuff like that, and I do sell those, but not on my personal website.
So the reason why my personal website needs to be a good experience is just like I said to illustrate that I do know what I’m talking about. I know how to make really awesome [00:14:00] experiences for the web and also because it’s it’s like a game of code golf. Like you just, it’s fun.
How good can I make this experience? And for businesses where you are selling something on the site, it can make a drastic impact on your bottom line based on how quickly your application loads and how confident users are that your application is doing what it should be. That it’s capable of doing whatever it is that you’re selling.
So if users land on your site and things are bouncing around a lot, it really reduces their confidence in your ability to provide whatever it is that you’re intending to provide.
Becky Peltz: Yeah, a website is a reflection of your product. If you’re doing a lot of crazy weird stuff on your website, maybe the product is a little funky too, just leave it alone.
Kent Dodds: Yeah. I sometimes will pick [00:15:00] restaurants based on how good their website is.
Sam Brace: Yeah. I actually have done the exact same thing, Kent, where I’m like, oh, that probably is a reflective of the overall service that I’m gonna be getting.
Kent Dodds: And maybe it’s not like it, it might be, it might not be, but it doesn’t actually matter cuz what matters is, did you go?
And so yeah, it does impact the customer’s impression of you.
Sam Brace: Absolutely. And when, and I think what’s also important, like whenever I thought about the Core Web Vitals as well, is that they’re normally done because Google is looking at it from a sense of trying to make the best user experience.
It’s not based upon trying to hit some score that’s arbitrary and doesn’t have significant value to it. They’re looking at to make sure that when we’re saying this has XYZ score to it, or 123 score to it, it’s indicating some factor of quality as overall associated. So I think that’s what [00:16:00] you’ve ultimately done with this overall experience to be able to provide these low quality image placeholders, be able to do the work to make sure the layout shifts aren’t constantly shifting.
To say that you did, to increase the quality. And I think that’s one thing that people should look at from an episode like this, is that if you’re trying to increase the quality of their overall web presence, a lot of the practices you did here who are directly applicable to things they could possibly do for their content as well.
Becky Peltz: Yeah. Yeah. They’re unleashing tons of crawlers on the web and these things need to act fast. And if those crawlers are waiting for images to load before they can figure out what the content is, that’s gonna be a problem for them, too. It works both ways. It’s like machines are sensitive to it as humans.
Sam Brace: So what I wanna jump into, so I’m, what I’m showing here is the blog post that kind of inspired this overall conversation. So if people are [00:17:00] saying, I wanna follow along, you just have to go to the kentcdodds.com and make sure that you’re looking for the “building an awesome image loading experience” post that you put out in late 2021.
But you can see here this video that you created is articulating exactly what you ultimately have as the result of this effort, where it’s making sure that the image has a place, it’s showing a low quality, blurred version of it, and then the full image will eventually come in, and that’s what we’re calling the low quality image placeholder.
Am I correct about that overall summary? Yeah.
Kent Dodds: That’s the basic idea.
Sam Brace: Okay. So looking at this overall situation here, I think the first section that we can see that you’re touching upon is the overall layout shift. As we mentioned, we don’t want it where you have text and it’s jumping to be able to bring in the overall space for the image.
We want it where you have the layouts make, it’s almost static. It’s where things should [00:18:00] be in certain places at certain times. It looks like you were able to do that with Tailwind. Talk to me about this overall plugin that you had here that was helping with the layout shift.
Kent Dodds: Yeah, sure.
The principle is aspect ratio. So you don’t know necessarily how big the image is going to be a lot of the time. But you might know the aspect ratio of the image. So because the, you might say, I want the width to be 90% of the viewport. The viewport could be any number of pixels. But you know the aspect ratio of the width and the height.
And Tailwind actually now supports aspect ratio as a built-in feature of Tailwind. So you don’t have to include a plug-in anymore. But the idea is just using that class name and it’s, I should also say that aspect ratio is a built-in feature of the browser that Tailwind is just using.
But yeah, [00:19:00] so that aspect ratio just will say, “Hey, I know that the image isn’t here yet, but when it is, this is how much space it’s going to take up” relative to how wide it is or whatever. And so then the browser can say, “okay, I’ll just leave that much space for that image”.
And so when the image shows up, it just pops in place and doesn’t have to move anything. So that’s actually a really, even if you’re not doing the nice placeholder or anything like that, that by itself is really useful. It can be kinda tricky if you don’t know what the aspect ratio is going to be.
So if you’re thinking about Instagram and you got pictures that are all sorts of different, you’ve got this grid and there are pictures coming in all over the place that can be tricky. The solution to that really is to just store the aspect ratio as part of the data for the for the images that you’re displaying so that when you server render or when you end up starting to render those images, you can include that because it, there’s really no other way to solve [00:20:00] this particular problem.
That’s precisely what aspect ratio CSS property was created for. And it is definitely better than having pictures pop in place cause even if we’re talking about that sort of grid of photos, you’re gonna have one pop in and then one above it pop in. And so that shifts this one down and they’re, they’ll just be going all over the place.
It just does not feel good. So aspect ratio is the solution to content layout shift for images.
Becky Peltz: And I noticed you linked to the article on setting height and with on images is important. Again, because for a while people went away from that. There was, initially height equals blah, what width equals blah.
And then the browser could figure out the aspect ratio that you were going for. But people stopped doing that. And a lot of it probably because we went from, just a desktop to a mobile and it didn’t really make sense in that respect, but this is a really good point here.
Sam Brace: What it also seems like it’s directly tied to the [00:21:00] next point that you raised here when you’re working on responsive images. Because aspect ratio, of course, is based upon the actual ratio. It has nothing to do with pixel width or pixel height. So when we’re saying we want it to be, let’s say, a three by two aspect ratio that we’re gonna be able to allocate the space for, that’s gonna be three by two for tablet, for desktop, for mobile, or maybe you need it to change, but it’s indicating what it should be based on these different areas.
So I think it’s leading us into the conversation about what you’ve done here with making sure that everything you are doing when it comes to this effort also is tied to responsive design as well.
Kent Dodds: Yeah. So if I’m on a desktop with a huge 5K monitor with this ridiculous resolution, then I can load an image that’s, really high quality and, pixel perfect.
And that’s awesome. The problem is that’s just a ton of pixels, and that’s a [00:22:00] lot, a very big image. And then if I shrink that down to something that I can see on a device and I’m using the exact same image either way. Then I am, basically what the device is doing is throwing away a bunch of pixels that it doesn’t need. It can’t display that many pixels on the device. Anyway, so it’ll look really nice and crisp, but there’s a lot of wasted download there. And the web platform comes in clutch for us again with the sizes and source set attributes on the image tag.
This was something new for me when I was working on my site. I’d never used these properties before. But the basic idea is these are configuration options that say so we’ll start with sizes. It’s a comma separated list of basically you could think of it as a tuple. So you’ve got an array of first the media query that should match and [00:23:00] then the width of the image at that media query.
And I can say for small sizes, then this is how wide the image should be, for bigger sizes, this is how wide and so on. And so I’m going actually in the blog post here, I’m going the opposite direction. Big size, this is how big or how wide the image is gonna be and so forth. I only know that because I know that the CSS that I’ve applied and so I added this later on and I just pulled up my site locally and looked at how wide the image was at different breakpoints, and then just said, here’s the size of the the image or the width that it’s gonna be here.
So then the source set says, here is the URL for when the screen is at this size. So if the screen is this big, then this is the URL to get that sized image. That allows you to really fine tune which image [00:24:00] is loaded for a given screen size which avoids the wasted bytes and ultimately results in a much faster loading experience.
Becky Peltz: Yeah. And with your sizes, because they’re always concerned, really they’re really focusing on width rather than height. You’re gonna see that the size that gets assigned is really based on the width. So you, you have a width of 50, then you’re gonna get 50 and width 30, 30. So feeling that.
Kent Dodds: Okay. Yeah I’m not sure if there’s a way to switch it so that it goes by the height, because if you wanted a horizontally scrolled thing or something, I don’t know, people come up with funny things. I don’t know what the world of VR says about all of this stuff is very width centric or, the way that we build most websites.
But yeah, this works out well for 99% of people.
Becky Peltz: Yeah. Yeah. No, totally.
Sam Brace: So in looking at this, so now scrolling down to the post, you can [00:25:00] see that now that we’ve understand like source and source set that we covered at this point, we can see how this is being done for a blog post like yours, where we’re looking at the overall URLs that are coming from here.
And of course now I’m starting to see Cloudinary and for his first case. So talk to me about what’s ultimately happening in this situation, because I can see that you’re declaring the whiffs as we’ve talked about, but then you’re also doing certain other things that are tied to this overall place that looks to be at least longer in URL compared to what you have for the initial example.
So talk to me about that.
Kent Dodds: Yeah, sure. My Cloudinary URLs, this is one of the things that I just love about Cloudinary, is the capability to transform the images on demand. And what’s cool about this is because I have q_auto and f_auto, this will not only give me well, and then of [00:26:00] course I have that w_ that specifies the width of the image that I want.
But this gives me not only the right size of image, but even the right quality and format based on whatever browser is requesting this image. Which is just awesome because we have a bunch of different formats whether it be a GIF or a PNG or a JPEG or a WebP or AVIF, all sorts of formats that various browsers support.
And it’s impossible for me to know at development time what browser is going to be requesting this, cause it’s literally all of them. And having Cloudinary be able to dynamically serve the proper image at request time is awesome. And it should be noted also that we do still have the regular source, attribute and that I just sent to like the middle between all of these sizes.
So if your browser doesn’t support the source set and sizes [00:27:00] attributes, then sorry, you’re just gonna get like a middle of the road thing here which is probably your experience on the entire web. If your browser is that old, it’s gonna be a pretty poor experience anyway. But but yeah, so I have a bunch of different sizes based off of what made sense for wherever I’m rendering this image.
This one in particular is the header image that I have on my blog.
Sam Brace: And then looking at this so I can see here you have very clear widths that you’ve declared when it comes to this, and as you said, like your source in here is in between the range that you have between 280 and 3,100.
But how are you getting those sizes? Is that just saying double the next one and then going it up? Or is there tools or utilities that you’re using?
Kent Dodds: Yeah, I wish there were tools and utilities and there. There may be now. But when I was writing this I didn’t know of anything, so I literally just pulled up my site, opened up the dev.
And then just [00:28:00] resized it every now and then, and just said that, that looks like a pretty good size. And then I grabbed what that size was and I have the next block of code here is the get image props that accepts what I call an image builder. It’s just a special little function that allows me to generate these URLs, cuz who’s gonna write that URL by hand, not me.
And then I can specify the widths that I care about for this particular image and the sizes, as well as any additional transformations I wanna make. And with that I can very easily just say, here are the different widths that I want to be concerned about for this particular image.
And these are the sizes when those widths matter. And yeah that ends up working out. If you scroll down a little bit further, you can see an example of using that utility. It ends up [00:29:00] being a relatively simple way to to manage this. Though there are some tools that I mentioned at the bottom of the blog post that can make this process even easier.
I’m not sure exactly how they accomplish that, because I feel like every image experience is gonna be actually a little bit different. But yeah, this is what I came up with and it’s been running on my site for quite a while now, and it works great.
Becky Peltz: Yeah, and it’s nice that you’ve codified it because if you decide you wanna change those widths, you just change a few numbers here in your code and you can spin up a whole other set of responsive images.
Kent Dodds: Yeah, mhmm.
Marker
Sam Brace: Now, one thing that, I saw a comment just come through here and saying “this approach would work potentially amazing for videos too”. Based on your experience, do you feel like that’s correct, or do you feel like there’s any caveats to that statement?
Kent Dodds: Yeah, I actually I’m guessing I haven’t looked in this, but I’m guessing that videos also [00:30:00] have a source set.
And sizes props. I can’t imagine why they wouldn’t. And Cloudinary also has support for on demand video as well. So I can’t imagine why you wouldn’t use this for that. I don’t have a lot of use cases for video on my site. Normally I just embed a YouTube or something like that.
Cuz yeah, I just don’t do it enough. But yeah, it sounds like that would be a pretty good solution for that as well.
Sam Brace: Excellent. And yeah and shout out to the community for being able to address things like this as we’re be going through this overall process too. So it seems like some of this was inspired, I know you mentioned Gatsby earlier, but also this was inspired by what Unsplash has been doing with your placeholder process. Talk to me about this and maybe what did you extrapolate from what Unsplash is doing to be able to keep going down this process with your own blog?
Kent Dodds: Yeah, sure. Unsplash [00:31:00] is like probably the pinnacle of image display on the web.
Like they, they do just a silly amount of work on displaying images. And so when I moved away from using Gatsby and I still wanted to have this nice load loading experience I tried to figure out, okay, so how do I have a nice placeholder that I used to have with Gasby and I thought about the SVG thing.
But SVGs sometimes look really funny. They do not. I mean they’re very small and that’s quite nice. And they, server render fine which is also nice, but yeah, the images can sometimes or the placeholder can sometimes look very odd. And so I I’ve seen Unsplash and Medium and others will have this placeholder that’s just like a blurred version of the image. And what I discovered as I was reverse [00:32:00] engineering what they were doing, I would look at what was server rendered, and it turns out they server render the primary color of the image. So they do some pre-processing of the image, determine what the primary color is. And then they also and that’s what ends up being so server-rendered.
Then another thing that they do, they pre-process the image to create what’s called a blur hash. And this is actually, it’s an open source thing. You can go grab it yourself with the blur hash is like 30 characters max of just random, seemingly random characters that somehow, it just is magic to me.
But they somehow represent a blurred version of the image. It’s like total magic. I don’t understand how this works.
Becky Peltz: Base64, a Base64 version of a blurry image that they can move in quickly, but it has to be a small string .
Kent Dodds: Yeah. It’s actually, it’s not even a base 64, because they’re using characters that are not [00:33:00] base 64 characters.
Some cool algorithm that somebody figured out. And what they do though is they feed this into a canvas and then the canvas can draw out the image based on that that blur hash. So what’s interesting though, or unfortunate is that canvas doesn’t server render. There are probably people doing some mad scientist stuff to make canvas sort of server render in some ways.
But yeah, that, that’s just not a thing. There’s no server rendering of canvas. And so that’s why they have their three-step process of first server render the primary color, and then show the blurred version with blur hash and then the final image loads. Now, this is actually not a big problem for oh, and the other thing is the blur hash library is not small.
It’s not huge, but it’s not small either. So that’s another thing to consider when we’re talking about making things fast and load as little [00:34:00] JavaScript as possible and all that. This isn’t a big problem for Unsplash because lots of the time, people will show up to the site and then they’ll click on images.
And if they’ve already got everything loaded, then we’re not server rendering those images anymore. Now we’re rendering them on the client side. So you actually will not see the full primary color displayed like we see here when you’re on Unsplash, because you typically are, you go to unsplash.com and then you click on an image and you, they already have the blur hash right there, so they don’t have to server or render the the primary color.
So for me though, lots of times people just land on my blog post. In fact, most of the time they do. So I didn’t want to have this three step process where we’re displaying the primary color first, cuz it just, it felt wasteful and a lot of the time the people wouldn’t even see the blurred version anyway, cuz Cloudinary’s CDN is very fast and so we’re gonna get the image anyway.
And so having that three steps just didn’t make any sense [00:35:00] to me. Yeah, that was honestly just a fun learning experience. I didn’t actually use any of their techniques myself because I didn’t want to to do the canvas approach or the primary color thing.
Sam Brace: One question I have about the primary color thing.
So if I go back up to the overall script that we’re showing you here, and you can see that we have these transformations and you have the background call on this case, is that the primary color coming through in that situation?
Kent Dodds: Yeah, that’s a great question. So I think that is just for transparent images.
Like I have a couple blog posts that have a transparent background and I decided at some point that they just look funny, to be transparent. And so I can’t remember what color that is. But it was just like a good background color that’s generally use or good for anything that has a transparent background.
No there’s no I’m not like determining what the primary color is and [00:36:00] putting it in there. That’s hard coded.
Sam Brace: No, but I still like this approach though. Cause it’s a flat color. It’s showing this is where something should be. So it may, it makes sense why you would do this type of a transformation.
So it may not be exactly like what we saw with Unsplash, but it is showing similar purpose.
So moving on to you. So now we’ve gone through the overall process here of talking about what you’ve gone and done and we can break down some of this, but we’ve touched upon Base 64 encoding. For those that aren’t fully aware of what we even mean when we say something like that.
What is Base 64 encoding and why would you even wanna do something like that?
Kent Dodds: Yeah base 64 encoding is just a way to represent binary data as a string. And like in, in particular as like a string that’s using characters that we recognize. But the particular [00:37:00] nicety of base 64 is that it can be used as the source attribute for an image element.
It can actually be used as a source attribute for a lot of things. There’s another place on my website, it’s the Call Kent podcast where you can actually record yourself asking a question and that will save to my database. And then I record my response later, and then that turns into a podcast episode.
It’s actually very cool. And I use Base64 encoding to set the source attribute of an audio tag so I can preview what they’ve recorded and stuff. So you can use Base64 to encode just about anything into what is a readable string and it’s not necessarily really small.
But interestingly, that that audio file that I create when people record themselves in the Call Kent podcast, I tried saving it to my database as binary, and I then I tried saving it to my database as Base64 and Base64 [00:38:00] was smaller. So I probably did something wrong, but I was, because I was very surprised by that.
But that’s how it’s saved in my database today is I’ll save it as Base64. With that the binary data that I want to turn into Base64 is a blurred version of the image, my placeholder. I want to turn that into Base64. And the reason that I wanna do that is so that I can render my blog post with that Base64 hard coded as the source attribute so that the browser doesn’t have to actually make any request to display that placeholder image.
And yeah, that’s the entire reason that we’re doing Base64 at all. Because if I what’s cool with Cloudinary is I can just say, “Hey, give me an image that has a width of a hundred and give it the effect of a blur of a thousand”, whatever that unit means. I don’t know what it means. I tried a bunch of numbers and that worked.
Becky Peltz: Best way to figure it out.
Kent Dodds: Yeah, exactly. And then and I [00:39:00] also specified the format as WebP, just because this is my server doing it. So I can’t rely on whatever browsers are requesting this. Anyway, I make a fetch request on the server at runtime to this, that gives me back the image data, which I then encode with Base64 and then set as the source property of my image as the background of the image that’s going to be loaded later.
So the drawback of using Base64 versus the blur hash is Base64 is 10 times bigger. In, practice it’s 10 times bigger of, a couple characters is actually not a whole lot. Like you look at the size of this blog post, it’s, it’s just a little drop in the bucket, but it still is not the best.
And so I wish I could avoid this. But for the use cases that I have, it’s definitely the best option.
Becky Peltz: It’s just like a lot of [00:40:00] channels on the web only can deal with text, if you want to put an image in a email or something, sometimes it has to be Base64 encoded.
Kent Dodds: Yeah. They don’t want to load remote stuff
Becky Peltz: Yeah.
Kent Dodds: But this wasn’t the end of everything because one thing I noticed was, and you scrolled to it for a second there. The blurred image looked really bad, like very pixelated, because what I did was I took it only a hundred pixels, so it was a hundred width. So not a hundred pixels, but it was width of a hundred.
And then blurred that, and then I upscaled it to 10x, a thousand pixels width. And so that just made it look, even though it’s blurry, it looked pixelated, just didn’t look very good. And luckily there is an awesome filter that you can apply to a div. So I put a div on top of, positioned absolutely on top of this image where the backdrop [00:41:00] filter to set a blur.
And then so I blur it from Cloudinary and then I blur it further from the browser to give it.
Becky Peltz: You have a tiny blur. You expand it and then you make the browser blur it. So that’s.
Kent Dodds: Yeah. Yeah, exactly.
And I actually, now that I say that I didn’t think about just saying, “Hey, Cloudinary, give me a small image and then I’ll just have the browser blur that myself”.
But maybe I could have tried that. But it’s working now, so why bother?
Sam Brace: And that’s one way we look at it is it’s like not everything always has to be a hundred percent Cloudinary. It’s where with CSS, other things you can come up with amazing results. And this is a proof of that. So we’re a piece of the pie.
We’re not the only pie that’s there. So that’s good.
Kent Dodds: Now I want pie.
Sam Brace: You can see the immediate difference here too. Like you’re, you can see like the rings of this are very distinct. It’s, it almost has a muddy look to it with the amount of moving you’re seeing there. And then when you did the work that you did, everything’s [00:42:00] smooth.
It’s very hard to tell even from the background what I’m looking at here. Which is the point of blur. So it’s a good, it’s very good what you did.
Kent Dodds: Yep. That, was actually that, that worked out really well. But it still wasn’t quite what I wanted because what I was looking for was you have the blurred image and then it fades into the finished image.
And what we had at this point was you have the blurred image and then when the actual image loads, it just takes its place. And that doesn’t look too bad. It’s fine, but I wanted it to fade into place. This is tricky because there’s no API in the browser from HTML that says, “Hey, apply this class when it’s ready to go”.
Of course, there’s a JavaScript way to do that, but there’s no HTML way to say, “on load, do this thing”. And what I had to do was I, and of course [00:43:00] like already we’ve gotten a couple of things in here that I’m like, yeah, I definitely want turn this into a component so I don’t have to do this all over the place.
So I made this blurrable image component, and so the code that we’re looking at now is an example of that blurrable image component. Where you passed the Base64 URL. That’s the blur data URL that we see as the prop there. We have our aspect ratios there as well. And then we have our image, the element, that you’re supposed to be rendering here and there’s the get image props there as well for doing our different sizes and all of that stuff.
So the actual implementation of the blurrable image component is a little bit further down, and this does some pretty interesting things.
Becky Peltz: Yeah.
Kent Dodds: Yeah. Sorry. Did you have a question about the usage though?
Becky Peltz: No, I just said this is cool. I [00:44:00] like how you did this.
Kent Dodds: Yeah. So the blurrable image component it takes that image, it takes the blur data URL, and then the rest of the props that it takes are just whatever else you can apply to in an image element. We’ll just pass those along. And so what we have to do in JavaScript because we, there’s no HTML way to do this as we have to maintain some state to say whether or not the image the final loaded image is visible.
And then I use that visible value to determine what class names should be applied. So this is all React’s nice and declarative model where we can re-render, and now the, here are the class names that it should be now. So you’ll notice on line 33, I’m cloning the image element that they gave me.
So , we have the react element that’s the image element that they created. I’m actually going to not render that directly and instead create a new one that’s a copy of that. That I have a reference to that’s the ref prop there. [00:45:00] And then I have a class name that’s going to be all the classes that they provided.
Plus I want to transition the opacity so I can animate that. So I can transition in and then I set the opacity to zero if it’s not yet visible. And then we’ll get to that use effect here in a second. But then where I render, I need to render the div. I’m gonna put all of the the rest of the props on that.
So I guess those that rest is not the image element, it’s the div element props. So yeah, I, I render a div around all of this to keep them together. If there is a blur data URL honestly, I shouldn’t make it so you can render one of these without that, because why would you use this component if you didn’t have a blur data URL?
But if that does exist, then I will render the blur image. So that is the source is the Base64. The class name is gonna have the same [00:46:00] class name as the image that you’re providing, so it has the same sizes and everything. And then the alt text because we care about screen readers.
And then we have that backdrop blur you URL to give it a smooth blur. And then next to that we render our JS image L and then the no script image there. So in case the, this is very rare but if somebody has disabled JavaScript on my site, I still want them to be able to see the images. And so we’ll just render the image as it is and it will work.
And I’ve tested that. That works. And so yeah that’s the basics. Now the trick is how do we know when we should remove that opacity zero class name? And so that’s what the use effect is for. If you go a little bit above, like in the middle of the blur image component, there’s this use effect where we say first we do some early returns, like if the ImgElRef, if we don’t have a current [00:47:00] DOM Node of that image, then that’s unexpected. We’ll just return that, that will never happen. But, I mean it could, and we don’t want bad things to happen if it does. So I guess and then the jsImgElRef.current.Complete. That .current is just a DOM Node reference to the image element.
And so .complete is a property on an image element that says whether or not that image is finished loading. So if we have finished loading, then we’re just gonna return. We’re all done. We’ve done this before, it’s fine. And it then we say add event listener on that image element, Load.
So when that load has finished, then we’re going to set visible and we’re putting that inside of a set timeout for a good reason that I can’t remember, and I probably should have wrote a code comment to explain why we’re doing that. I remember putting it there. I just don’t remember why I did it.
Just putting it on the next ticket to the event [00:48:00] loop for some reason. I just can’t recall why that was necessary. So anyway, that, that’s a basic idea. We’re fundamentally we’re just saying when this image has finished loading, then let’s set it to visible so that it will fade in. So it’s actually a lot of work just for the simple fact that I wanted to be able to have it fade in rather than just magically appear.
And that the bulk of this component is for that particular feature, we could probably remove everything from line 14 to line 41 if I didn’t care about that. Yeah.
Becky Peltz: When you do have timing considerations here cuz you’re rendering really two images. You’ve got your blurrable image and then you, in the background, the other, the real image is loading and you need to know when it’s done before you can do your transition. So you do, you are working with some things that you have to think about there.
Kent Dodds: Yeah. Now what’s kinda interesting about this is I ran [00:49:00] into some problems. First of all, it makes me a little uncomfortable that I require JavaScript for my images to be seen. So if we have to wait until the JavaScript shows up before we can actually get that opacity zero class off, cuz we, we render that opacity zero class on the server.
So you will not see this image until React does its thing and I can say, okay, re-render without that class name. That makes me feel uncomfortable. And it actually played out in in production where I had some sort of error with my site where the JavaScript errored out. And so this code never ran, and so people could only see the blurred image only the stuff that was sever rendered.
And the no script stuff on line 54 doesn’t work in that case because scripts are available, they’re just, they failed to run. And so I don’t really like that too much. And I just moved [00:50:00] on and it was fine. And this only happened once and so it wasn’t a really big deal.
But it does make me feel uncomfortable that I have to wait for JavaScript to load and then be parsed and then executed before we can actually remove that visible zero or opacity zero class name. Yeah, that’s just unfortunate because the image could actually have finished loading before the JavaScript has even been loaded itself.
And so we’re showing a blurred. A blurred placeholder when we could just be showing the full image and that would be a lot better. On top of that, if the browser has already cashed the image and you just go up and hit refresh on the page you’re going to see the blurred image until the JavaScript is evaluated and stuff.
Where, what I would prefer is that you don’t see a blurred image. So what our status quo is now is you always see a blurred image and you’ll see a flash of blurred state and then you’ll see the [00:51:00] full image. And I would much rather say if the image is in the browser cache, it should just instantly show, I don’t even care about showing a placeholder.
And so I left it this way for a long time and then like two months ago, you all reached out to me and said, “Hey, we want to talk about this cool blog post”, and in the back of my mind I’m thinking, “Oh shoot, there’s that one thing I don’t like about this”. Two days ago, two days ago, right before we did this, I spent a little bit of time investigating.
This this loading experience to make it a little bit better. And so that’s the next section here is fading faster. Yeah, I said, and really that’s it. That was how I ended my blog post before. And then I added, except now that it’s 2023, I decided to improve one more thing, and that’s to make it fade faster, to solve this problem of what if the JavaScript fails to load?
What if something goes wrong? And the fact is because html doesn’t support any mechanism for updating or for saying, I want to fade this image [00:52:00] in. We have to do it in JavaScript. But, I don’t want to tie all of this logic into that particular bunch of JavaScript that happens within the react hydration and all of that.
I would a rather just have a little bit of JavaScript because it’s really not a lot that says when this load thing happens, just remove that class. And so that’s exactly what I do in theory, this is as easy as it should be, is you just add an on loan prop. I realize there are a lot of people who are looking at me right now and saying, “you’re doing inline JavaScript, you’re a joke”.
“That’s even worse than inline styles”. And it is. This is the quintessential, like perfect use case for something like this. It’s the simplest amount of JavaScript I can imagine for for this type of use case. I could also do render another script [00:53:00] element that does the same thing, but I don’t know, look at line 5.
That’s easy. There’s nothing complicated about this. Unfortunately, there is something complicated about this because React does not like inline JavaScript like this and it will not render it will not render these prompts and instead it will give you an error that says you need to use the on load prop with an actual function.
And so that is annoying. That’s really unfortunate.
Becky Peltz: There’s nowhere.
Kent Dodds: Cause now I’m like right back into the React thing and I have to wait for all of React to hydrate and all of that. So, I did a fair bit of work to make this this work. That is a little involved and I don’t think it’s necessary for you to dive in.
You can look into the commit that I linked to a little bit below to dive into how I made this work cause it is kind of complicated. But at the end of the day, I was able to make a really awesome experience where if you’re on the page and you hit refresh, [00:54:00] so the image is already in your cache, you do not see a flash of loading state.
And it just it instantly just shows the image. And I think that is a much better user experience. Yeah, you, if you click on that, yeah, you can see on the left side it’s flashing. Each one of them is hitting the refresh button at the exact same time. But the left side is flashing the blur state and the right side, you don’t see anything like that, so much better experience. Some people actually comment on this and they say, “I actually like seeing the blur state, cause it shows me that it refreshed.” And I’m thinking “You’ve been conditioned, my friend. That’s wrong. You don’t like it. You don’t like it.” So anyway, there you go. That’s how I did nice placeholder and an awesome loading experience on my website.
Becky Peltz: Yeah.
Sam Brace: Amazing.
Becky Peltz: It’s so interesting how there’s such a battle with wanting to use JavaScript to help you make things work, but then JavaScript takes long to [00:55:00] load, so for performance reasons you don’t wanna use it. Yeah. It’s kinda like you’re torn.
Sam Brace: So, a couple questions for you, Kent, about this overall thing. So, obviously we’re using React for a lot of the things that we’re showing in this case, but could you take similar concepts that we did here or maybe identical concepts and apply it to other frameworks, let’s say Vue or Angular other things, or is this like where unless you’re using React, this is impossible.
Kent Dodds: Yeah, that’s a good question. There’s nothing in here that I’m doing that is exclusive to React. This is all web platform stuff. Arguably it might even be easier in other frameworks because of that on load thing that I was talking about.
React just really, doesn’t want you to do that. Like I said, I could do an inline script or a script tag that does the same thing and that maybe I’ll switch to that. Because you can’t actually the content security policy doesn’t work very well with inline scripts JavaScript or attribute scripts.
Which, [00:56:00] yeah, so I should probably change it for that reason. But yeah, actually at the bottom of the post there, I have that little Ps there’s this unpic image component that is a framework agnostic implementation, very similar to what I’m doing. They actually don’t do a Base64 and instead use CSS gradients to accomplish a blurred version of the image.
It’s very interesting and they have implementations in all sorts of different frameworks. They also support a lot of different image CDNs, including Cloudinary and others. Look, I wish this existed when I was building mine, but now I have this cool blog post where I can explain how it works.
Becky Peltz: Yeah, no it’s just a neat, watching you come up with a solution in this, and I’ll just share too, that like the Cloudinary React SDK does have a placeholder plugin that you as it kind of starts out blurry and it turns [00:57:00] full resolution while you’re watching it. But again, you’re loading somewhere JavaScript to make that happen.
Sam Brace: And I, I actually love the shout out you’re doing for the unpic side of things because I can look at just the contributor to list here, and there’s some really awesome people that are tied to this. Looking at Zach, who’s tied to Eleventy here, our friend Elad who’s tied to Stackbit, like there’s a lot of good minds that are putting contributions into this particular thing.
I agree it’s a great place to be able to start handling multi framework imagery and responsive aspects of it. So it’s great. So, one question that did come up in the community that I wanna address here, because a lot of things that we covered here, of course they’re, in my opinion, I would say advanced topics.
You’re doing things where you’re almost like optimizing what’s already been optimized with some of the things that you’ve gone through, this process stuff. But, let’s say that I’m a fairly new JavaScript developer or someone thats new to web development, [00:58:00] where would I be going to learn how to do more of these things? And I’m not trying to give you a softball like, “Hey, queue up Epic or React and all the great work you’re doing there.” But please do. But in the same sense, like where, is there any spaces where people can be getting to better understand what’s happening with the web, particularly with JavaScript development that you’ve come across that have been helpful?
Kent Dodds: Yeah, I have a blog post about experience and getting experience as a web developer, cause this is a very common question, how do I get better? And the answer sounds pretty obvious. You get experience by having experiences. You really just have to you, you can spend all day on Twitter. You can spend time on YouTube watching videos. You can spend, buy a really great course like Epic React when Epic Web comes out, Epic Web. And that’s all good. You should be doing those things some of those things. [00:59:00] But really you don’t get experience until you have those experiences.
I strongly advise just spending a ton of time working on actually building stuff. And subscribing to newsletters is good for keeping up. I’ve got a really great Discord community that you can come in and keep up with what’s going on in there. Staying involved on Twitter and stuff, that’s also really good.
To be involved in that. So all of these things are useful to give you a sense of what’s going on in the ecosystem. But then you have to take that and actually build something.
Sam Brace: A hundred percent, and I’ll plug your Discord community. I’ve become a recent member of it myself, and I think it’s a great place to be hearing about these conversations, but to further your point, it’s where if you hear something that kind of tickles your brain and you’re like, oh, I wanna learn more about this, then yeah, do your job to learn about it, [01:00:00] but then get your hands dirty and get into it.
And that’s the only way that you’re gonna be able to grow, in my opinion as a developer. You, you have to if you always say good writers write a lot, the same thing, good coders code a lot. And it doesn’t mean that every line you write is gonna be beautiful, but sometimes it will be, and it all comes experience.
Becky Peltz: I think its sort of like any kind of like an athletic event, if you wanna be prepared for it, or if you wanna prepare for it, you just have to do a lot of it, it sounds like every day you have to dedicate time to massaging that and building it up.
Sam Brace: Excellent, Kent. I’m inspired and I, and of course we’ve already shown the blog post extensively to all the places that people can understand what’s happened and be there. I’ll also point out in, gimme a little bit more detail there too, but you have a GitHub repository that is focused on just the overall blog presence that you have here, and I’m sure that a lot of the things that you have that you’re showing here [01:01:00] are available through this overall repo. But what, like, why did you ultimately decide to expose everything you have for your website in this repo?
Kent Dodds: It’s easier. Yeah. So my, my content is actually inside of the website itself. So there’s the content directory and that’s all my pages, all of my blog posts, everything is in there. And I do that because the, it’s just a lot easier to manage the contributions when I have like typos and stuff, people contribute I have hundreds of contributors to my blog posts through that mechanism. And then my, having my site open source just makes it a lot easier for me to answer people’s questions. They’ll say, how do you do this? And I’ll just say, here’s the file where I do that.
And so yeah, the entire site is open source and it I’ll I’ll also mention that my website is not your typical developer portfolio. And if what you’re [01:02:00] building as a developer portfolio, do not use my website as a template because it is way over scoped for what you’re trying to do.
And that scope brings along a lot more complexity than you need for your site. So start use somebody else’s because I’ve got three SaaS products that I or three things that I could turn into SaaS products on my website. That you definitely don’t need on yours.
Sam Brace: Completely fair. And it, it’s good to get people of those caveats. I completely agree. And I think we’ve also one thing I always ask before we end one of these conversations, Kent, is where people should be going for more information. I think we’ve made it pretty clear, kentcdodds.com is your main portal for all things that are tied to you.
But is there any other places where you find that you’re more active? Are you more on Twitter or LinkedIn or other places? Or if you wanna get like the the latest that’s coming from you? [01:03:00]
Kent Dodds: Yeah. I’m most active on Twitter and I always share stuff to the Discord community. They typically get the exciting stuff first.
And then the, my mailing list that you can find, just kentcdodds.com, scroll down to the bottom you can or just sign up for an account there and you’ll be put on the mailing list as well. But yeah I’m doing remote workshops and stuff like that I, yeah, I recommend yeah your signed up looks like, cause you, you signed in, but yeah, so that, that little image on the right there turns into a form if you’re not signed in.
Okay. So yeah, the, that’s probably the mailing list is the best way to not miss anything, for sure.
Sam Brace: Excellent. Kent, once again, I’m inspired even past what I read of the blog post, getting to hear your introspective review of how you [01:04:00] got done, what you got done, and also getting the business case of it.
So, keep up the good work, Kent. Obviously there’s lots of people that are tied to the communities and the work that you’re doing, but we love what you’re doing here at Cloudinary, so keep it up.
Kent Dodds: Thanks a lot. I appreciate that.
Sam Brace: Excellent. So Becky, I had wanted to ask you.
Becky Peltz: Yes?
Sam Brace: What is our big takeaway from this? There’s a lot of things that are bubbling up my mind by what’s yours.
Becky Peltz: I think that Cloudinary needs to create an e_kentdodds effect. So we don’t have so much JavaScript. His process is just wonderful. And I think the effect is something that anybody could appreciate. And he does use one of our effects, the blur effect. But then he has that little bit of magic in it that gives you something before, and then it transitions into it. Yeah it’s definitely something if you’re putting images on your site, think about something like this or [01:05:00] use this.
Sam Brace: Yeah. It’s one of the things that we’ve seen other great guests talk about some similar stuff, like when we had Brad Garropy on, he was talking about cumulative layout shift and being able to understand it.
But it’s where this is kind of taking what Brad did which was kind of creating a simple placeholder for it and really doing a lot with it. Being able to tie in the blur effects and then being inspired for the different places on how we can maybe incorporate background colors as we saw so, and being able to evaluate what is the right choice for your overall presence.
But it is to say that the more you can create an optimal experience for the visitor or the user or the person that’s diving into your content as Kent showed, you can really do it in a really fun way and make sure it also helps out your presence from how search engines and others see.
Becky Peltz: Yeah, and I think too, like just the idea he got inspired by what he saw on Unsplash, that you could see something on the web that you like and you can [01:06:00] actually take it, tweak it, write your own code for it and make it even better, so it’s great to, to be aware of that inspiration out there.
Sam Brace: I completely agree. And talking about further inspiration, Becky, we have future and past episodes. They’ll always be at cloudinary.com/podcasts. So if you took something away from a conversation that me and Becky just had with Kent, please make sure that you’re checking out other episodes that are happening to be in the space.
And of course, those episodes are gonna be on all the places where you typically will like and subscribe to podcast content such as YouTube, the Cloudinary Academy, Spotify, Apple Podcasts, Google Podcasts. There’s so many out there, but it’s where we do have hopefully our presence in those different places, wherever you like to consume content.
And similarly, I recommend continuing the conversations about this overall content in the Cloudinary community. That’s gonna be at community.cloudinary.com [01:07:00] and as you can see, when we take a look at this, this is going to be where you have lots of forum based tools, but also if you’re an active Discord user, we do have a lot of members of the community that are also having more real time conversations in that space.
And so if you’re a forums person, if you’re a Discord person, if you’re both, it gives you options to be able to continue the conversations about what you’ve just heard about in our conversation with Kent and have that possibly affecting the way that you’re building out your next software development project.
Becky, before we let everybody go, any final words, any final thoughts?
Becky Peltz: Yeah, I just, it’s amazing what’s going on in the community and to meet somebody like Kent Dodds who is so involved and in into so many things. I think I’m thinking, I’m gonna go sign up for his newsletter, let’s just say.
Sam Brace: Becky, thanks for being a part of this as always. And thank you, all of you that are listening and watching this DevJams episode on behalf [01:08:00] of everybody at Cloudinary, thank you, and we hope to see you at the next DevJams episode, and where we’re we gonna profile another developer that is building inspiring, innovative, exciting projects, and of course using Cloudinary for an aspect of it. Take care everybody. We’ll see you soon.
2023-05-23
Retrieving Instagram Content, Delivering with Cloudinary
In this Cloudinary DevJams podcast episode, we talk with Joel Turner – Senior Product Engineer at Sprinkr! He demonstrates how he built a Gatsby plugin that uses Cloudinary to serve Instagram content on his blog. Our hosts and guest dive into all things open-source, as Joel is actively creating and sharing code on GitHub for Jamstack plugins and other projects he is authoring. Additionally, Joel recently migrated code from one React-based framework to another and shares his experiences, now publishing his blog on the Next.js framework. If you are interested in working with Instagram posts for future development projects, or building your own plugins, this is a DevJams episode you won’t want to miss!
Sam Brace: [00:00:00] Hey there everybody. My name is Sam Brace and I am the Director of Customer Education for Cloudinary, and you are about to watch and listen to DevJams.
For all of you that are coming in, thank you for being a part of this amazing episode where we’re gonna be talking with Joel Turner about some of the awesome work that he has done to incorporate Instagram to develop a project that’s allowing to bring in the illustrations that he’s sharing through that social media service and using Cloudinary to be able to do so because on Dev Jams, we’re featuring developers like Joel and many others who are developing, inspiring, innovative, interesting projects that happen to use Cloudinary in some way and of course, our overall development projects. So we’re gonna be talking about all things API, SDK, and overall code related concepts.[00:01:00]
So, with every one of these episodes is Becky Peltz, and she is the overall curriculum development manager, program manager at Cloudinary. When it comes to developer education, we’re always having her on these episodes, and it’s always a pleasure because of the wealth of development experience that she brings to these conversations.
Becky, wonderful to have you here once again.
Becky Peltz: Hey, thank you, Sam. It’s great being here.
Sam Brace: So tell me why are we excited to talk to Joel here today?
Becky Peltz: You know what I really notice about this project and this whole discussion that we’re gonna have is we all interact with websites that have images, especially like social media.
And in this case will be Instagram. And what I like is that you can simplify your interaction with the images, video, whatever type of digital media that you’re working with. By moving it to Cloudinary and that’s what I think we’re gonna see here because [00:02:00] Joel is able to pull his images out of Instagram into Cloudinary and then moving it around in different stacks and different formulations.
He has simplified his work. So it’s a neat little story. I really hope we can share the code and everything that he’s done for that.
Sam Brace: I agree. I think one thing that’s very cool about the way that he’s gone about this is that he’s made this social media service, which of course he’s used for many different purposes, and kind of almost turned it into his CMS for all things illustration related and being able to be able to not just be solely reliant on the Instagram APIs.
That way you can involve the content delivery networks and all the various things when it comes to web-based delivery and caching that Cloudinary can provide. It creates this really nice, stable way to make sure his illustrations are shown without any hiccups or issues. So it’s an exciting time.
Becky Peltz: Yeah. Yeah. No, it’s exactly very well said. [00:03:00] Thanks. Yeah.
Sam Brace: So before we jump on over to Joel, what I do wanna make sure for, because this may be your first time going through DevJams here with Becky and myself and the Cloudinary team, but always know that all of our past episodes are gonna be located at Cloudinary.com/podcasts, and that’s where you can see that all podcasts that our team has developed for the DevJams program, as well as our sister program, MX Matters, where we talk about thought leadership when it comes to what they call the visual economy, that’s where you can see all of the various episodes. And then of course, if you are a listener or a watcher of podcasts on other services such as: YouTube, Spotify, Apple Podcasts, Google Podcasts, and wherever else we’re probably there too. And on top of that, also at our Cloudinary Academy, which is where all training things take place. Know that if you are saying, wow, this was a [00:04:00] good episode. I would love to do more of these or be part of more of these, know that you can always do all of that there.
And just to point out, we do have an excellent and vibrant Cloudinary community for users like you. So if you are inspired by some of the conversations that me and Becky and Joel are about to have, know that you can always continue those conversations here at community.cloudinary.com so without further ado, let’s bring in our friend Joel and start talking a little bit about this amazing project that he has gone and developed. Joel, welcome to the program.
Joel Turner: Hello. Thanks for having me on.
Sam Brace: So tell us a little bit about yourself and how you got to the space that you’re in today. Where, as we’ve pointed out, you’re using Instagram, you’re an illustrator, you’re combining these two things together. But even before that, how did you get into the overall development space?
All things that I’m very interested to learn about.
Joel Turner: Yeah. I studied graphic design in college and [00:05:00] that kind of morphed into working on websites as, as soon as people know you have some sort of design, they tends to be design everything. So I spent a couple years just tearing apart websites and trying to figure it all out and got into html and css pretty solidly.
And then yeah, that just morphed into more of a technical role with companies where I was the IT webmaster, graphic designer, all that. And that kicked some of my design sense down a little bit I guess I was spending so much time in front of the screen and wanting a break from that.
So I started drawing every day and sharing those on Instagram and knowing that, they’re [00:06:00] gonna be bad at first, but hopefully I would progress in public and got a couple years of drawings.
Becky Peltz: Yeah, and the drawings are wonderful.
Joel Turner: Oh, thank you.
Becky Peltz: If we don’t see ’em right away, we’ll definitely be taking a look at them and I just so appreciate the fact that you have the attitude of, I don’t care if it’s not a perfect drawing, I’m gonna get it out there, it’s gonna be put online, it’s gonna be cataloged as we’ll see. Yeah, it’s a very good approach.
Sam Brace: So Joel what led you to starting to say, cause I, I love the idea of learning in public or doing things in public, as you’re pointing out. It’s a great way to get instant responses, but it also encourages you to keep going through the practice. But what got you to say, I wanna post this content on Instagram? What was that turning point? [00:07:00]
Joel Turner: I think I, I was seeing a lot of hand letters on, at the time, this was 2015, I think 2014, 2015. And the community around hand lettering was so supportive and beautiful. So I thought, may, maybe this is a safe place to, to start exploring this. And sure enough, everyone was so supportive and warm and we just all bounced everything back together. And I think I got to an emotional point where I just wanted to do something in public that was different than my normal day to day and try to get rid of all the fear and anxiety around shipping something. And there was a lot.
Becky Peltz: Yeah. I’d say it’s a critical public, that’s for sure. And even putting anything on social media [00:08:00] you’re putting yourself at risk, but I, one thing about Instagram that I’ve always appreciated is that it’s, it is a visual, more visual medium. Visual social media, you’re not sharing links, you’re not making little, snide remarks. You’re saying, “Hey, take a look at this.” So I think that’s a great place to share.
Sam Brace: So then looking at this, and I feel like I’m gonna bring up your screen here so people can understand some of this, because now that we can see that you’re doing all of this amazing work with hand lettering, you’ve got great illustrations taking place. You were taking this content, you were ultimately bringing it also to your personal web space. But then, because of that, it sounds like there was some type of pain point or maybe some type of issue with getting the content from Instagram to the Joel Turner personal space. Can you talk to me a little bit about that?
Joel Turner: Yeah. There, there came a point where I wanted to share some of my, what I thought were my better pieces in, in one [00:09:00] collected area. And at the time I was still on WordPress and found a couple of WordPress plugin dealt with Instagram, but it wasn’t quite what I wanted. I couldn’t narrow it down very specifically. And then Gatsby came along and shifted my whole mental model of what could be a source for a website. And that, that’s one of the idea of using Instagram as a CMS by adding hashtags to all of these posts like these that are up. I’ll have a JMT underscore featured hashtag on ’em. That way I can search my user and those hashtags and get that whole list. And Gatsby worked really well with that sort of system.
Sam Brace: And to be clear, so you’re adding those hashtags like let’s say in the description of the [00:10:00] post, and then it’s able to extract that from.
Joel Turner: Yeah, and there was a limitation on Instagram, which we can go into it later, but they, for a while, they wouldn’t allow you to edit your original description, I guess for the post. So I would have to add those hashtags later on in the comments.
Becky Peltz: There is always really around.
Joel Turner: Yeah. So when I’m pulling from them, I have to look through multiple comments as well.
Sam Brace: Got it. Okay. Okay, so I’m starting to understand the workflows. So Joel draws something fantastic.
He documents it in Instagram, makes sure that there’s a certain hashtag that’s been applied there for tagging purposes. So then, now that you’ve applied the tag, it sounds like then that’s acting as a signal to whatever service that you need to be able to display it onto the website. And I know you just mentioned Gatsby, so is that what’s happening there?
Is Gatsby involved in that [00:11:00] process?
Joel Turner: It originally it was, yeah, there was a, there’s a plugin from one of the community members called Gatsby Source Instagram that pulled all that pretty much anything from your user in, and then added a little feature to that to also filter down on hashtags and let those.
Becky Peltz: So I’m gonna call out a little bit there about Gatsby Source, because you’ll see if you go out to Gatsby and Gatsby, if anyone’s not familiar as, a static site generator for producing websites. And it’s now been purchased by Netlify, but always deployable there. But the thing, the Gatsby source is something that they created to allow you to go in, to basically
API your way into many different sources, but then get it into that GraphQL Gatsby data layer. [00:12:00] So is, and so that’s if you go out, Gatsby source, Contentful Gatsby source, all these different things. So you found one that was for Instagram and that was your starting point to getting into Gatsby.
Joel Turner: Yeah, exactly. And that exact plugin didn’t quite support the hashtag feature. So that, that little bit I added to the plugin and then that shows up in your Gatsby, GraphQL as all the hashtags, an array of hashtags that are on that Instagram post.
Becky Peltz: And that was kind of like, was that your first step into open source, of submitting PRs and working with developers like that?
Joel Turner: Yeah. I had done a minor one before that was just, one character change, but this was like the [00:13:00] first actual feature and a little bit of a complex one. I wouldn’t say people were clamoring for this feature. It was…
Becky Peltz: I don’t think anybody realized you could tag Instagram. Kinda like we have tagging and Cloudinary, for to help us manage. But to be able to tag your Instagram using a hashtag is a really great idea.
Joel Turner: Yeah, ended up working out really well and actually Cloudinary’s ability to use tags was a major part of my decision to use Cloudinary. The one API that I wanna pull from for my site.
Sam Brace: Yeah, that’s what I’m looking for here.
Cause I like that’s the big connection that I might be missing. Cause like I understand that you have this flow. To me it seems like it’s almost that would work perfectly. Like you’re querying Instagram. You’re getting all the data you need, you’re getting a place to do [00:14:00] it.
Where did Cloudinary come into the process? Why did you decide that we were part of the, when I say we Cloudinary why were we part of the process?
Joel Turner: Yeah. There were two major pieces of that. One, I was exploring building my site in SvelteKit and NextJS and I didn’t wanna have to redo all the images everywhere that I went, each has their own way to handle images.
And I love the simplicity of a Cloudinary URL where you can just add whatever parameters you need to there. So it, it felt more portable if I could leverage Cloudinary in that way, and the big reason was every time I opened my website locally to write a new post or anything, the Instagram API had very [00:15:00] aggressive limits.
So you spin it up once it works. If you have to restart the dev server, it’s not gonna work again for 15 to 30 minutes or sometimes more than that. So I got real tired of that flow.
Sam Brace: Oh, I would get tired of that too if I had to say oh, for me to do something, it should be fairly simple.
It’s gonna take me 15 to 30 minutes to do, I would be looking for alternatives immediately. So I understand exactly why you went down that path.
Becky Peltz: And I think the thing too, when you submit things to social media, a lot of times you, I just go in with the idea that I’m giving it up my content.
I don’t own it anymore. I don’t have a really great way to access it again. But what you’ve done is open that up, so now you can, now you, when you get it in Cloudinary, you do own it, and it’s, there’s many ways for you to interact with it. So it’s a good idea.
Joel Turner: Yeah, and the in, in that vein, the service is meant to [00:16:00] hopefully pull from other endpoints maybe Google photos or iphotos, things like that.
I have plans for that in the future. My, my wife is really good at photography and it’d be nice to be able to pull her photos from Google Photos and display them on her site.
Becky Peltz: That’s, yeah, that’s really great.
Sam Brace: I would love to be able to see a little bit of how it, how you got it all to work.
Is there any way we can dive into some of the code, take a look at how this overall flow worked?
Joel Turner: Yeah, definitely.
Sam Brace: Awesome.
Joel Turner: So lets start with the, so this is the service. It’s mainly all in, in one file. That’s just a couple of the functions here. So we have our setup for the Cloudinary, API, just getting all the right config in there.
Becky Peltz: So just to be clear, we’re no longer talking about one [00:17:00] of the Gatsby source. You, this is a script that you wrote, Instagram Cloudinary, that deals specifically with this.
Joel Turner: Yep. Yep. This is bypassing that whole flow. And originally after I set this up, got my images up on Cloudinary, I was able to use the Gatsby source Cloudinary to pull those back into Gatsby.
Flawlessly. Never had to worry about timeouts or anything, so that was a huge improvement. Just right there. So if we go down to where we’re calling the file here the first step we’re fetching all the posts from Instagram, and then from there we’ll convert those into the shape that I want to send up to Cloudinary that’s going to have the tags and the [00:18:00] public Id or the name of it.
Then we upload those and then few pieces here just to make sure that they did upload correctly, which I never had a problem with. Just being a little redundant there.
Becky Peltz: Yeah, no good idea to use those net netlify or the web hooks.
Joel Turner: Yeah. And then, yeah, and then it tells Netlify to go build my site again. Once it’s good, we can so when we fetch from in Instagram just this one URL with parameters, so you can give it your Instagram id and then it’s gonna call just your user. It’s not gonna crawl all of Instagram to find these hashtags whatever you tag, you’re only gonna get yours, which was key for me.
I, if somebody else tagged something, JMT featured, I didn’t want theirs on my site necessarily. Then [00:19:00] you can specify…
Sam Brace: One thing, Joel, pardon my ignorance on this, where is the hashtag being specified in this?
Joel Turner: So in this one, you actually just specify that you want comments and you want the description.
And then when that comes back, the Instagram object, I think I might even have the types here. They’ll have the comments, which will have hashtags in it which you have to parse out a little bit. And then sometimes they’ll have, a little bit extra.
Sam Brace: Okay. No that, that’s really helpful.
Joel Turner: And right now I’m supporting carousels, just the first image of a carousel, but that was a fun gotcha that I ran into [00:20:00]
So yeah, once, once we get all the posts back from Instagram, then we can start converting them into what I’m calling an upload post, which is just the shape that I want to give Cloudinary all the required fields and the array of tags, which is the important bit.
Becky Peltz: So you’re specifying a folder, a public id, and then you’re taking your hashtags from Instagram and turning them into Cloudinary tags.
Joel Turner: Exactly.
Becky Peltz: Yeah.
Joel Turner: Exactly. Yeah. And the folder works really well for this just having the illustration folder that matches with this whole model, and I chose to name the images with the timestamp so I could sort ’em again on the front end. So it’s whenever they were posted on Instagram and that then I sort reverse on that. [00:21:00]
Sam Brace: And I think that’s pretty smart, frankly, cause if a timestamp is acting as a like unique identifier, it like there never could be identical timestamps likely, unless you are really doing something crazy, in my opinion.
So I think that’s a nice way to look at it, because it makes sense to you. It’s not true randomization, but it’s randomization in the sense that you’re not gonna be accidentally overriding files or anything like that. So I think that was an excellent identifier for what you’re naming things, putting them into Cloudinary.
Becky Peltz: Especially when you’re using tagging, it’s not so important to like, put a big description into your public id, because you’ve got all that description in the tags.
Sam Brace: Exactly.
Yeah. Yeah.
Joel Turner: And it’s, it is not like they come with names since they’re on Instagram it’s not a…
Becky Peltz: Yeah. You’d have to run ’em through some kind of an AI, yeah. Which we have, but…
Joel Turner: Yeah, I definitely thought about it. But so far this is working pretty well. But this is the big bit that [00:22:00] reduces all the comments down to one big string. So it combines all the comments and the description into just a large string that I can then use a RegEx to find any of the hashtags that I specified.
Becky Peltz: I gotta say, the code is so clean. I know. When I was looking through this, I was like, this is really great. It’s very easy to read.
Joel Turner: Thank you.
Sam Brace: Yeah, it really is. I, I don’t mean to just be like, Becky, I agree, but oh my gosh. It it’s so easy to follow. So this is fantastic.
Joel Turner: Thank you.
Becky Peltz: I guess this is when a designer starts coding, they know how to make the code look good.
Sam Brace: Yeah, that’s a good point.
Joel Turner: Been working on way too many projects where I go back to my own code six months later and have no idea what it does. So, it’s nice to document it all. These are the RegEx’s for all of [00:23:00] those hashtags that I’m pulling into the site, so I can just, say “anything that’s j-anything and ends in 2017”, which this is gonna be.
I mis-tagged a few photos. Some were added an extra letter at some point or an extra underscore, so this catches all of that. Make sure that it’s Joel M Turner, ABC’s 2017. And then same with all the others here.
Becky Peltz: Yeah, it’s nice to get those all in one place too. When you just have those scattered throughout your code, that’s pretty hard to find.
Joel Turner: So after that then we create the new timestamp and then the ID based on that. So it’s creating it with the timestamp of the the post, the created time of that post, and then using the Post ID from [00:24:00] Instagram. So if I ever need to go look up that image on Instagram I have that post ID right there. Which I’ve never had to, but just in case…
Becky Peltz: yeah.
Joel Turner: Kinda works out. And having the timestamp first allows me to keep that sort…
Becky Peltz: Kind of have like a bidirectional index there between Cloudinary and Instagram.
Joel Turner: Yeah, definitely. And then if we already have that ID in there we start to add the tags based on is this a new upload post that we’re adding?
Otherwise, if we already have it, then we’re just gonna add the new tags that we just found into the original tags. [00:25:00] So this just loops over all the posts and makes sure that we get all the tags into the posts.
Becky Peltz: Oh, because over time people are gonna be commenting and so you might pick up more tags to add?
Joel Turner: Potentially. Yeah. Or what often happens is I scroll through some of my posts and say, “Oh, you know, that one should be tagged this, or, something else.” I might add it to the featured or remove it from featured or something like that.
Sam Brace: Yeah. Yeah. And that makes sense. Absolutely.
Joel Turner: And then we do the then we send it up to Cloudinary. Once we have all those, and this is just using the upload function from the API. Yeah, just give it a few parameters that we defined in our [00:26:00] upload post and yeah. Always works so well. At first I was nervous because I was thinking I’ve got potentially hundreds of posts here that I need to upload.
Becky Peltz: Yeah.
Joel Turner: What you know is there no bulk uploader that, can handle this? When I was reading through the docs, everyone mentioned, oh, just use the upload function. It’s fast. It works for that. I was like, yeah. Oh, okay. It, can it be that fast and yeah it is.
Becky Peltz: That’s really good to hear. I know we have some situations where people have like thousands and thousands of things they need to migrate and we have to write, a, multi-threaded or kind of functions to do it. But how many would you guess you’re uploading here? Maybe a hundred?
Joel Turner: Yeah, probably. I think it gets up to 200.[00:27:00]
Becky Peltz: 200. So this, yeah. So it is fast. Yeah.
Joel Turner: Yeah, it, I was blown away by that. And again, I had a little catch here just in case, one of the uploads fails and I think I only ran into that once and it was when I before I had formed this correctly it was just a malformed request to Cloudinary.
Becky Peltz: And you’re running this in node with node type NodeJS.
Joel Turner: Yeah.
Becky Peltz: One thing I could call out here though is that they did make the V2 uploader a promise, so you can await it if you
Joel Turner: Oh, nice.
Becky Peltz: Yeah. Yeah. It was a, an improvement that they made. So that, yeah, you don’t have to wrap it. It’s good to see that you can wrap it too, and it still works. Just you don’t have to upgrade your code even though they upgraded the functionality there.
Joel Turner: Yeah. [00:28:00] I’ll have to look at that, that it’s a little cleaner to, to read for me.
Becky Peltz: Yes. If you just wait that you’ll, yeah.
Joel Turner: That’s awesome.
Sam Brace: And one question I have here, Joel, so I can see the overall upload processes taking place. It’s clean, it’s simple, it’s scalable from what I can see here. So if you decide to start illustrating every single day, this can handle the hundreds, if not thousands of illustrations. That’s gonna be coming from Instagram out of Cloudinary.
But one thing that I noticed when I was taking a look at your site is that you have certain transformations that you’re applying. To these various images. I think for consistency purposes, maybe for optimization sides of things. Talk to me about that. And also maybe where those transformations are being applied in the overall code you have here.
Joel Turner: Transformations as in…
Sam Brace: Like, I can see like you’re adding like f_auto to be able to optimize the …
Joel Turner: Oh, gotcha.
Sam Brace: And be able to resize it to maybe width 400 on the gallery view, but then the, like the carousel view, it’s at 700 [00:29:00] pixels width all of that detail.
Joel Turner: Yeah. And that kind of comes down to a, another great Cloudinary utility. I think Colby made it next Cloudinary.
Becky Peltz: For NextJS? Or, for Netlify yeah.
Joel Turner: Yeah. This one is the the wrapper around next image.
Becky Peltz: Oh, okay.
Joel Turner: That allows for Cloudinary URLs. And it, as soon as I learned about it, threw it in there because I had so many troubles getting it just right between next, next next image and the Cloudinary URLs.
Just mainly the width and height. It just never gave me the quality that I wanted necessarily. But then, but now using using that component it allows all the right parameters to go into the [00:30:00] Cloudinary URL. So we now we get f_auto q_auto and all the right sizes, all the you can even do responsive sizes pretty easily with that.
So you get the, the best of the both worlds. Next Image plus Cloudinary.
Sam Brace: Oh, that’s exciting.
Becky Peltz: That is really cool. Yeah, Colby’s done some really great work. Even like he put a plugin in Netlify to just add f_auto q_auto to everything, so using a fetch, so it’s like very easy to get that going. But this is another, this is next Cloudinary, isn’t it? Is that what it is?
Joel Turner: Yeah. And right now I’ve got it, I’m using the CLD image from Next Cloudinary. And that’s, I think the docs on that are …
Becky Peltz: The frontend SDK. Like the React frontend…
Joel Turner: Yeah.
Becky Peltz: Yeah.
Joel Turner: Exactly. Yeah. So this is [00:31:00] my website code now it’s on NextJS and this, the component’s a little weird.
I’m wrapping that CLD image with Chakra’s image just so I can apply. Chakra styles to it. Chakra UI is like a little component UI library that I’m using throughout the site.
Becky Peltz: That’s great though. So you can not only take advantage of Next Cloudinary to get the sizes and responsiveness, but then you can even wrap that in a, another styling type of UI. So that’s yeah. Component.
Sam Brace: That’s pretty cool. I honestly I feel like this is my first time really seeing this part, and this is what I’m taking away from this episode.
Becky Peltz: Yeah
Joel Turner: This was fun. Without, people like Colby sharing all the cool things, [00:32:00] and this podcast sharing all the things that you can do, I wouldn’t have gotten this exact flow down. So it’s, yeah, it’s nice to be able to keep optimizing, keep playing.
Becky Peltz: I think what I think Colby, in doing this with Cloudinary image, he made it almost like a data driven… a data-driven component. So rather than you having to learn all the details of Cloudinary image and all the functions and whatnot, you just pass in a few bits of data width, height, source, whatever, and he takes care of all that for you. So that is nice.
Joel Turner: Yeah. Yeah. And we can see how I’m implementing that here. Some of this is a little bit Next image and some is just for Cloudinary the width and the height the source are the big ones for Cloudinary. From there it handles all the others [00:33:00] which you can also add, different styles, different parameters that Cloudinary supports. And so all that can be added here which makes that really nice.
Becky Peltz: Yeah. That’s great.
Sam Brace: One more thing that I really love that you have in here is the placeholder. Like you’re doing a blur, and that’s coming from the fact that everything’s frontend and you’re doing that. That’s great. I love the fact that like you have like low quality image placeholders through that area.
I also really love the fact that you’re bringing in a lot of the details through the alt in here as well. This is, there’s a lot to like about this. This is fantastic.
Joel Turner: Cool. Thank you. Yeah, and part of the feature on this site, I’ll demonstrate. When you click on one of these, it comes up in a light box so you can get a little [00:34:00] bit bigger view.
And the other piece is the reason I have three different sizes on it is you can adjust the sizing of the grid. So can see these all.
Becky Peltz: That’s cool. That’s really neat. Now, what gave you that what component gave you that, that was light box, did that?
Joel Turner: Yeah, I created my own little light box component.
And and we can see that these are just slightly sized, larger than what I’m rendering. I’m at, but that allows for any kind of wiggle room mobile to desktop. But it, it adjusts the sizes based on which grid mode I’m in, which is nice. So if you want to keep it at the smaller grid mode, you don’t have to download the massive images.
Becky Peltz: Yeah. [00:35:00]
Sam Brace: And the nice thing I like about this too, Joel, is that let’s say that in time you decide to adjust the sizes for the light box. Let’s say that you want a four by four grid at some point or a five by five. It’s where, because you’re keeping the base original in Cloudinary, and then you’re just changing with size requirements based on what you have in your code.
You can always just declare a different size. Then it’ll transform it and make sure it’s optimally placed. So it, you’re future-proofing the ability to grow this grid as you so choosed with the way that you’ve done this. So this is very smart. This is very smart.
Joel Turner: Thank you. Yeah. This also allows for, say I wanted to showcase Instagram images that weren’t artwork, that wanted to focus on people’s faces and things like, Instead of having to, figure that out every time you just add that parameter, crop and…
Becky Peltz: Gravity face.
Joel Turner: Yep. [00:36:00]
Becky Peltz: Yeah. Nice. Wow.
Joel Turner: Makes it a lot easier if you’re really trying to dial things in.
Sam Brace: Gravity. Yeah, this is great. Yeah, this is really…
Becky Peltz: Yeah. Is this component available? Open source? Is this something? Check out.
Joel Turner: Let’s see. Outside of that, so those are the way that we render the images and here’s the grid that we adjust based on the input of the whichever icon you, you chose for the.
And then it’ll kick off this light box, which has another just same sort of image that, that we had there. And then a few other navigation pieces on the sides. And then, so after [00:37:00] we get our images up to Cloudinary, and it kicks off a new build. This whole site is static, so it’s doing everything at build time right now.
I might explore server side coming soon, but it should be pretty much the same flow. We have on the illustration page for GET static props. This is where it gets all the data that needs to be rendered on that page. So I’ve gotta function to grab all of those images that we just uploaded.
This is using the Cloudinary search API. So you’re just designating which folder you’re looking in and you want to sort by public id, that allows that timestamp piece that allows me to sort based on that. And then right now I’ve just got a [00:38:00] hard coded 800 just to keep it safe. I don’t have that many posts coming in yet, but one day…
Sam Brace: I like it. It’s aspirational, Joel
Becky Peltz: There’s a cursor too with that call. So if you ever need to like, you’re up to like 2000, whatever, you can grab a cursor and keep going. It’ll just keep going.
Joel Turner: Nice. I think that’ll be helpful. And then, yeah, you just specify that you want the tags to come back with all those images and yeah, it gives you this nicely shaped image response.
So you have so many fields that you could use if you wanted to off of this like looking through those just, the geeky part of me loves seeing all those stats.
Becky Peltz: Yeah. Yeah. [00:39:00]
Joel Turner: But for the display purpose I only needed just a few fields here. And then here we’re just adding these tags whatever we found.
This image we’re gonna add that image to the tag set that I have specified up here. This allows me to essentially have an array of images just for that tag.
Becky Peltz: So those arrays is like public ID or something of the images that
Joel Turner: It’ll be the whole image object. This whole object here.
Becky Peltz: Oh, got it.
Joel Turner: Just, so I don’t go look up those again, but that would be a nice optimization actually to have just the ID in there. But the same image might be in two different arrays depending [00:40:00] on if I tagged it both. So this gets returned to the page. And then from here I can just pass that data down into my gallery component.
And the selected images is easier to show whatever you select in here. Is gonna be pulling from one of those arrays. Now you can kinda look at different aspects of what these are. And there’s a kind of a bonus feature that is overkill for all of this. When you click on an image, I actually add to the URL the collection.
So that’s the selected group of images [00:41:00] in this case, letter clash and the index of that image. So if you want to share that with somebody, you can actually they just use that URL and it’ll pop up this image in the light box.
Becky Peltz: Oh.
Joel Turner: Kinda state management
Becky Peltz: Yeah, got all the data that they need there.
Joel Turner: Yeah.
Becky Peltz: That’s the nice thing about static sites too, is that you had to have these shareable links.
Joel Turner: Yeah.
Sam Brace: And I know you called it overkill, Joel, but I can see exactly why you would wanna do that because you’re putting all this time into this art. You wanted to be represented in the best way possible.
So it’s not only get to the exact piece you’re trying to show, but also in a nice format so that way it’s as big as possible so that way they can see all the detail you put into it. So I think that level of detail. Perfect. I totally agree with what you did there.
Joel Turner: Thank you. Yeah, and then that’s,[00:42:00]
I, I think that’s about it for the light box and the gallery there.
Sam Brace: I think this is good time for us to talk about the move, because one thing that we talked about at the beginning was we talked about going from like the concept of WordPress and then deciding to use Gatsby for the project. But I can see, and we alluded to it when we talked about transformations and the Next side of things that Colby helped with, but you moved from Gatsby to Next.
What was the decision making for that? It’s something that I think we’ve seen, not necessarily people do, but it’s where people are always deciding what should people use for static site generators or for site display. What was the reasoning for the Gatsby to Next move that took place?
Joel Turner: Yeah, that’s it didn’t come easily for me.
I love Gatsby. I [00:43:00] love how easy it made it to pull from different sources, pull ’em all together, get something up. A few factors started coming in. I’m primarily an app developer like web apps, so we use Next JS a lot, I wanted to get better with that. The issues that I was having with Gatsby, so many times when I load up my project locally and have different dependency issues and build issues like those kinds of things those were the impetus to move it over to Next JS.
But for websites, especially this website like mine Gatsby is amazing for it, and actually we have the whole WHO dashboard that our team built. That’s all on [00:44:00] Gatsby.
Becky Peltz: Hey, can you show us that? I love that site. That’s, its really cool. So this is your work site, right? You built this at work.
Joel Turner: Yeah. This is…
Becky Peltz: This was great in the pandemic.
Joel Turner: This is kind of an oddball for our team. We’re data visualization developers. And then this kind of came into our lap while we were early on in the pandemic.
Becky Peltz: This was important when Covid was really revving up and everybody was kind of needing to know where it was happening and how far away it was from your place, where you’re at.
Joel Turner: Yeah, definitely. Yeah, especially to see the trends and pinpoint areas of interest there.
Sam Brace: And so your team built this with Gatsby. That’s very cool actually.
Joel Turner: Yeah. Yeah. All of this was Gatsby has a lot of features, a lot of data. [00:45:00] This site has so much data that we’ve had to continually optimize in different ways because it’s multiple data points per day, per country, so it’s, it just grows so, so quickly.
Becky Peltz: I can see how GraphQL could help out when you’re dealing with lots and lots of data. Cause it’s gonna do a little filtering for you.
Joel Turner: Definitely, yeah. It makes it, especially on a page that shows all the data like a table
Becky Peltz: Yeah.
Joel Turner: That have everything showing up.
Sam Brace: I think this is good to point out because it’s where, yeah, you made a choice for your personal presence to be able to move it from Gatsby to Next, but it’s also pointing out that both solutions are fantastic for what you might need it for.
So it wasn’t like, you’re moving from a bad source to a good source. You’re moving from a good source to a good source that just had different needs and different use cases. So I love [00:46:00] this comparison.
Becky Peltz: I think we’ve seen a lot, we’ve talked to a lot of developers who use their blog as a place to test out something new or something they wanna learn.
So making that choice is not like condemning the thing, they’re leaving so much as saying, “Hey, I really wanna learn this new thing that I don’t know yet.” Yeah.
Joel Turner: Yeah, and sometimes, unless we keep creating multiple sites like our personal sites just kinda becomes that.
Becky Peltz: joelmturner.com one, joelmturner.com two. Pick your framework.
Joel Turner: Yeah.
Becky Peltz: But yeah.
Joel Turner: I, yeah, I ended up creating joelmturner.com dashboard just to pull in my stats from dev.to and Code Sandbox. One of the others just to play with NextJS and different variations of it.
Sam Brace: Yeah. Becky, this reminds me like I remember one of our initial DevJams episodes, we talked with Ryan Filler and he was talking about how he [00:47:00] moved from like from Jekyll to Gatsby to SvelteKit was constantly just moving and moving and moving.
So it’s where I agree it’s sometimes it’s nice to be able to have that personal presence to be able to test drive something before you try to do it professionally or try to do it at scale. That’s also a massive reason to try something else out.
Joel Turner: Yeah.
Becky Peltz: Yeah.
Joel Turner: Definitely.
Sam Brace: So Joel, so now that we’ve seen this and I’m inspired in many different ways.
First of all I think I’ve gushed a lot about the transformations, but it’s a, it’s where, but this is fantastic and I love the fact that you took something that was handmade, hand lettered, be able to have a digital output for that and be able to do something the way that you did it. So it’s a fantastic project and concept.
Where can people learn more about the work that you’re doing? Obviously you have your website, but is there any places that you’re continually contributing, maybe insights outside of the blog that you have there? Is there, are you [00:48:00] are active on LinkedIn or on Twitter or other places where can people learn about Joel?
Joel Turner: Yeah, primarily, Twitter is probably where I’m most active. I tend to read a lot and not post a lot, but sometimes I’ll jump in on conversations.
Becky Peltz: I post my wordle scores there. I read it a lot more than I write
Joel Turner: But outside of that dev.to try to stay a little bit active on there as well.
Sam Brace: Yeah. I would say the same for Becky. Like you’ve, you have a good growing dev.to presence yourself.
Becky Peltz: I like it there. It’s a real easy site to post on. Look things up, save things. Yeah.
Joel Turner: Yeah, definitely.
Sam Brace: Excellent. Joel, this has been fantastic. I really love this example here and of course we’re gonna point people to the blog post that you wrote where you detail everything there.
[00:49:00] I know you have active links to GitHub repos for people to be able to look at this and be able try to be able to learn from all the concepts that you took the time to learn from as well. So yeah, I really appreciate everything that you’ve done here.
Becky Peltz: I’m just, sorry we didn’t get to get into how you learned PHP while you were a dog sled guide.
Joel Turner: Wouldn’t recommend it’s slowly to learn but it worked.
Sam Brace: Yeah, I think it, it could be part two for sure let’s have Joel come back and talk about the way that he got to the, where he’s at with this. So maybe there’s a little bit of dog sledding adventures we can weave in, in, in a future visit.
Joel Turner: Good.
Sam Brace: Excellent. Excellent. Joel, thank you. Thank you again.
Joel Turner: Thank you both.
Sam Brace: Becky, there’s a lot to take away here. There’s a ton to take away here cause this is an amazing project. Obviously Instagram is a network that is widely used. We’re talking probably [00:50:00] millions and millions of users. So this is something where if you’re tied to development and Instagram, you’ve probably seen something there.
But what’s your overall takeaway from this?
Becky Peltz: You know, I’m thinking a lot about how, I hear a lot of talk about composable architecture and how you’re gonna pick pieces of a cloud, put your cloud stuff together so that it’s easy to compose. And when you think about an app like Instagram, it’s not really part of that composable world.
It does have APIs, but it’s not really intended. So moving your, what you own, your content into something that’s composable makes so much sense. And we’ve seen it here really well. That he was able to then make his move and Gatsby to Next that’s not an easy thing to do, but, how Cloudinary helped that with that.
Sam Brace: Oh and I love that yours is so much more articulate than what I was gonna say.
Becky Peltz: No, you were more articulate before.
Sam Brace: Cause like it’s one of those things where yeah, that, that’s an amazing reason for it. And you’re right, there’s a lot of conversations taking [00:51:00] place about composable architecture, headless architecture, all of these concepts.
Being able to have a single source of truth. So that way, regardless of what you use for your framework or what other systems you hook into it, your content is always there and stable is absolutely true. So I agree with that. My takeaway was just the fact that oh my gosh, Colby Fayock, like that guy is doing amazing things.
So it’s to say like Colby, of course is, and I think we’ve mentioned him practically on every DevJams episode, but he is one of our lead members on Cloudinary developer relations team or DevRel teams. And it’s where I think in past episodes we’ve pointed to plugins or we’ve pointed to just assistance he’s provided people in the Cloudinary community, whether it’s on Discord servers or on Twitter conversations. So it is to say, that if you need assistance with a lot of this stuff when it comes to image delivery, video delivery, management of us being able to work with certain files [00:52:00] we have go-to people and it’s between like myself, Becky, and others are willing to help, but it’s not just the two of us.
It’s not just the people that are on the support team either. So the lookout for help of people like Colby and others because they can really help guide some of the projects that way you don’t have to build everything from scratch or go hunting through repos. They can point you in the right direction.
Becky Peltz: Yeah, Colby is amazing. He’s always helpful, I know he is really busy, but he always gives me good pointers. He has this series on YouTube called Dev Hints. Very, great stuff to learn about Cloudinary in tiny bites. So yeah, we’re lucky to have him.
Sam Brace: Absolutely. Absolutely. So I think at this point, let’s make sure that people have all the details about what to do after this episode, which of course…
First, go to joelmturner.com. This is where Joel’s whole entire web presence that we talked about in this episode happens to be. You’ll notice here that if you wanna simply go into the illustration grids and [00:53:00] light boxes that we showed, that’s gonna be straight at the illustration part of his page, so you can go ahead and take a look at all of the great work that he’s doing, bringing this content from Instagram onto his web presence.
Thanks to all of the work that he’s done and with assistance from Cloudinary. And if he does detail all of this inside of the blog post that he has, Instagram Cloudinary, as well as some of the things that we talked about, such as the move from Gatsby to Next. It’s all very well detailed, so it makes it frankly easy for you to follow along with the episode.
Once this is in a recorded format, you have a chance to follow along probably side by side with something like this. And to point that out. For those of you that are interested in further Dev Jams or Cloudinary podcast in general, all of those are gonna be found at cloudinary.com/podcasts.
And you can see not only all the episodes that we’ve produced, but also links to many of the places where you can listen and watch to the content such as the Cloudinary Academy. [00:54:00] YouTube, Spotify, apple Podcasts and Google Podcasts, and I can’t not feature this where I love this transcript feature that one of our team members and Nadin went and built where if you are simply just wanting to jump to a certain part of the episode, you have to click the timestamp and it takes you right to that, it’s fantastic.
So really easy to follow along with all of the conversations that are taking place. Now, also keep in mind that all of these podcasts, as I mentioned, they’re housed in the Cloudinary Academy. That’s all of the work that myself, Becky, and others at the company are putting into educating developers. On the many use cases that are available, with our APIs and the various SDKs that we support.
So please take the time to look at that at training.cloudinary.com and keep the conversation going at the Cloudinary community. You can see that we have it at community.cloudinary.com and it’s associated Discord server, but you can easily access directly from there. So before [00:55:00] I let everybody go, Becky, any final thoughts?
Anything that we wanna leave our audience?
Becky Peltz: No, just I’d say dive into some of this code. It’s really good. Very helpful, and get you on a good path.
Sam Brace: I agree. I completely agree. On behalf of everybody at Cloudinary, I’m also gonna say on behalf of Joel, because we, he probably would say so himself, thank you for being a part of this episode.
Thank you for listening and watching DevJams and being interested potentially in Cloudinary, and we hope to see you at the next. Take care everybody. We’ll see you soon. Bye.
2023-05-11
Data and Content Orchestration Across All Channels
CEO of Consica.ai Sana Remekie joins Sam and Maribel from Cloudinary in this MX Matters episode! They discuss the concepts and growing opportunities around data and content orchestration, explaining how to manage, analyze and deliver information across different spaces in your organization. Our hosts and guests also dive into details surrounding headless and composable architecture, explaining some ways to connect disparate systems with APIs for digital experience orchestration. If your content and data are siloed in legacy backend systems, especially associated with imagery and videos, this will be an MX Matters episode you won’t want to miss.
Sam Brace: [00:00:00] Welcome to MX Matters. This is where we talk about the trends that are affecting the visual economy. That could be tied to e-commerce, that could be tied to website optimization, basically anything that is affecting the way that images, videos, and digital media are being used within many different channels in many different spaces.
My name is Sam Brace and I am the Senior Director of Customer Education and Community at Cloudinary. And joining me for this episode, and luckily for many episodes of MX Matters, is Maribel, who is our technology partner manager. Maribel, it’s great to have you here for this conversation.
Maribel Mullins: Thank you, Sam. Thanks for inviting me.
Sam Brace: For this conversation, we are joined with Sana, who is the CEO and co-founder of Conscia. And there’s a trend that we’ve started to see emerging in the overall digital marketing, digital outreach space that’s called data and content orchestration. [00:01:00] And if you think about an orchestra, it’s where you have violins and you have cellos, and you have all these amazing instruments.
They’re all coming together to make this beautiful sound. And I think that’s what data and content orchestration ultimately is. But instead of music, we’re now talking about digital content and digital data that is there to be able to come up with some way to orchestrate it. But we have heard this term floating around through various conversations.
It’s even mentioned at previous MX Matters podcasts. So now we wanna bring on the expert as someone that really understands what’s happening with this overall space since her company, Conscia, is directly tied to it. So with that said, Sana, welcome to the program.
Sana Remekie: Hi Sam. Hi Maribel. Thank you so much for having me here.
Sam Brace: Let’s just dive straight into it. What is data and content orchestration?
Sana Remekie: So I think Sam, you actually did a pretty good job defining what orchestration actually is in the context of music. And you’re absolutely correct. You’re really applying that same [00:02:00] concept of bringing different types of music and different types of instruments together in an orchestra, but applying that to data and content.
So when you’re thinking about large enterprises, let’s talk about enterprises upward of 1 billion in revenue. You are talking about enterprises where the data and the content is sitting in a bunch of different systems. They’re sitting in a lot of different silos. And in order to create digital experiences, what you need to be able to do is connect the dots between the data and the content from a lot of different systems so that you can build compelling, unified experiences for your customer.
Now, just to clarify, there is a slight difference between data and content. The way we speak about data and content, they’re two different things. Content is essentially anything that you are displaying to the customer or presenting to the customer. [00:03:00] Not just visual content, but any kind of content.
Data, on the other hand, is anything that you are capturing about the customer. So in order to create experiences, you have to be able to connect the customer data to the content in the right context at the right time, so that what you’re presenting to the customer is relevant, based on who they are, based on what their real time intent may be.
Secondly, the other part of the term, which is orchestration. There’s a lot of confusion between orchestration and integration. When we’re talking about integration, what we’re really talking about is just two systems connected to each other.
In today’s world, in a composable world, or a headless world, I should say, two systems can be connected to each other via APIs, or they may be connected to each other based on some sort of event triggers. That is an integration between two [00:04:00] systems. When we speak about orchestration, there’s an element that is essential to it, which is there’s an involvement of a person, a human, or some sort of decisioning that needs to be considered in order for two systems to be connected to each other.
So a human being essentially in our case, is going in and deciding how to use customer data in a very specific context to present the content to the customer. So somebody needs to be orchestrating all of this. It’s not being orchestrated on its own. There’s a decisioning element, there’s a human element to all of this, which makes integration and orchestration very different.
Sam Brace: That’s actually very, very helpful. Going back to that music analogy that I gave at the very beginning. Think about the person that is doing the overall content orchestration. They’re like the maestro. They’re the ones that’s putting everything together, [00:05:00] helping to know when the violins come in and the cellos come out.
So it seems to be the same way. So you wanna have someone that’s at the helm of the overall orchestration efforts when it comes to data and content. It’s not where we have systems that are just automating this overall effort together.
Sana Remekie: That’s exactly it.
It’s not happening on its own. Somebody’s doing it and you need to empower the right people to do it as well. So you need some sort of tooling and some processes in place where empowering the decision makers, the subject matter experts, and the business user essentially to present the right content to the customer at the right time. And that is orchestration.
Sam Brace: Now I know when we are talking about this overall concept of data orchestration, content orchestration, I like the differentiator that you shared there about why one is separated from the other. It’s data orchestration and content orchestration cause they’re two different things.
But I’ve also heard conversations about digital experience orchestration [00:06:00] and it doesn’t seem as necessarily as finite as data and content of that area, but maybe it is. What’s the difference maybe between digital experience orchestration and data and content orchestration?
Sana Remekie: So orchestration is just about giving the control to somebody to do something with data and content.
When we talk about digital experience orchestration, we’re contextualizing that conversation. What we’re saying is that we need to orchestrate this data and content in the right context in order to build digital experiences. So that is where the differentiator is. It’s basically contextualizing data and content orchestration for the purpose of building digital experiences.
Data and content could be orchestrated for other reasons as well. Sometimes you want to orchestrate data and content simply to keep two different systems in sync with each other for an operational reason, but that may not have anything to do with building a [00:07:00] digital experience. When we talk about digital experience orchestration, what we’re saying is we’re giving that control to the marketer, to the business, to connect the dots between the data and the content in the right context for the purpose of building an experience that makes sense for the customer.
Sam Brace: What would be an example of a digital experience? Maybe I’m booking travel online. Would that be considered a digital experience? Or maybe I’m purchasing new shoes online. Is there any areas that act as qualifiers of when something would be considered a digital experience for the orchestration?
Sana Remekie: Yeah, so digital experience can happen on various touchpoints throughout the customer journey, or it may not even be a customer at all. It could just be a user, like an employee of the company. So anytime a customer or a user is interacting with some digital technology, some digital interface to consume information, to make decisions about something such as a purchase, that is all types of digital experiences that we’re talking about. [00:08:00] That could be through the web interface. It could be the mobile interface, it could be the kiosk screen within a store, or a branch of a bank. So all of those are examples of digital experiences.
Maribel Mullins: And you mentioned orchestration, you were talking about how that’s the piece where you’re having people make that human decision of whether to bring the data or the content up. So do you feel that most people are struggling with understanding that? Maybe they don’t wanna automate that process? Or are you quick to see that people want to automate the process for orchestration?
Sana Remekie: No, that’s a really good question. So, I’m gonna go back to the talk about headless and composable and how that ecosystem lends itself so nicely to this new concept of digital experience orchestration.
So when we moved from the traditional DXP world where all of the data and all of the [00:09:00] content was sitting inside this one system, we took for granted that the marketer is gonna decide how experiences are gonna be presented to the customer. They would go log into this one system, one screen, and they would essentially orchestrate the experience within the walls of that DXP, but that was very much limited to the web experience for the most part. Sometimes they would be orchestrating the experience for mobile as well, but only when mobile was built based on some sort of web view and not a native mobile app. So the reason why we moved into headless and composable was because we wanted to provide that flexibility to build all types of experiences on all types of screens to our customer.
Now, in that transition from DXP to headless and composable, what ended up happening is that your data and content essentially became [00:10:00] siloed and your business user no longer had the choice or the empowerment to really present a certain type of experience to a customer at an operational level.
So on a day-to-day basis, they couldn’t just go into one screen and say, Hey, I want today for this campaign and for this type of person, I wanna show them this type of content. What instead they had to do was go talk to the developer, the front end developer, essentially, who is responsible for building that experience for that specific touchpoint, and let them know what their requirements were on a day-to-day basis.
And then they would go and hard code that experience for the customer. Now you can just imagine how many problems there are with that. So the discipline of digital experience orchestration is essentially rising because the business users and marketers are getting frustrated that [00:11:00] they’re not able to orchestrate these experiences on their own.
They need to be autonomously orchestrating these experiences at an operational level. So this is giving back the control to the right person, the person who understands the customer, who understands the content that is there to be presented to the customer. And they can do that in the moment of need, and they can do it on an ongoing basis instead of having that reliance on developer. Going back to the conversation of integration, what the developer is essentially doing is integration. They are pre-specifying all of the logic that needs to be put in place to connect this dot to that dot, and the experience becomes very static.
By empowering marketers to do this and business users to do this, you are giving them the agility, the ability to do this on their own and keep modifying the experience as they wish based on[00:12:00] the campaign that may be in place today or the type of person that’s coming in, or what their context may be.
Sam Brace: Now thinking about this, it seems a lot like ways that you would wanna connect the dots. I have this data about this user, this customer. I have this content that may align to that. That feels to me like a lot of the conversations that I’ve had about content personalization. Is that part of this effort or is there distinct differences between a content personalization effort and then what would be happening with orchestration?
Sana Remekie: So the way I see it is that content personalization is a use case of orchestration. So it’s a subset of orchestration, but you could theoretically have other use cases that fall into digital experience orchestration as well. Personalization definitely is one of the big ones because you have CDPs like Segment for instance, that are holding [00:13:00] onto customer data and you have CMSs like Contentful that are holding onto content.
So in order to personalize the content that is sitting inside the CMS, you have to be able to activate the data that is sitting in the CDP at the right time. But again, personalization is a use case. Digital experience orchestration is more of that overall capability of showing the right thing to the right person at the right time. It could be based on locale, it could be based on geography, it could be based on device. It may not be specific to a person at all. It could just be a campaign that you are running. So what you’re really doing is managing who is seeing what, when and where, and not just constraint to the use case of personalization.
Maribel Mullins: Is experience orchestration the same thing as like an omnichannel experience? Because I feel like I hear people say that synonymously.
Sana Remekie: Yeah. A good experience orchestration platform [00:14:00] should allow you to build omnichannel experiences. A lot of times people confuse digital experience orchestration with something like digital experience composition.
When we’re talking about digital experience composition, we’re specifically talking about, at least at this day and age, we’re specifically talking about the digital experience on a web framework. A React framework, a Vue.js framework, a Next.js framework. So you’re talking about server side rendering and client side rendering, and all of those web related concepts.
Digital experience orchestration goes beyond just the web. It allows the marketer to control the entire customer journey and not just be limited to the web. It’s not about just a visual composition of the page. So the concept of page is not really there in digital experience orchestration.
It’s an experience that you are managing. And that experience could be on the screen, [00:15:00] it could be on a webpage, it could be on the kiosk, it could be anywhere. So digital experience orchestration has to be completely headless in order for that to happen. That means you have to interact with the DXO or digital experience orchestration platform through an API, and you have to be able to receive a structured response that can be presented on any screen using that API response.
That would, in my mind, be the primary difference. You’re controlling who sees what, but not necessarily how exactly the page is laid out or the web. You know, here’s the CSS for the title versus the description. That is the presentation, the styling of, and the layout information that digital experience composition tools are primarily responsible for owning.
Whereas with DXO, it’s more about what you’re showing to the customer, not exactly how it looks and how it feels.
Sam Brace: One thing that [00:16:00] I have a question about, cause we’ve touched upon it a few times that we’ve been talking so far, about headless and composable architecture. And we’ve had many episodes about this, so we don’t need to dive into what it is and all the differences.
What I wonder is like some of the things that are tied to this overall orchestration effort, does it require it to be tied to a headless and composable stack, or could it be where if I have legacy systems, like, and I’m not saying these are exactly legacy, but let’s say like I have a Salesforce instance and I have a WordPress site, and none of those are necessarily headless or composable by design, but could I still do content orchestration linking those types of systems together? Or does it need to be something where truly the front end has decoupled from the back end, like the way, like a typical composable architecture stack would be?
Sana Remekie: That is a really, really good question and it’s an area of great debate I would say as well, in terms of how to handle legacy systems within a composable stack. Do you need to completely make your stack a [00:17:00] MACH or composable stack, or could part of that stack still be legacy?
Like how best to make legacy systems play nice with the overall composable ecosystem. So I am a true believer that organizations aren’t ready to fully move off of legacy systems. It’s not an overnight shift. A lot of times organizations take on an initiative to build or implement a composable technology simply for a brand new experience that they wanna roll out rather than change everything about their organization.
A DXO should be able to connect to a legacy system. Now, I say that with some caveats. One is the legacy system needs to be able to have some API that delivers some sort of structured response. That I would say is a requirement. Some legacy systems don’t have that in place at [00:18:00] all.
So what we’re seeing pop up within this space is this ability or this idea of encapsulating these legacy systems inside some sort of a caching layer or a modernization layer that has APIs that expose the rich data that is sitting in these systems without actually replacing these systems. So there are a few options within the ecosystem that provide that type of flexibility. If I were to name a few of them, for example, Netlify just came up with Valhalla, which is a content hub that is able to take the data from these older systems and expose it. Conscia has its own digital experience graph, which also syncs the data out of these systems and makes it available to downstream experiences as API responses essentially.
So it’s the same kind of idea. You’re encapsulating your legacy system and you’re not [00:19:00] replacing it. You’re just modernizing your existing stack.
Sam Brace: And I love the fact that like you and as well as Netlify, they’re addressing this because I think you’re right. We can’t fully abandon all of the systems that we have put into place and say, we’re just going headless today, because it’s just, no, that’s just not possible. So I think it’s where being able to come up with intermediary tools to say, we can make this possible.
Maribel Mullins: Yeah. And you pointed out something great in the sense of you need to be sure that the legacy systems have APIs exposed, but what other things, if somebody were to take this on that they should consider? Just because it seems like they’re doing not an overhaul, but like a restructuring of like how they’re presenting things.
Who should be the stakeholders in this as well as what else should they consider when trying to start a whole experience orchestration initiative?
Sana Remekie: There are a bunch of considerations. I think overall, in order to just implement composable and headless technologies and going down that path of [00:20:00] composability, it requires a certain level of digital maturity within the organization. What we see a lot of times is that organizations are very siloed, where each department starts their own initiative to build out a new site, for example. Like a large organization may have 200 different sites each built on different backend systems and different technologies altogether.
So when you’re moving down the path of composability, and then in essence, digital experience orchestration, there needs to be some higher level governance over the initiative. There needs to be this idea of reuse. You don’t want to keep reinventing the same wheel over and over again because what something like a DXO allows you to do is to do exactly that. It’s able to source content from all these different systems. It’s able to reuse and redeploy that content in whatever channel or whatever touchpoint. But that type of an [00:21:00] initiative requires leadership to understand that this is a new way. We’re gonna do things right for the first time, and it may not be an overhaul initially, but there has to be that culture change, a change in direction essentially that comes from the very top. And once that decision is made, it doesn’t mean that overnight you’re gonna have all of those systems, those 200 websites, all of a sudden totally composable. That’s not gonna happen.
But what can happen is that slowly one website at a time, or maybe you start with a new website that you’re about to build or a new digital touchpoint you’re about to build, you start with that to make that composable, and then others get inspired by what you’ve done, and they want to start to take advantage of the foundation that you’ve really laid out.
And so piece by piece, you are impacting that change across or affecting that change, I guess I should say, [00:22:00] across the enterprise.
Sam Brace: You’re touching upon something that I’ve definitely noticed as a trend is you’re talking about siloing and it continues to happen across the enterprise.
And frankly, with a lot of organizations where you have a CMS, you might have multiple CMSs, you have a PIM system, you have a DAM system, you have CRM systems with many different departments that are putting in various types of data. Why is this happening? I mean, obviously what Conscia is doing is it’s addressing the situations there…
Sana Remekie: You know, it’s funny, I’ve actually spent a lot of time thinking this through, like what are all of the different factors and considerations within the organization that make this happen? So one of them could be, for some organizations, it’s just the tools that they’re used to.
As the organization grows, as the number of departments increase, the people that you bring in have some sort of affinity to certain technologies, and they have certain relationships with certain vendors. So they say, all right, I’m just about to [00:23:00] build something new here. Let me show everybody that I’m gonna use this technology that they’ve never used before, which I have used before, and how that’s gonna help them achieve things faster and it’s cheaper and it’s better, and all those types of things, right? They have enough power to essentially convince the leadership that they should give this new tool a try, and that happens in large organizations, they have the money. So that’s one thing. So it’s money is not really the gating factor.
They just want speed, right? And so if you want speed, then you gotta use tools that you’re comfortable with. And so that would become the argument from a leadership standpoint that okay, let’s just use what makes sense for you.
The second thing is, as brands buy out other brands, so, these brands already are using certain technologies.
And you can’t, again, for the same reason, you can’t go from monolith [00:24:00] or legacy to composable all of a sudden, even if the brand that is buying out these other brands, even if they wanted to enforce some sort of a standard way of using technology that takes many years and it causes a lot of disruption.
So they let these smaller brands that they’re buying just do what they were always doing and act autonomously and not be consistent with the mothership all the time as well.
So you get the gist of where I’m going with this. It’s more about the people, the process and the change management that is so difficult within these larger organizations.
It’s much harder to turn a large ship. We all know that if it’s a small company, 500 million or less, you know, few websites, you can do a quick overhaul maybe within a year you are able to do that, but not with the larger corporations.
Sam Brace: One thing that you’re touching on that I hadn’t thought about, but I could see like almost being like a cycle that would happen is, let’s say you have a [00:25:00] company and they go through a process of saying, okay, we’re gonna go through data orchestration, we’re gonna do the DXO the way that we want it done, and then they buy a new company or they do a merger and acquisition, and then it’s almost like we’re constantly stepping backwards cuz they may be on monolith systems.
And so we’re constantly having to go backwards to bring them back up to what, as you said, the mothership has. So, right. There’s no way to ever be fully headless if you’re continuing growth, if when you’re thinking of it from an M&A perspective.
Sana Remekie: Yeah, it’s like two steps forward and one step back, in a sense. But I think that having a proper process in place to standardize the way in which experiences are built gives you that platform for future innovation. So if you do need to incorporate other brands into this new way of working, what the DXO essentially provides is an agile way to do that transformation on an ongoing basis [00:26:00] because it can work with legacy systems, it can work with headless systems as well. And that orchestration layer in the middle essentially can actually standardize the responses that are coming from backend systems. Say you have a CMS like Contentful in one place, and Sanity over here and Storyblok over here.
The DXO is able to take the data that comes from each of these systems and standardize it to an output that your front end needs or as an organization that you decide should be your standard API response so that anytime you build any new system or any new digital experience, doesn’t matter what your backend system is.
In fact, it could be multiple until you decide to standardize for other reasons. Like the other reasons could be that you wanna save money on your contracts. The other reason could be you wanna train the staff on all of the same tools. But from a front end [00:27:00] standpoint, if we could essentially standardize what comes out from the DXO, you don’t have to change the front end ever, regardless of what the back end may be.
Sam Brace: I think it’s kind of neat because like one thing that we say a lot of Cloudinary is that we want Cloudinary accounts to be ultimately the single source of truth for where all of your images, videos, digital assets should be. So that way if you decide to link it to a CMS, that means the whole team has access to this, and then it’s just with the web output or the mobile output.
Sana Remekie: Right.
Sam Brace: And it sounds like what we’re saying is that a DXO effort should be the single source of truth for all data and content because they may live in so many different places across the enterprise, whether it’s legacy or whether it’s headless, they’re just in many places. So it’s now, as a marketer, as an orchestrator, I can go to one space and know where everything happens to be.
Sana Remekie: Yeah. Because a DXO essentially connects to all of your backend systems, [00:28:00] right? And it connects to them in a very standard way. So you’re not coupling the DXO to the front end to the backend. It’s a very flexible way, a very decoupled way of connecting to these backend systems.
It’s through configuration. No code whatsoever should be allowed in that layer. It has to be a zero code layer, because as soon as you add custom code in that integration process with those backend systems, what you’re essentially doing is you’re creating a coupled system. And so we are very big proponents of staying away from any kind of custom code to build those types of relationships with backend systems as well.
Maribel Mullins: And along those lines, like I have been seeing more CMSs like trying to go into this orchestration capability. And I’m not sure if it’s the same in the sense that, like you hear that they’re trying to do the federation and as you mentioned, they’re trying to build as many integrations as they can to be able to pull content and keep them as the main content management [00:29:00] system and make it sticky.
And so I guess like how does that differ from what you’re trying to achieve?
Sana Remekie: This is such a controversial topic and I love it. This kind of goes back to what I said about what’s the difference between data and content orchestration versus experience orchestration. So copying and pasting data from one system to another, that is syncing of two different systems, which a lot of organizations that I’m actually speaking to right now are doing, cuz they didn’t have a way to dynamically assemble the content from two different systems together.
So for example, a CMS may pull in information from a product information management system. That’s because the content managers want to see the price and the inventory and this and that so that they can plug that data into a promotion for the product that they’re building within the CMS. It is orchestration [00:30:00] to some degree cuz you’re syncing the data between these systems.
But it also creates a problem of duplicating content over and over again in multiple systems. Cuz if you look around the organization, if you look at the example of an organization using Strapi as a CMS in one place, and Contentful as a CMS in another place. Essentially, what you’re gonna do then with that PIM to CMS connection, is you’re gonna duplicate that to all of those backend CMSs.
Instead, what we’re suggesting is you don’t do that and you let all of that data and content come together from the PIM and the CMS or wherever else dynamically through dynamic rules. You say that I’m gonna take the pricing information from the product and I’m gonna plug it into this price tag on the CMS side, but I’m gonna do it in the DXO [00:31:00] and not have to duplicate that data as well.
It’s absolutely happening right now. Most organizations in fact, are doing that today, and most CMSs are extending their capability to orchestrate, quote unquote orchestrate the data from other systems into their systems.
Because everybody wants to be the center. Everyone. PIMs wanna be the center. E-commerce systems wanna be the center. CMSs wanna be the center. The reality is, in a composable world, there is no center. There’s a lot of data sources. You shouldn’t think about it as a center. You have to think of it as a way to connect all of these different systems together.
And they’re not all converging to the same point. The system that connects all the dots between systems should also be going in between two different platforms and not just talking to the front end from a central point as well. So I think this is definitely an ongoing conversation, and there are [00:32:00] some use cases where this concept of the knowledge graph plays out, where you may have data sitting in 15 different databases and backend systems behind the scenes, and there’s no visibility from a business standpoint into what each of these different systems contain.
And in order to build experiences, you have to connect the data in a graph before you go and build out the front end experience.
In my opinion, anytime the data can be accessed in real time from another system using headless APIs, you shouldn’t be copying and pasting it anywhere. You should just get it from where it is.
A perfect example actually is Cloudinary connection into digital experience orchestration. The way we built the connector to Cloudinary was that we’re not copying the videos and images out of Cloudinary and putting them into some other repository [00:33:00] before activating those in real time.
Instead, what we’re doing is we’re connecting to your APIs in real time and giving marketing the tools to select what video, what image should be displayed to the customer in a specific context, but also how do you want to transform this image in real time. Conscia is not able to transform images. We are not able to go and overlay the video with some text or zoom into a specific part of the image, and we shouldn’t be able to do that. Cloudinary is good at that. So why would we pull the content out and copy and paste that content into another repository and lose all of that powerful capability that Cloudinary has to offer?
It just doesn’t make any sense to me to do that. When you have the APIs to deliver that content and deliver it in a dynamic [00:34:00] and transformative way, you should not be intercepting that in any way. You should leverage it to its full potential.
Maribel Mullins: Yeah. I love that because I feel like that in itself just made everything click, that everything’s in real time, and it’s not, as you mentioned, being copied over.
Sam Brace: One thing that I really have loved about the conversations about headless and composable architecture in general is it’s very humble in some ways…
Sana Remekie: mm-hmm.
Sam Brace: …where I’ve noticed a lot of cases where previous software conversations, let’s say 10, 15, 20 years ago, where they’re saying, we have to build it all ourselves cuz we’re the only ones that can know how to do it.
And it’s kind of saying, no, we recognize that there are vendors, there are people that are producing software that may know more about this than us, but we can work together through integrations and orchestration to make it all possible. So it’s not the chest beating where we’re saying, if we don’t do it, nobody else can.
It’s more of saying, yeah, let’s make it all possible because [00:35:00] we respect and like what you’re doing and how can we be like-minded in that way.
Sana Remekie: Exactly. I think that’s a perfect way of putting it, like humility within the ecosystem. I think that that’s the only way that it can work. In fact, and I see sometimes within the headless and composable players where people are trying to do too much, they are trying to expand to increase their pie.
And I don’t think that actually helps them or anybody else in the long term. I think it’s very important for each company to know what is their core value proposition? What is the one thing that they can do better than anyone else? Right? For Conscia, it’s orchestration. We know that this is something that we’re good at.
And we’re gonna keep making that capability stronger and stronger and provide more and more tooling to the business and the developers to really have everything that they need [00:36:00] to do orchestration. But if we start to say, Hey, you know what? We’re gonna start transforming images.
Forget about getting it from Cloudinary like we can. Why can’t we just get it from a repository and transform it ourselves in real time? There’s CDNs out there that you can put images on top of, but that’s silly. Now you’re expanding to something that is not what you know about. You have no clue how these images and transformations work.
And you are gonna go too broad, but not deep enough in any one single thing, and that’s what happened with the DXPs, right? They started off as a CMS. Then they started buying all these different tools like marketing automation and analytics and CDP and digital asset management and e-commerce and PIM. And then before you know it, they weren’t good for anybody. It’s like an average that doesn’t work for anyone.
What’s important is for each player within the [00:37:00] ecosystem to know who they are at the core and become better at that than anybody else. That’s the way to compete and not try to cannibalize the entire ecosystem by becoming everybody else, or be everything to everybody.
Maribel Mullins: How do you determine the ROI on this experience? And I also see where you take one step back and then two steps forward and so forth where you’re having to rebuild things. And then not just that, like I could see developers saying like, you know what, let’s just take a copy of that and do this our own thing, and I can see the marketing struggling and like, no, we wanna do our own thing.
Sana Remekie: So once the experience is out there, regardless of whether you built it as a monolithic application or a composable application, you would measure the ROI based on conversions or the average order value and those types of things. But the thing is if it took you a year to get there versus two months to get [00:38:00] there, that’s the differentiator. That’s the missed opportunity. So I think that when we make the business case for composable, it’s about agility, it’s about flexibility, it’s about speed to market, and it’s about the control that the marketing needs over the experience that they’re building, because every missed opportunity is costing them revenue that they could have had.
So it’s not really the individual metrics on, okay, I’ve now orchestrated my content and now the content sitting in the right place. So is this the right thing for the customer? And you’ll know that if the right number of people are clicking on it, assuming that you can achieve the same outcome from an experience standpoint eventually.
All things being equal, I think really the differentiating factor with going composable and doing things through orchestration instead of within silos or[00:39:00] by hard coding logic into the CMS or hard coding logic into any one specific front end, it’s really about how fast you can get there.
Does the marketer, if they wanna roll out a new campaign tomorrow, do they have to come talk to the developer to do it? And if they do, that means that they’re gonna take long or they have a backlog and they’re gonna take their sweet time. Now, what that means is that your competition could be doing what we’re suggesting here, and they would’ve rolled out that experience faster than you.
They would’ve responded to the market faster than you. And that’s where the loss is. So it’s more, I think the reason that organizations should be thinking about this is not so much about the increase in revenue, but the fear of lost revenue, if they don’t go down that path.
Sam Brace: And that makes sense to me because it really ties back to the whole need for this, because if you don’t have all the data, you don’t have all the content, there’s no way you can make actionable decisions and be able to affect a lot [00:40:00] of things that we’re talking about that are tied to ROI, like revenue that is gained or lost.
So, it definitely is where because you have all of the data, all of the content, you can now decide how you want to do things with it…
Sana Remekie: Quickly.
Given enough time, resources, and money, anybody can do it. A DXP could do it too eventually by copying and pasting things into the dxp and creating custom integrations and plugins and millions of dollars in development time. You could do it. I think it’s all a matter of how fast you could roll something out.
Sam Brace: That’s a good point. That’s a really, really good point.
So let’s say I’m a CMO or a CTO, and I’m listening to this conversation that three of us are having, and I’m saying, oh, this sounds great. I would love to be able to start orchestrating certain things within my org.
What’s the first step they should take? I mean, obviously I could just say like, oh, well you should go talk to Conscia.
Sana Remekie: That would be the right thing to do. I’m just kidding.
Sam Brace: But from a [00:41:00] more agnostic standpoint, what would be a natural first step for you to say, you’ve made a decision that you want to try this, or you want to do something about this. What’s the first natural step to go forward with it?
Sana Remekie: I think that the most important thing is to do your research on what are the tools and capabilities that are out there, look at various vendors that are offering this type of capability. See what you need within the organization. Look around and see how big of a need is it really for you to do this. Are you mature enough to do this, first of all? I think that’s the audit that first needs to be done, and it’s that introspection and that reflection on your own company and your own capabilities. Do you have a team that is able to grasp what is going on here?
If you don’t, then the first step really is to start to advocate and evangelize that change that needs to be made [00:42:00] internally and start changing the mindset. And once that mindset is there, and that will only be there through education and evangelism, that means you’ve already spoken to all the leaders within the industry.
You now understand all the various perspectives of how you should move forward. Then the next step is to start to make the change one step at a time and not try to boil the ocean. Look at a new initiative that you are about to roll out, a brand new digital experience and what you were planning to do with it. Is that something that you could build your foundation upon potentially? So you need to start with some sort of POC and fail fast. You gotta try a few different vendors, see what’s working, see what’s not working. The whole point of composable is that you should be able to replace things faster than buying a monolith and locking yourself into a five year plan of a million [00:43:00] dollars each year. That wouldn’t be a good idea. So that in my mind would be the first few steps. I guess I took the liberty to go to the next couple of steps as well.
Sam Brace: I think it helps anybody when they’re seeing like, okay, this is a playbook. I can understand this. That’s the one reassuring thing that I would feel as if I was in a new org and we’re going down this path, is that others have done this. This isn’t like brand new, such bleeding edge territory that you’re the first one to make the jump.
It’s to say there’s others that are doing this and being successful with it. I mean, Conscia has customer bases that are doing this now…
Sana Remekie: That’s a really good point. So look at the customers that are doing this today and share the stories, share the concerns, and see if they can find themselves in an existing organization that has very similar challenges as they have.
I wouldn’t say that at this point that there is a playbook fully because it is still an emerging market. It’s still very new. [00:44:00] However, any organization that wants to leapfrog their competitor, a competition has to catch the wave early. If you wait till all your competitors are already doing it, then you are already way behind.
So you gotta try something new, because what’s happening right now is it’s not working. You’re not moving fast enough. So it doesn’t hurt to give something new a try that looks pretty promising, at least on the surface.
I’d be realistic about the expectations with the customer as well. There’s so many factors that could affect the initiative. Again, your own digital maturity, your ability to accept change. All those things could impact. And it may not even be the methodology that is failing. It could be the way you adopt it that fails and you’re just not ready, right?
But you have to take the first step if you’re gonna make any change and move in the right direction.
Sam Brace: Makes perfect sense. So, we have this great [00:45:00] conversation here and hopefully people agree that it’s great that are listening to us. But in terms of where people should be going for more information about this, so like when you were talking about go do your research, go figure out, is there any like go-to spaces that are really helpful in understanding this emerging space of the DXO, the understanding of orchestration in general?
Sana Remekie: It’s a little bit scattered, I would say, but there are definite industry leaders and thought leaders within the space already that you should be following. My go-to is LinkedIn and then from that I branch out to a lot of different hosting platforms where there’s articles and blog posts about orchestration generally, or digital experience composition.
And I think the other place is also the MACH Alliance, the website itself is also a host to a whole bunch of blog posts and articles, thought leadership articles about composability and [00:46:00] building MACH ecosystems generally as well.
So that would be, I think, another, uh, resource that people should definitely give it a try.
Sam Brace: So if you’ve enjoyed this conversation, and as I said earlier, hopefully you have, but that means take the time to check out previous episodes and future episodes wherever you’re listening to this podcast, we’re gonna be in that location, but also many that includes Apple Podcast, Google Podcast, Spotify.
We put content up on YouTube, even our own Cloudinary Academy. So make sure you’re taking the time to check out all of the latest and greatest conversations that we’re having with thought leaders like Sana and others on future MX Matters episodes. And of course, if