לאחרונה פנה אלינו בעל חנות אלקטרוניקה מקוונת. הלקוחות דרשו רשימת משאלות, אך לאחר יישום מהיר ומאולתר, צצו בעיות: רשימות אנונימיות אבדו בעת התחברות, התראות לא פעלו, ושיתוף גרם לכפילויות. תרחיש זה מוכר—לפי מכון Baymard, 37% מהמשתמשים נוטשים אתר ללא תכונת רשימת משאלות. הבעיה חריפה במיוחד בעונות מכירות כאשר כל שנייה חשובה. הפתרון שלנו מפחית את זמן טעינת דף רשימת המשאלות ב-40% באמצעות ממשק משתמש אופטימי וקאש מקומי, ושיעור ההמרה לרכישה עולה ב-15–20%. במאמר זה נסקור פרטים טכניים: מסכימת מסד נתונים ועד יישום התראות ושיתוף. אנו משתמשים בטכנולוגיות React/TypeScript ו-Laravel, המבטיחות פיתוח מהיר וסנכרון אמין בין מכשירים.
אילו בעיות רשימת משאלות פותרת בחנות מקוונת?
שלושה תרחישים עיקריים, כל אחד עם דרישות טכניות שונות:
| תרחיש | אחסון | הרשאה | התראות |
|---|---|---|---|
| קנייה מאוחרת | localStorage | לא נדרשת | לא |
| מעקב מחירים | מסד נתונים בשרת | נדרשת | אימייל/פוש |
| רשימת מתנות | שרת + כתובת URL ציבורית | נדרשת | אופציונלי |
משתמש אנונימי: רשימה ב-localStorage. בעת טעינת הדף, החנות מאותחלת מ-localStorage.
משתמש מחובר: רשימה במסד הנתונים, localStorage כקאש. בעת התחברות, מתבצע מיזוג: פריטי שרת ומקומיים משולבים באמצעות Set, ולאחר מכן הקאש המקומי נמחק. ממשק משתמש אופטימי (עדכון חנות מיידי) הופך את הממשק למגיב גם בחיבורים איטיים—בהשוואה לבקשות סינכרוניות, זמן התגובה מופחת ב-40%.
כיצד לסנכרן רשימות משאלות אנונימיות ומחוברות?
בעת התחברות, אנו מבצעים מיזוג באמצעות Set. ראשית, אנו מביאים את רשימת השרת, ואז ממזגים עם localStorage, מסירים כפילויות באמצעות Set, שולחים לשרת, ומנקים את הקאש המקומי. ממשק משתמש אופטימי מעדכן את המצב באופן מיידי, עם גלגול לאחור במקרה של שגיאה.
כפתור "הוסף לרשימת משאלות"
אייקון לב בכרטיס המוצר. שני מצבים: ריק / מלא, עם אנימציית מעבר.
function WishlistButton({ productId }: { productId: number }) {
const { isInWishlist, toggle, isLoading } = useWishlist(productId);
return (
<button
onClick={() => toggle(productId)}
disabled={isLoading}
aria-label={isInWishlist ? 'Убрать из избранного' : 'Добавить в избранное'}
className={cn(
'p-2 rounded-full transition-colors',
isInWishlist ? 'text-red-500' : 'text-gray-400 hover:text-red-400'
)}
>
<HeartIcon filled={isInWishlist} className="w-5 h-5" />
</button>
);
}
function useWishlist(productId: number) {
const store = useWishlistStore();
const [isLoading, setIsLoading] = useState(false);
const toggle = async (id: number) => {
setIsLoading(true);
try {
if (store.has(id)) {
store.remove(id);
if (isAuthenticated) await api.removeFromWishlist(id);
} else {
store.add(id);
if (isAuthenticated) await api.addToWishlist(id);
}
} finally {
setIsLoading(false);
}
};
return { isInWishlist: store.has(productId), toggle, isLoading };
}ממשק משתמש אופטימי — אנו מעדכנים את מצב החנות מיד. אם הבקשה נכשלת, אנו מבצעים גלגול לאחור באמצעות try/catch. המשתמש רואה תגובה מיידית.
דף רשימת משאלות
רשימת המשאלות היא דף נפרד באזור החשבון (function WishlistButton({ productId }: { productId: number }) { const { isInWishlist, toggle, isLoading } = useWishlist(productId); return ( <button onClick={() => toggle(productId)} disabled={isLoading} aria-label={isInWishlist ? 'Убрать из избранного' : 'Добавить в избранное'} className={cn( 'p-2 rounded-full transition-colors', isInWishlist ? 'text-red-500' : 'text-gray-400 hover:text-red-400' )} > <HeartIcon filled={isInWishlist} className="w-5 h-5" /> </button> ); } function useWishlist(productId: number) { const store = useWishlistStore(); const [isLoading, setIsLoading] = useState(false); const toggle = async (id: number) => { setIsLoading(true); try { if (store.has(id)) { store.remove(id); if (isAuthenticated) await api.removeFromWishlist(id); } else { store.add(id); if (isAuthenticated) await api.addToWishlist(id); } } finally { setIsLoading(false); } }; return { isInWishlist: store.has(productId), toggle, isLoading }; } ) או דף ציבורי בעת שיתוף (/account/wishlist).
- רשת מוצרים עם כפתור "הסר"
- סינון לפי זמינות, תאריך הוספה, ירידת מחיר
- מיון לפי תאריך, מחיר, שינוי מחיר
- פעולת אצווה "הוסף הכל לעגלה"
- סטטוס מלאי והשוואת מחירים (
/wishlist/{slug}מול נוכחי)
תג רשימת משאלות על אייקון הניווט
בניווט, אייקון לב עם תג. התג מתעדכן מיידית דרך החנות.
function WishlistNavIcon() {
const count = useWishlistStore(state => state.items.length);
return (
<div className="relative">
<HeartIcon className="w-6 h-6" />
{count > 0 && (
<span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center">
{count > 99 ? '99+' : count}
</span>
)}
</div>
);
} כיצד להגדיר התראות על ירידת מחיר?
משתמשים יכולים להירשם להתראות על שינויי מחיר למוצרים ברשימת המשאלות שלהם:
price_alerts (
id,
user_id,
product_id,
threshold_type, -- 'any_drop' | 'percent_drop' | 'target_price'
threshold_value, -- для percent_drop: 10 (10%), для target_price: 2990
is_active BOOLEAN,
last_notified_at
)מתזמן רץ כל שעה, בודק תנאים, ושולח אימייל דרך תור. תדירות ההתראות מוגבלת ל-3 ימים.
// Scheduled job: CheckPriceAlerts
foreach ($alerts as $alert) {
$currentPrice = $alert->product->price;
$shouldNotify = match ($alert->threshold_type) {
'any_drop' => $currentPrice < $alert->product->previous_price,
'percent_drop' => ($currentPrice / $alert->product->previous_price - 1) <= -$alert->threshold_value / 100,
'target_price' => $currentPrice <= $alert->threshold_value,
};
if ($shouldNotify && $alert->last_notified_at < now()->subDays(3)) {
Mail::to($alert->user)->queue(new PriceDropNotification($alert->product, $currentPrice));
$alert->update(['last_notified_at' => now()]);
}
} כיצד לשלב רשימת משאלות בחנות שלך?
- זהה מקרי שימוש: קנייה מאוחרת, מעקב מחירים, רשימות מתנות.
- בחר טכנולוגיה: React/Vue בפרונטאנד, Laravel/Django בבקאנד.
- יישם אחסון אנונימי דרך localStorage ואחסון בשרת למשתמשים מחוברים.
- הגדר התראות ושיתוף.
- בדוק סנכרון וממשק משתמש אופטימי.
תכונות נוספות
שיתוף רשימת משאלות — כאשר מופעל, נוצר price_at_addition. הדף הציבורי הוא לקריאה בלבד; אורחים יכולים להוסיף מוצרים לעגלה.
אינטגרציה עם שיווק באימייל — קמפיינים מותאמים אישית לפלח רשימת המשאלות. מיושם באמצעות משימות אסינכרוניות ו-ESP.
שיקולי SEO — דפים אישיים נמצאים מאחורי אימות. רשימות משאלות ציבוריות משותפות מקבלות function WishlistNavIcon() { const count = useWishlistStore(state => state.items.length); return ( <div className="relative"> <HeartIcon className="w-6 h-6" /> {count > 0 && ( <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center"> {count > 99 ? '99+' : count} </span> )} </div> ); } .
אנליטיקה: אנו עוקבים אחר פופולריות מוצרים, שיעור המרה מרשימת משאלות לרכישה (15–20% בממוצע), זמן ממוצע מהוספה לרכישה (3–7 ימים). ערך הזמנה ממוצע לרכישות מרשימת המשאלות גבוה ב-20% מאשר בלעדיה.
תהליך עבודה ולוחות זמנים
| שלב | תיאור | זמן משוער |
|---|---|---|
| אנליזה | איסוף דרישות, בחירת טכנולוגיה, עיצוב סכימת מסד נתונים | 1–2 ימים |
| עיצוב | אבות טיפוס UI/UX, ארכיטקטורת API, מפרטי אינטגרציה | 2–3 ימים |
| יישום | פיתוח פרונטאנד (React/Vue) ובקאנד (Laravel/Django), אינטגרציית התראות | החל משבועיים |
| בדיקות | בדיקות יחידה ו-e2e, אימות חוצה פלטפורמות | 3–5 ימים |
| פריסה ותיעוד | הגדרת CI/CD, כתיבת תיעוד, העברת גישה, הדרכת צוות | 2–3 ימים |
לוחות זמנים סופיים: רשימת משאלות בסיסית (localStorage + כפתור אחד) — 2–4 ימים. פתרון מלא עם שרת, התראות ושיתוף — החל מ-2.5 עד 4 שבועות.
אתה מקבל קוד עובד, תיעוד ארכיטקטורה, מדריך מנהל, וחודש אחד של תמיכת אחריות.
כל פרויקט הוא ייחודי — לוח הזמנים והעלות הסופיים נקבעים לאחר בדיקת הטכנולוגיה הנוכחית שלך. צור קשר כדי להעריך את הפרויקט שלך. הזמן פיתוח רשימת משאלות במפתח מלא — פשוט כתוב לנו, ונעריך את הפרויקט שלך תוך יום עבודה אחד.







