Wishlist
Add to Wishlist
Save a product to the user's wishlist
Overview
Add a product to the user's wishlist for future reference. This endpoint supports both authenticated and guest users with automatic session management.
Endpoint
POST /v1/wishlistAuthentication
Requires the x-api-key header for authentication.
Request
Headers
| Header | Type | Required | Description |
|---|---|---|---|
x-api-key | string | Yes | Your API authentication key |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
productId | string | Yes | The ID of the product to add |
Example Request
async function addToWishlist(productId) {
const response = await fetch('https://api.yourstore.com/v1/wishlist', {
method: 'POST',
headers: {
'x-api-key': process.env.BACKEND_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ productId })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to add to wishlist');
}
const guestToken = response.headers.get('x-guest-token');
if (guestToken) {
localStorage.setItem('guest_token', guestToken);
}
return response.json();
}
// Usage
addToWishlist('prod_123')
.then(wishlist => console.log('Added to wishlist:', wishlist))
.catch(error => console.error(error));interface AddToWishlistRequest {
productId: string;
}
interface WishlistItem {
id: string;
productId: string;
product: {
name: string;
price: number;
image: string;
};
}
async function addToWishlist(
productId: string
): Promise<WishlistItem[]> {
const response = await fetch('https://api.yourstore.com/v1/wishlist', {
method: 'POST',
headers: {
'x-api-key': process.env.BACKEND_API_KEY!,
'Content-Type': 'application/json'
},
body: JSON.stringify({
productId
} as AddToWishlistRequest)
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to add to wishlist');
}
const guestToken = response.headers.get('x-guest-token');
if (guestToken) {
localStorage.setItem('guest_token', guestToken);
}
return response.json();
}Server Action Example (Next.js)
'use server';
import { cookieManager } from '@/lib/auth-tools';
import { revalidatePath } from 'next/cache';
export async function addToWishlistAction(productId) {
try {
const headers = await cookieManager.buildApiHeaders();
const response = await fetch('https://api.yourstore.com/v1/wishlist', {
method: 'POST',
headers,
body: JSON.stringify({ productId })
});
if (!response.ok) {
const error = await response.json();
return {
success: false,
message: error.message
};
}
await cookieManager.handleApiResponse(response);
const wishlist = await response.json();
revalidatePath('/wishlist');
return {
success: true,
wishlist
};
} catch (error) {
return {
success: false,
message: 'Failed to add to wishlist'
};
}
}'use server';
import { cookieManager } from '@/lib/auth-tools';
import { revalidatePath } from 'next/cache';
interface AddToWishlistResult {
success: boolean;
wishlist?: any[];
message?: string;
}
export async function addToWishlistAction(
productId: string
): Promise<AddToWishlistResult> {
try {
const headers = await cookieManager.buildApiHeaders();
const response = await fetch('https://api.yourstore.com/v1/wishlist', {
method: 'POST',
headers,
body: JSON.stringify({ productId })
});
if (!response.ok) {
const error = await response.json();
return {
success: false,
message: error.message
};
}
await cookieManager.handleApiResponse(response);
const wishlist = await response.json();
revalidatePath('/wishlist');
return {
success: true,
wishlist
};
} catch (error) {
return {
success: false,
message: 'Failed to add to wishlist'
};
}
}Wishlist Button Component
'use client';
import { addToWishlistAction } from '@/actions/wishlist';
import { useState } from 'react';
import { Heart } from 'lucide-react';
export function WishlistButton({ productId, isInWishlist = false }) {
const [loading, setLoading] = useState(false);
const [saved, setSaved] = useState(isInWishlist);
const handleToggle = async () => {
setLoading(true);
const result = await addToWishlistAction(productId);
if (result.success) {
setSaved(true);
alert('Added to wishlist!');
} else {
alert(result.message);
}
setLoading(false);
};
return (
<button
onClick={handleToggle}
disabled={loading || saved}
className={`flex items-center gap-2 px-4 py-2 rounded ${
saved ? 'bg-red-100 text-red-600' : 'bg-gray-100'
}`}
>
<Heart className={saved ? 'fill-current' : ''} size={20} />
{saved ? 'Saved' : 'Save'}
</button>
);
}Response
Success Response (200)
Returns the updated wishlist items array.
[
{
"id": "wish_123",
"productId": "prod_456",
"product": {
"id": "prod_456",
"name": "Wireless Headphones",
"price": 199.99,
"image": "https://example.com/images/headphones.jpg",
"inStock": true
},
"createdAt": "2024-03-15T10:30:00Z"
}
]Error Responses
| Status Code | Description |
|---|---|
401 | Invalid or missing API key |
404 | Product not found |
409 | Product already in wishlist |
422 | Invalid input data |
500 | Failed to add to wishlist |
Important Notes
Duplicate Prevention: If a product is already in the wishlist, you'll receive a 409 error. Consider checking the wishlist state before attempting to add.
Product Validation: The API validates that the product exists and is available before adding to wishlist.
Toggle Wishlist Component
Here's a reusable component that handles both adding and removing:
'use client';
import { addToWishlistAction, removeFromWishlistAction } from '@/actions/wishlist';
import { useState } from 'react';
import { Heart } from 'lucide-react';
export function WishlistToggle({ productId, wishlistItemId = null }) {
const [loading, setLoading] = useState(false);
const [itemId, setItemId] = useState(wishlistItemId);
const handleToggle = async () => {
setLoading(true);
if (itemId) {
// Remove from wishlist
const result = await removeFromWishlistAction(itemId);
if (result.success) {
setItemId(null);
}
} else {
// Add to wishlist
const result = await addToWishlistAction(productId);
if (result.success && result.wishlist) {
const newItem = result.wishlist.find(
item => item.productId === productId
);
setItemId(newItem?.id);
}
}
setLoading(false);
};
return (
<button
onClick={handleToggle}
disabled={loading}
className="p-2 rounded-full hover:bg-gray-100"
aria-label={itemId ? 'Remove from wishlist' : 'Add to wishlist'}
>
<Heart
className={itemId ? 'fill-red-500 text-red-500' : 'text-gray-400'}
size={24}
/>
</button>
);
}Related Endpoints
- Get Wishlist - View all saved items
- Remove from Wishlist - Delete items