
- Home
- From my desk
- Building Sway: An AI-Powered Vacation App
Walkthrough of the site
There’s a unique thrill in dropping everything and diving headfirst into an idea. A kind of beautiful chaos that only a hackathon can deliver. That’s exactly what I did for the Next.js Hackathon, channeling my early-career energy into something that was part experiment, part nostalgic challenge—and 100% exhausting in all the best ways.
I hadn’t felt this connected to building from scratch in a long time. But five days in, my 37-year-old self started to feel it. The late-night coding marathons I once pulled off without flinching now came with consequences—fatigue, life interruptions, and juggling my full-time job, family responsibilities, and this relentless two-week sprint.
But here’s the thing: we did it. We made something cool.
🏆 The Challenge
The hackathon offered three categories:
- Highest Quality: Pixel-perfect design and obsessive attention to detail.
- Fastest App: Millisecond-level performance using cutting-edge Next.js features.
- Best Use of AI: Creative, functional, and well-integrated AI implementations using the AI SDK.
Our team went all in on the third.
💡 The Idea
We built Sway—an AI-powered travel and vacation recommendation engine.
The experience is simple on the surface. A user answers a few casual questions, and behind the scenes, AI builds context from those answers and any previous search history. From there, it recommends specific places to visit or rent—complete with names, summaries, and locations.
But we didn’t stop there. We took those AI-generated businesses and piped them into the Google Places API to validate and enrich the recommendations. This gave users meaningful extras: photos, reviews, price points, links, and more. They could save favorites or revisit their history in a neat, digestible format.

Open AI flow diagram
🧠 Smart Choices
We wanted speed initially, but AI’s compute demands quickly redirected our focus. With OpenAI, Google Places, and MongoDB in the mix, we needed clever ways to manage costs.
So we hacked it—literally.
We added breakpoints to API responses, grabbed the payloads, and saved JSON snapshots directly in the codebase. These snapshots served as frozen reference points during development and testing, helping us keep usage low without sacrificing functionality.
When running in "mock mode," Sway served those snapshots. With it off, responses were cached in MongoDB, avoiding repeated calls to services like Google Places for favorites or history.
⚠️ Gotchas
We ran into our fair share of “oh no” moments.
- Timeouts on Vercel's Hobby Tier: Our OpenAI calls could take up to 3 minutes, but the hobby tier only allowed 60 seconds. We upgraded to Pro and unlocked “Fluid Mode” (hello, 800 seconds!), but the upgrade flow was... let's say unpolished. Vercel, please let us opt out of that extra $10 observability fee next time.
- AI Bottlenecks: We were generating 80 recommendations—10 each for top picks, best deals, most popular, and most luxurious—for both rentals and destinations. Naturally, that took time. In a production world, this should be a background job with notification support. We just didn’t have the time to build it in.
- Clerk Authentication Woes: Out of the box, Clerk looked promising. But deep integration revealed strange inconsistencies between session identifiers. We ended up using user email as a consistent ID for querying the DB. Functionally fine—but not ideal. Next time? We'll probably skip Clerk.
- Next’s Image component: It insisted on preloading and hitting Google Photos hard, even with lazy loading and cache tricks. Rate limits became a nightmare. In hindsight, rotating 10 API keys might have helped—but, hey, this was a hackathon. Ain’t nobody got time for that.
🧰 What I Learned
Despite the chaos, I walked away with some new favorites from the Next.js ecosystem:
- Server Actions: This was the game-changer. Say goodbye to messy data fetching and Context API wrangling. You define server logic, call it from the frontend, and Next handles the rest. Clean. Powerful. Life-changing.
- Dynamic Grouping Folders: Next.js now lets you wrap folder names in parentheses ( e.g., (dashboard) ) to hide them from the URL path. A small thing, but it massively improved our folder organization and routing clarity.
- React's cache() Function: I’d used it before but finally got it. It helped us avoid redundant fetches during complex UI state transitions. It’s like useMemo but tailored for data loading and server-side rendering. Underrated gem.
- Prompt Engineering is Real: Writing a precise, exhaustive prompt for OpenAI took real effort. But when done right, it delivered. Even when results were sparse—like for remote regions in Alaska—the AI didn’t hallucinate or fabricate filler content. That was refreshing.

Screenshot taken from NextJS Documentation
🧳 The Prompt
Here’s a glimpse at the OpenAI prompt that powered our recommendations. It wasn’t just "find cool places"—it demanded structure, quality, and clarity. And it delivered.
Below is part of the query we used for Open AI prompting.
"You are a vacation and rental finder. Your primary function is to generate structured JSON output to help generate data for Google Places. I will send you a series of questions followed by answers to provide context. Based on this context, return recommendations in the following JSON format:"
📣 Final Thoughts
The results of the hackathon come out today. Whether we win or not, the process was incredibly rewarding.
I probably wouldn’t do another two-week hackathon anytime soon—it was a lot. But the timing couldn’t be better. I’m currently exploring new opportunities in the React and Next.js space, and this project proved (even to myself) that I’ve still got it. Even if I move a little slower than I used to.
Check out the project here. Poke around, explore the recommendations, and let us know what you think. We’d love to hear from you.
Project Sway was a group comprised of:
Check out the code in our repo here.
Last updated: 04/22/2025 @ 04:35 AM