Building a Full-Stack AI Product Recommendation System (and Solving Real Deployment Issues)

I’m an Incoming SDE Intern (.NET) focused on improving my skills in C#, JavaScript, and SQL. I share what I learn through simple explanations to help other beginners grow in their coding journey 🚀.
By Sandipmryadav
Most so-called “AI projects” stop at a chat screen or a local demo and never make it to the real world.
I wanted something people could actually open in a browser and use.
So I built and deployed a full-stack AI Product Recommendation System, powered by:
React (Vite) frontend
Node.js + Express backend
Google Gemini API
Frontend on Vercel
Backend on Render
Live app: https://product-ai-recommender.vercel.app/
GitHub repo: https://github.com/sandipmryadav/product-ai-recommender
This post breaks down UI, architecture, Gemini integration, deployment, and the actual problems I ran into during production — not the sugar-coated tutorial version.
1. What the App Does
The idea is simple:
“Describe what you want, and the AI recommends products instantly.”
The UI shows a clean card with:
Title: Product AI Recommender
Subtitle: “Describe what you want, and the AI will recommend products.”
Textarea placeholder example:
“Suggest 3 budget smartphones under 15000 INR with pros and cons.”
Flow:
User enters query
Frontend sends the prompt to the backend
Backend hits Gemini API
Gemini returns recommendations
Frontend displays neatly formatted output
Looks simple. Underneath → full-stack + AI + deployment.
2. Architecture Overview
[Client Browser]
|
v
[React (Vite) on Vercel]
|
v
POST /api/recommend
|
v
[Node.js + Express on Render]
|
v
[Google Gemini API]
Vercel hosts the frontend
Render hosts the backend
Backend holds the GEMINI_API_KEY
Frontend calls only one endpoint:
POST https://<render-service>/api/recommend
3. Frontend (React + Vite)
Minimal UI, single focus:
Type → Click → Get Recommendations.
Core states:
const [query, setQuery] = useState("");
const [result, setResult] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
Request handler:
const res = await fetch("https://<your-backend>/api/recommend", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query }),
});
No clutter. No over-engineering.
4. Backend (Node.js + Express + Gemini)
Endpoint:POST /api/recommend
Backend tasks:
Read user prompt
Build structured system prompt
Call Gemini using
@google/generative-aiReturn the processed text
Example:
const model = genAI.getGenerativeModel({ model: "gemini-pro" });
app.post("/api/recommend", async (req, res) => {
const { query } = req.body;
const prompt = `
You are a product recommendation assistant.
User query: "${query}"
Return 3–5 products with a title, description, pros, and cons.
Keep it concise.
`;
const response = await model.generateContent(prompt);
const text = response.response.text();
res.json({ recommendations: text });
});
Environment variables stay in Render — never exposed in frontend.
5. Deployment Setup (Vercel + Render)
Frontend → Vercel
Connect GitHub
Select frontend folder
Build:
npm run buildOutput:
dist
Backend → Render
Create Web Service
Build:
npm installStart:
node index.jsornpm startAdd environment:
GEMINI_API_KEY=xxxx
After deployment → copy backend URL → update frontend.
6. Real Problems I Faced (and Their Fixes)
Tutorials hide this stuff. Here’s the real story.
6.1 CORS Errors Between Vercel & Render
Problem: Browser blocked the request.
Fix:
app.use(cors({
origin: "https://product-ai-recommender.vercel.app",
methods: ["POST"],
}));
Avoid * in final production.
6.2 Environment Variables Not Working
Problem: GEMINI_API_KEY was undefined.
Fix checklist:
Correct variable name
Added in Render dashboard
Restarted service
Confirmed no env used in frontend
Simple mistake, big headache.
6.3 App Worked on Laptop but Not on Phone
This one was annoying.
Root causes:
Using localhost in frontend code
HTTP/HTTPS mismatch
Mobile blocked insecure requests
Fix:
Used only Render’s public HTTPS URL.
6.4 Gemini API Authentication Errors
Problem: “missing api key” even though key was set.
Fix:
Used official Gemini SDK
Removed accidental spaces around key
Tested key with a separate route first
6.5 Cold Starts on Render (Slow First Request)
Free tier problem — nothing you can do except accept it or use ping services.
7. What I Plan to Improve Next
Better UI (cards, animations, layout)
Structured JSON output instead of raw text
User accounts + history
Category-wise enhancements
Product comparison mode
This is v1. The potential is much bigger.
8. Live Demo & Code
🚀 Live app: https://product-ai-recommender.vercel.app/
📦 GitHub: https://github.com/sandipmryadav/product-ai-recommender
If you have feedback — especially harsh, real feedback — I want to hear it.
9. Final Thoughts
This project forced me to solve real engineering problems, not tutorial fluff:
Third-party AI integration
Frontend + backend across separate hosting providers
CORS
Deployment debugging
Real-device testing
That’s the difference between “I built something on localhost” and I shipped a real product.
Publish Note
Originally published on Medium, this article has also been shared on Hashnode for broader reach.



