DEV Community

Cover image for I built a quiz-driven gift recommender (Next.js + Cloudflare Pages)
hao764
hao764

Posted on

I built a quiz-driven gift recommender (Next.js + Cloudflare Pages)

Most "AI gift finders" are a search box with a chatbot glued on. I wanted to build something different — a quiz-driven gift recommender that ranks real Amazon products by who the recipient actually is, not just keywords. I call it GiftHive.

In this post I'll walk through the architecture, the conversion tricks I learned shipping it, and the bits I'm proudest of.

The Problem

Picking gifts is emotionally expensive. You scroll Amazon for an hour, second-guess every option, and end up buying a gift card. Existing tools don't help because they optimize for keyword match, not recipient fit.

GiftHive flips the input: instead of "show me gifts under $50", you answer a 30-second quiz about the person (relationship, interests, occasion, budget) and get a ranked shortlist with explanations of why each gift fits.

Stack

  • Next.js (App Router) — SSR for fast first paint, RSC for product data
  • Tailwind CSS — design system + dark mode via CSS variables
  • Cloudflare Pages — edge-deployed, free tier covers the traffic
  • Amazon Associates — affiliate revenue model

The Funnel

The whole site is a 3-step conversion funnel:

  1. Landing page — exit-intent modal + social proof toasts prime the visitor
  2. Quiz — 30-second, one-question-per-screen flow, no login
  3. Results — ranked products with countdown bar and "X people found gifts this week" social proof

Every step has a single primary CTA. The exit-intent modal is route-aware — it only fires on / and stays silent on /quiz and /results so it never interrupts the funnel mid-flow. That bug cost me ~15% of quiz completions before I caught it.

Personalization Logic

Each quiz answer maps to a vector of attributes (interests, style, budget, relationship). Products in the catalog have matching tags. Ranking is a weighted score:

score = tag_overlap * w1 + budget_match * w2 + occasion_match * w3
Enter fullscreen mode Exit fullscreen mode

No ML model needed — a few hundred products and clean tagging is enough to feel personal.

Amazon Affiliate Integration

Every product link runs through getAmazonUrl() which:

  1. Checks if the URL already has a tag= param — if so, replaces it with ours
  2. Otherwise appends ?tag=gifthive08-20
  3. Falls back to an Amazon search URL if no product URL exists
export function getAmazonUrl(gift: Gift) {
  const AFFILIATE_TAG = "gifthive08-20";
  if (gift.amazonUrl) {
    return /[?&]tag=/i.test(gift.amazonUrl)
      ? gift.amazonUrl.replace(/([?&])tag=[^&]*/i, `$1tag=${AFFILIATE_TAG}`)
      : `${gift.amazonUrl}${gift.amazonUrl.includes("?") ? "&" : "?"}tag=${AFFILIATE_TAG}`;
  }
  return `https://www.amazon.com/s?k=${encodeURIComponent(gift.name)}&tag=${AFFILIATE_TAG}`;
}
Enter fullscreen mode Exit fullscreen mode

Every ASIN in the catalog is real and verified, so clicks register in the Associates dashboard.

Conversion Optimization

A few things that moved the needle:

  • Exit-intent modal with a 15-second arm delay so it doesn't fire on bounce-and-leave
  • Social proof toast ("12 people found a gift in the last hour") in gentle mode on results
  • Countdown bar that creates urgency without being sleazy
  • Dark mode matching the user's system preference — warm palette instead of pure black

Deployment

Deployed on Cloudflare Pages via wrangler. The default *.pages.dev domain works fine, but some startup directories (like BetaList) reject it as "free hosting" — something to keep in mind if you're planning a launch there.

What's Next

  • A/B testing CTA copy
  • Localized quiz for non-US markets
  • A "gift recipient profile" save feature

It's live at gifthive.pages.dev if you want to poke at the actual flow. Feedback welcome.

The bigger lesson for me was about placement: route-aware components beat global components. A social proof toast that fires on every page feels spammy; one that only fires on /results feels like proof.

If you're building a similar funnel, the patterns worth copying are the route-aware exit modal, the weighted-score ranking, and the affiliate-tag-stripping helper. The full codebase is small enough to read in one sitting.


Disclosure: This post contains Amazon affiliate links. If you buy through them I may earn a small commission at no extra cost to you.


P.S. — GiftHive just launched on ProductHunt today. If you found this post useful, an upvote would genuinely help: GiftHive on ProductHunt.

Top comments (0)