In this article, I'm not going to show you much code. Instead, I'm going to show you how you can build a holiday card collage, complete with a ribbon footer with text, a background, and 5 styled photos with rounded, colored borders in one line using the magic of Cloudinary's transformations.
This is way cool, so buckle up and let me show you how I built this URL-generating app for your holiday card-sending needs. You can try it right now here; it generates cards that look like this:
Maybe this tool will even save you some money as printing photo-quality holiday cards can get expensive!
Build an app, any app
I have been enjoying building Astro apps, and, let's face it, using Cursor makes architecting this sort of thing a real breeze. Use your favorite AI tool to craft an app that will allow you to upload five photos to Cloudinary, rearrange them, and generate a URL to build the holiday card.
💡 Here's a tip. If you are looking to quickly scaffold an app via prompting in Cursor or your IDE of choice, you can get better results by using two tools: ChatGPT to build the prompt, and Cursor to execute it.
My initial lazy half-baked idea sent over to ChatGPT:
what kind of demo could I build to create a holiday photo card maker for cloudinary
ChatGPT, of course, thought I wanted it to build an app for me, and went straight to scaffolding a Next.js app with code everywhere. A few clarifications later, after requesting Astro for use in Cursor...
create this as a prompt I can give to cursor
...ChatGPT generated a really nice, detailed prompt ready for building which you can read in full here
By having this kind of very detailed prompt, Cursor is able to build a perfectly reasonable app on the first try. Then it's up to the engineer to tweak it, redesign it, and add elements while keeping the core functionality of uploading and URL-building intact.
Add some extras and get ready to upload
I went ahead and changed the app colors for a wintry, cozy look, adding some falling snow, a popup elf with changing holiday messages (can you find him?), glowing lights, and a candy cane border, mostly borrowed from CodePen. Just because we use AI doesn't mean we can't continue to make interesting interfaces! And AI can help you do that, too.
After those fun things are complete, you can start making sure that you're set up to use Cloudinary's image upload and image transformation capabilities. To make this work, you need to ensure that you have some environment variables set up. Create an account on Cloudinary (there's a generous free tier) and grab your API keys from the console by clicking the "⚙️" gear icon in the left nav and selecting 'API Keys':
You want to add those keys to your .env file locally, and then make sure they're available on your hosting service when you push your app to the cloud. I use Netlify so I add these keys into the Netlify console before publishing.
PUBLIC_CLOUDINARY_CLOUD_NAME=<your cloud name>
PUBLIC_CLOUDINARY_UPLOAD_PRESET=christmas-collage
This app also needs what's called an 'Upload Preset', which is essentially a placeholder that helps your app figure out where your uploaded images should go.
- Set up that preset by clicking the 'Uploads' navigation link that's right under the 'API Keys' navigation on the left. This will let you set up an unsigned preset.
- Call it 'christmas-collage' (or something else, and make sure to update your app).
- Make sure you have a folder set up by clicking
Assets > folderson the left nav in the Cloudinary console. Call this folder 'collages'. - Also create a folder called 'holiday-assets' and add a collage background image and a background image for your ribbon element on the card. I used a white pixel image and a fancy holiday background like this:
Photo by JESHOOTS.COM on Unsplash
Watch the URL builder work
Now here's the interesting bit. Once you're done messing with your interface to make it look cute, take a look at the very clever way that your card is generated. First, you upload a series of 5 photos of your family to the app, and the interface lets you rearrange them into the order in the card that you want.
True story, my daughter asked me what the difference is between this and PicCollage, the answer being "Mom made it!"
The URL that is generated, packed with Cloudinary image transformations, looks something like this:
https://res.cloudinary.com/jen-demos/image/upload/w_1600,h_900,c_fill,q_auto,f_auto
/l_holiday-assets:jhi9cpio4ahxomhagwvs/c_fill,w_473,h_680/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_50,y_50
/l_holiday-assets:d9njoekpa1zzzepy2y5d/c_fill,w_473,h_426/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_563,y_50
/l_holiday-assets:nm9i3sjh6c3mkfj0ari1/c_fill,w_473,h_214/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_563,y_516
/l_holiday-assets:rg0c1ul7ux1gcgl8c2lr/c_fill,w_473,h_214/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_1076,y_50
/l_holiday-assets:d0brmcfuqfyzwtelsiyt/c_fill,w_473,h_426/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_1076,y_304
/l_holiday-assets:white-pixel/c_fill,w_1600,h_100/o_70/fl_layer_apply,g_south,y_20
/l_text:Pacifico_70:Our%20Family%20-%20Holiday%202025,co_rgb:000000/fl_layer_apply,g_center,y_380
/holiday-assets/collage-bg
Yes, that one line created this card:
Let's break down that one-liner.
Step 1: Set up the base “card” background:
.../image/upload/w_1600,h_900,c_fill,q_auto,f_auto/ ... /holiday-assets/collage-bg
-
w_1600,h_900– make the final image 1600×900. -
c_fill– crop/resize to fill that aspect ratio. -
q_auto,f_auto– optimize quality and format automatically (WebP/AVIF/etc). -
holiday-assets/collage-bg– this is the base background image for the card.
Step 2: Add the first photo (top left)
/l_holiday-assets:uzfzkx8d5xd0jr1jxzyo/c_fill,w_473,h_680
/r_25,bo_8px_solid_rgb:FFD700/fl_layer_apply,g_north_west,x_50,y_50
-
l_holiday-assets:...– load this image as a layer. -
c_fill,w_473,h_680– size it to 473×680, cropping to fill. -
r_25– rounded corners (radius 25). -
bo_8px_solid_rgb:FFD700– 8px solid gold (#FFD700) border. -
fl_layer_apply,g_north_west,x_50,y_50– apply the layer at the top-left, offset 50px from the top and left.
Add the remaining images, some taller than others and placed in different areas of the card.
Step 3: Add a semi-transparent footer bar
/l_holiday-assets:white-pixel/c_fill,w_1600,h_100/o_70
/fl_layer_apply,g_south,y_20
This bar uses a white-pixel asset as a tiny base and stretches it to w_1600,h_100 to form a strip which is o_70 – 70% opacity (semi-transparent). It's then applied at the bottom (g_south) with a small vertical offset (y_20).
Step 4: Finally, add the holiday greeting text
/l_text:Pacifico_70:Our%20Family%20-%20Holiday%202025,co_rgb:000000
/fl_layer_apply,g_center,y_380
-
l_text:Pacifico_70:...– create a text layer with Font: Pacifico in size: 70. Give it the text:Our Family - Holiday 2025withco_rgb:000000– black text color. -
fl_layer_apply,g_center,y_380– center the text horizontally and shift it vertically to overlay the footer.
In short, this monster URL
- starts with a festive background
- lays out five photos in a collage with rounded corners and gold frames
- adds a semi-transparent white bar at the bottom
- and writes “Our Family - Holiday 2025” in a script font on top of that bar
...rendering the whole card on demand in a single Cloudinary transformation URL. Really nice!
Tip: you can make edits right in the URL to change elements on the card - try adding your own family name and changing the border color.
Enjoy the results
You could save this image and print it for snail mail, or send it right away via email to the folks who are eager to hear from you this holiday season. And you did it in one line. That's awesome!
Try this in Cloudinary today, and get one more item checked off your holiday to-do list. Learn more about image transformations here.
Happy holidays from Cloudinary Developer Relations to you.






Top comments (0)