AI Chat Widget for EuroMillions — Build Summary

🧠 Building a Smart & Responsive AI Chat Widget for EuroMillions Predictions

From design chaos to production-ready elegance

Over the past days, I developed and refined an AI-powered chat experience for a EuroMillions prediction platform, aimed at offering playful, user-centric interactions that guide visitors through number generation — using OpenAI and Firebase.

It started with a simple goal:
🎯 Let users receive interactive EuroMillions predictions via a friendly, animated assistant.

But the journey revealed a long list of small but critical issues that needed solving to deliver a great user experience across devices.

🔧 Key Issues & Fixes

1. Responsive Chat Box (Mobile vs Desktop)

Problem: The chat widget either overflowed or looked too small depending on screen size.

Fix: CSS media queries with dynamic layout:

  • Desktop: fixed bottom-right box (340px width)
  • Mobile: full-width, 80vh height floating card
  • Controlled with @media (max-width: 640px)

2. Broken or Conflicting Animations

Problem: AOS (Animate On Scroll) caused flickers and conflicts.

Fix: Replaced with native opacity, transform, and pointer-events using a toggled .open class. Smooth entry/exit, zero flicker.

3. CORS & Firebase Permission Errors

Problem: Silent failure due to TypeError: Failed to fetch.

Fix:

  • Added CORS support for both localhost and production
  • Handled OPTIONS preflight correctly
  • Used gcloud to make the function public:
gcloud functions add-iam-policy-binding kanscoachChat \
  --region=us-central1 \
  --member="allUsers" \
  --role="roles/cloudfunctions.invoker"

4. Typing Feedback UX

Problem: No indication that the assistant was responding.

Fix: Introduced a “🔮 Glazen Bol typt...” message during the OpenAI API call. Removed it after reply.

Bonus: CSS dot animation:

.dots::after {
  content: '...';
  animation: dots-appear 1.2s steps(4, end) infinite;
}

@keyframes dots-appear {
  0% { width: 0ch; }
  100% { width: 3ch; }
}

5. Duplicate IDs / Hidden Bugs

Problem: Multiple id="chat-box" caused erratic behavior on mobile.

Fix: Cleaned up DOM and validated uniqueness with:

document.querySelectorAll('#chat-box').length // should be 1

💡 Stack Overview

  • Frontend: Plain HTML + Tailwind CSS + JavaScript
  • AI: OpenAI Chat Completion (GPT-3.5)
  • Backend/API: Firebase Cloud Functions
  • Hosting: Firebase Static Hosting
  • Animation: Pure CSS + optional Lottie

📈 Outcome

  • ✅ Fully responsive
  • ✅ Fast and lightweight
  • ✅ Engaging step-by-step interaction
  • ✅ Secure backend logic with OpenAI
  • ✅ No frameworks or build tools required

If you're building something similar — an interactive AI experience for lead generation, gaming, or onboarding — I’ve solved the major friction points already. Feel free to reach out.

💬 Curious to hear your thoughts! Would you prefer a Tailwind-only component, a React-based upgrade, or keep it as lightweight as possible?

Comments