When my good friend Renas Demir was planning his wedding, he asked if I knew of any service where guests could easily share their photos. Instead of pointing him to an existing solution, I offered to build something custom for them. The result was www.ayserenas.dk - a simple web app where guests could scan QR codes at their tables and instantly upload photos from their phones.
Wedding tables with QR codes allowing guests to upload photos instantly
Results
The wedding day was a complete success:
- 212 guests visited the website 📱
- 91 lovely memories collected 📸
- 1 happy bridal couple ❤️
Zero downtime throughout the event. Guests aged 20-70 uploaded successfully without help.
What It Needed To Do
Before diving into code, I mapped out what the app needed to accomplish:
Functional Requirements:
ID | Description |
---|---|
FR01 | Guests must be able to access via a QR code |
FR02 | Guests must input name before uploading photos |
FR03 | Guests must be able to upload multiple photos |
FR04 | The system must validate file types (JPEG, etc.) |
FR05 | The system must enforce a 5MB max per photo |
FR06 | The system must store photos securely |
FR07 | The system must show name with each photo |
FR08 | The couple must have access to a gallery |
FR09 | The couple must receive email notifications |
Most importantly, it needed to be fast, reliable, and simple enough for anyone to use - whether they're 20 or 70 years old.
How It Works
I built the app with Next.js 15, using React for the interface and Tailwind CSS for styling. For the backend, I used PostgreSQL to store photo information and Supabase Storage to host the actual images. This setup gave me fast loading times and the ability to handle multiple uploads at once.
The tech stack included:
- Next.js 15 for the web framework
- React Hook Form & Zod for handling uploads and validation
- PostgreSQL & Prisma for storing and querying photo metadata
- Supabase Storage for images
- Nodemailer for sending instant email notifications
The Upload Flow
When a guest scans the QR code, here's what happens:
- Land on the home page
- Click to upload CTA
- Enter their name
- Select photos from phone
- App validates files
- Photos upload in parallel
- Data saves to database
- Couple gets instant email
- Photos appear in gallery
The entire app runs on Vercel's serverless platform, which automatically scales to handle many uploads at once - perfect for when everyone's taking photos during the wedding.
System Architecture
Here's how all the pieces fit together:
Building the Upload System
The heart of the app is the upload endpoint. When photos come in, the system processes them efficiently by handling multiple uploads at the same time. Each photo gets a unique name, gets stored in Supabase, and its information is saved to the database. Once everything's uploaded, an email fires off to the couple with a preview of the new photos.
This parallel processing approach means that when guests upload several photos at once, they don't have to wait for each one to finish before the next starts - everything happens simultaneously, making the experience feel instant.
The User Experience
I kept the interface simple and clean. The home page greets guests with a welcoming photo and a clear call-to-action button.
The upload page has just two things: a field for their name and a button to select photos. Behind the scenes, it checks that files are the right type and not too large.
For the couple, there's a private gallery showing all uploaded photos in a grid layout, with each guest's name displayed alongside their contributions.
The gallery displays all wedding photos with guest names in a clean, responsive grid
Staying in the Loop
Every time a guest uploads photos, the couple gets an email showing who uploaded, how many photos, and small preview thumbnails. This way, even during the busy wedding day, they can see the memories being captured in real-time.
Wrapping Up
Building this app taught me that sometimes the best solutions are the simplest ones. By focusing on making photo uploads effortless, the app just worked - no complicated instructions needed, no technical support required on the wedding day.
The combination of Next.js, Prisma, and Supabase gave me everything I needed to build something reliable and fast. But the best part? Seeing friends celebrate their special day while your code quietly works in the background, capturing memories.