🎯 Smart Personalization
Use AI to personalize user experiences. Smart recommendations, dynamic content, and intelligent search that adapts to each user.
Personalization Features
Product Recommendations
Suggest items based on preferences
Dynamic Content
Adapt text to user context
Smart Search
Understand intent, not just keywords
Personalized Messages
Tailored notifications & emails
How It Works
Combine user data (from GammalTech.user.get()) with AI (from GammalTech.ai.ask()) to create personalized experiences.
Smart Product Recommendations
Recommend products based on user history and preferences:
async function getRecommendations(products, count = 5) {
// Get user data
const userData = await GammalTech.user.get();
// Build user profile for AI
const userProfile = {
purchases: userData.purchaseHistory || [],
viewed: userData.recentlyViewed || [],
favorites: userData.favorites || [],
preferences: userData.preferences || {}
};
const prompt = `You are a product recommendation engine.
User Profile:
- Past purchases: ${JSON.stringify(userProfile.purchases.slice(-10))}
- Recently viewed: ${JSON.stringify(userProfile.viewed.slice(-10))}
- Favorites: ${JSON.stringify(userProfile.favorites.slice(-5))}
- Preferences: ${JSON.stringify(userProfile.preferences)}
Available Products:
${JSON.stringify(products.slice(0, 50))}
Recommend ${count} products this user would love.
Return ONLY a JSON array of product IDs, like: ["id1", "id2", "id3"]`;
const response = await GammalTech.ai.ask(prompt);
// Parse response and get full product details
const recommendedIds = JSON.parse(response);
return products.filter(p => recommendedIds.includes(p.id));
}
// Usage
const recommendations = await getRecommendations(allProducts, 5);
displayProducts(recommendations);
Dynamic Content Personalization
Adapt page content based on user context:
async function personalizeHero() {
const userData = await GammalTech.user.get();
// Determine user segment
const segment = getUserSegment(userData);
const prompt = `Write a hero section headline and subtitle for a user.
User Context:
- Name: ${userData.name || 'Guest'}
- Segment: ${segment}
- Last visit: ${userData.lastVisit || 'First visit'}
- Interests: ${userData.interests?.join(', ') || 'Not specified'}
Our product: Online learning platform
Requirements:
- Headline: Max 8 words, compelling
- Subtitle: Max 20 words, benefit-focused
- Personalized to their segment
Return JSON: { "headline": "...", "subtitle": "..." }`;
const response = await GammalTech.ai.ask(prompt);
const content = JSON.parse(response);
// Update UI
document.getElementById('hero-headline').textContent = content.headline;
document.getElementById('hero-subtitle').textContent = content.subtitle;
}
function getUserSegment(userData) {
if (!userData.lastVisit) return 'new_visitor';
if (userData.purchaseCount > 5) return 'loyal_customer';
if (userData.purchaseCount > 0) return 'returning_customer';
return 'browsing_user';
}
Intelligent Search
Understand search intent and return relevant results:
async function smartSearch(query, items) {
const userData = await GammalTech.user.get();
const prompt = `You are a smart search engine.
User Query: "${query}"
User Preferences: ${JSON.stringify(userData.preferences || {})}
Available Items:
${JSON.stringify(items.map(i => ({ id: i.id, name: i.name, category: i.category, tags: i.tags })))}
Tasks:
1. Understand the user's intent (even if query has typos)
2. Consider their preferences
3. Rank the most relevant items
Return JSON array of item IDs in order of relevance: ["id1", "id2", ...]
Only include truly relevant items. Return [] if nothing matches.`;
const response = await GammalTech.ai.ask(prompt);
const rankedIds = JSON.parse(response);
// Return items in ranked order
return rankedIds.map(id => items.find(i => i.id === id)).filter(Boolean);
}
// Usage - handles natural language!
const results = await smartSearch('something comfy for winter', products);
// Returns cozy sweaters, warm jackets, etc.
Personalized Notifications
Generate personalized messages and notifications:
async function generatePersonalizedMessage(messageType) {
const userData = await GammalTech.user.get();
const templates = {
welcome_back: `Welcome back message for ${userData.name || 'user'}
who last visited ${userData.daysSinceLastVisit || 'recently'} days ago.
They were interested in: ${userData.lastViewedCategory || 'our products'}`,
cart_reminder: `Friendly cart reminder for ${userData.name || 'user'}
who has ${userData.cartItems?.length || 0} items in cart worth $${userData.cartTotal || 0}.
Items: ${userData.cartItems?.map(i => i.name).join(', ') || 'various products'}`,
new_arrival: `New arrival notification for ${userData.name || 'user'}
who likes: ${userData.favoriteCategories?.join(', ') || 'our products'}.
Highlight new items matching their taste.`
};
const prompt = `Write a short, personalized notification.
Context: ${templates[messageType]}
Requirements:
- Max 2 sentences
- Warm but not pushy
- Include a subtle call to action
- Don't be generic
Message:`;
return await GammalTech.ai.ask(prompt);
}
// Usage
const message = await generatePersonalizedMessage('welcome_back');
// "Welcome back, Sarah! We noticed you were eyeing those hiking boots —
// they're still waiting for you with free shipping this week."
Complete Personalization System
Combine everything into a reusable class:
class PersonalizationEngine {
constructor() {
this.userDataCache = null;
}
async getUserData() {
if (!this.userDataCache) {
this.userDataCache = await GammalTech.user.get();
}
return this.userDataCache;
}
async recommend(items, count = 5) {
const user = await this.getUserData();
const response = await GammalTech.ai.ask(`
Recommend ${count} items for user with preferences: ${JSON.stringify(user.preferences)},
purchase history: ${JSON.stringify(user.purchases?.slice(-5))}.
Items: ${JSON.stringify(items.slice(0, 30))}.
Return JSON array of IDs only.`);
const ids = JSON.parse(response);
return items.filter(i => ids.includes(i.id));
}
async search(query, items) {
const user = await this.getUserData();
const response = await GammalTech.ai.ask(`
Search "${query}" considering preferences: ${JSON.stringify(user.preferences)}.
Items: ${JSON.stringify(items)}.
Return ranked JSON array of IDs.`);
const ids = JSON.parse(response);
return ids.map(id => items.find(i => i.id === id)).filter(Boolean);
}
async personalize(template) {
const user = await this.getUserData();
return GammalTech.ai.ask(`
Personalize this for ${user.name || 'user'}: "${template}"
Context: ${JSON.stringify(user)}`);
}
async generateGreeting() {
const user = await this.getUserData();
const hour = new Date().getHours();
const timeOfDay = hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening';
return GammalTech.ai.ask(`
Write a brief ${timeOfDay} greeting for ${user.name || 'visitor'}.
They've visited ${user.visitCount || 1} times.
Keep it under 10 words.`);
}
clearCache() {
this.userDataCache = null;
}
}
// Usage
const personalization = new PersonalizationEngine();
const greeting = await personalization.generateGreeting();
const recommended = await personalization.recommend(products);
const searchResults = await personalization.search('comfy shoes', products);
Tracking User Behavior
Build up user data over time for better personalization:
async function trackView(product) {
const data = await GammalTech.user.get();
// Add to recently viewed (keep last 20)
data.recentlyViewed = data.recentlyViewed || [];
data.recentlyViewed.unshift({ id: product.id, category: product.category, viewedAt: new Date() });
data.recentlyViewed = data.recentlyViewed.slice(0, 20);
// Update category preferences
data.categoryViews = data.categoryViews || {};
data.categoryViews[product.category] = (data.categoryViews[product.category] || 0) + 1;
await GammalTech.user.save(data);
}
async function trackPurchase(product) {
const data = await GammalTech.user.get();
data.purchases = data.purchases || [];
data.purchases.push({ id: product.id, category: product.category, purchasedAt: new Date() });
data.purchaseCount = (data.purchaseCount || 0) + 1;
await GammalTech.user.save(data);
}
async function trackSearch(query) {
const data = await GammalTech.user.get();
data.searchHistory = data.searchHistory || [];
data.searchHistory.unshift({ query, searchedAt: new Date() });
data.searchHistory = data.searchHistory.slice(0, 50);
await GammalTech.user.save(data);
}
Best Practices
• Start simple — personalize one thing well before adding more
• Cache user data to avoid repeated fetches
• Have fallbacks for new users with no data
• Test with different user profiles
• Respect privacy — only collect what you need
• Don't over-personalize — it can feel creepy
• Don't send too much data to AI — summarize it
• Don't rely 100% on AI — have sensible defaults
• Don't personalize critical UI that users expect to be consistent
AI Prompt for Vibe Coding
PersonalizationCopy this prompt to build your personalization system: