- Add Apollo Client for Saleor GraphQL API - Create GraphQL fragments (Product, Variant, Checkout) - Create GraphQL queries (Products, Checkout) - Create GraphQL mutations (Checkout operations) - Add TypeScript types for Saleor entities - Add product helper functions - Install @apollo/client and graphql dependencies Part of WordPress/WooCommerce → Saleor migration
12 KiB
12 KiB
Advanced E-Commerce Features Checklist
Saleor Built-in vs Missing Features
✅ Built-in (Ready to Use)
| Feature | Saleor Support | Notes |
|---|---|---|
| Products & Variants | ✅ Native | Simple & variable products |
| Categories | ✅ Native | Hierarchical with nesting |
| Collections | ✅ Native | Manual & automated collections |
| Inventory | ✅ Native | Multi-warehouse support |
| Multi-language | ✅ Native | Full translation support |
| Multi-currency | ✅ Native | Per-channel pricing |
| Promotions | ✅ Native | % off, fixed amount, vouchers |
| Gift Cards | ✅ Native | Digital gift cards |
| Taxes | ✅ Native | Per-country tax rates |
| Shipping | ✅ Native | Zones & methods |
| Customer Accounts | ✅ Native | Full account management |
| Order Management | ✅ Native | Status tracking, fulfillments |
| Staff Permissions | ✅ Native | Role-based access |
| Pages & Menus | ✅ Native | CMS features |
| Checkout | ✅ Native | Customizable flow |
| Payments | ✅ Native | Stripe, Adyen, etc. |
❌ Missing Features (Need to Build/Add)
1. Product Reviews ⭐ HIGH PRIORITY
Status: NOT in Saleor (on roadmap but not planned)
Solutions:
| Solution | Cost | Effort | Best For |
|---|---|---|---|
| Judge.me | Free-$15/mo | 2 hours | Budget option, works well |
| Trustpilot | $200+/mo | 2 hours | SEO, brand trust |
| Yotpo | $300+/mo | 4 hours | Enterprise, UGC |
| Build Custom | Free | 2-4 weeks | Full control |
Custom Build SQL:
CREATE TABLE product_review (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES product_product(id),
user_id INTEGER REFERENCES account_user(id),
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
title VARCHAR(255),
comment TEXT,
is_verified_purchase BOOLEAN DEFAULT false,
is_approved BOOLEAN DEFAULT false,
helpful_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW()
);
2. Upsells & Cross-sells ⭐ HIGH PRIORITY
Status: NOT in Saleor (confirmed missing)
What You Need:
-- Related products / upsells table
CREATE TABLE product_related (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES product_product(id),
related_product_id INTEGER REFERENCES product_product(id),
type VARCHAR(50), -- 'upsell', 'cross_sell', 'related'
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(product_id, related_product_id, type)
);
Types of Upsells:
| Type | Example | Location |
|---|---|---|
| Upsell | 500ml → 1L (upgrade) | Product page |
| Cross-sell | Olive oil + vinegar (complementary) | Cart page |
| Related | Same category products | Product page |
| Bundle | Oil + vinegar + herbs package | Product page |
| Frequently Bought Together | AI-based recommendations | Cart page |
Implementation Options:
Option A: Manual (Product-Level)
-- Admin manually assigns related products
INSERT INTO product_related (product_id, related_product_id, type, sort_order)
VALUES
(1, 5, 'upsell', 1), -- Product 1 shows Product 5 as upsell
(1, 6, 'cross_sell', 1), -- Product 1 shows Product 6 as cross-sell
(1, 7, 'related', 1); -- Product 1 shows Product 7 as related
Admin UI Needed:
- Product edit page with "Related Products" section
- Search & select products
- Drag to reorder
- Choose type (upsell/cross-sell/related)
Option B: Automated (Category-Based)
// Automatically show products from same category
const getRelatedProducts = async (productId: string, categoryId: string) => {
return await saleorClient.query({
query: gql`
query GetRelatedProducts($categoryId: ID!, $excludeId: ID!) {
products(
first: 4,
filter: {categories: [$categoryId]},
channel: "default-channel"
) {
edges {
node {
id
name
slug
thumbnail { url }
variants {
channelListings {
price { amount currency }
}
}
}
}
}
}
`,
variables: { categoryId, excludeId: productId }
});
};
Option C: AI/ML Recommendations (Advanced)
Services:
- Recombee - $99/mo+
- Amazon Personalize - Pay per use
- Algolia Recommend - $29/mo+
- Build custom - Requires order history analysis
Effort: High (4-8 weeks)
3. Product Bundles ⭐ MEDIUM PRIORITY
Status: NOT in Saleor (requested, on roadmap)
Example:
- Olive Oil 500ml + Vinegar 250ml = Bundle price $15 (save $3)
Custom Implementation:
-- Bundle definition
CREATE TABLE product_bundle (
id SERIAL PRIMARY KEY,
name VARCHAR(250),
slug VARCHAR(255) UNIQUE,
description JSONB,
product_type_id INTEGER REFERENCES product_producttype(id),
bundle_price_amount NUMERIC(20,3),
currency VARCHAR(3),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
-- Bundle items
CREATE TABLE product_bundle_item (
id SERIAL PRIMARY KEY,
bundle_id INTEGER REFERENCES product_bundle(id),
product_variant_id INTEGER REFERENCES product_productvariant(id),
quantity INTEGER DEFAULT 1,
sort_order INTEGER DEFAULT 0
);
Storefront Display:
// Show bundle on product page
<ProductBundle
bundle={{
name: "Mediterranean Starter Pack",
items: [
{ name: "Olive Oil 500ml", price: 12 },
{ name: "Balsamic Vinegar 250ml", price: 6 },
],
regularPrice: 18,
bundlePrice: 15,
savings: 3
}}
/>
4. Abandoned Cart Recovery ⭐ HIGH PRIORITY
Status: NOT in Saleor
Solutions:
- Mautic (FREE - you have it!) - See
mautic-abandoned-cart.md - Klaviyo - $20-50/mo
- N8N automation - FREE
5. Email Marketing ⭐ MEDIUM PRIORITY
Status: NOT in Saleor
Solutions:
- Mautic (FREE - you have it!)
- Klaviyo - Best for e-commerce
- Mailchimp - Good free tier
Email Types Needed:
- Welcome email
- Order confirmation
- Shipping notification
- Post-purchase follow-up
- Win-back campaign
- Birthday discount
6. Loyalty/Rewards Program ⭐ MEDIUM PRIORITY
Status: NOT in Saleor
Custom Build:
-- Loyalty points
CREATE TABLE loyalty_account (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES account_user(id),
points_balance INTEGER DEFAULT 0,
lifetime_points INTEGER DEFAULT 0,
tier VARCHAR(50) DEFAULT 'bronze', -- bronze, silver, gold
created_at TIMESTAMP DEFAULT NOW()
);
-- Points transactions
CREATE TABLE loyalty_transaction (
id SERIAL PRIMARY KEY,
account_id INTEGER REFERENCES loyalty_account(id),
points INTEGER, -- positive for earn, negative for redeem
type VARCHAR(50), -- 'purchase', 'referral', 'redemption', 'bonus'
description TEXT,
order_id INTEGER REFERENCES order_order(id),
created_at TIMESTAMP DEFAULT NOW()
);
7. Subscription/Recurring Products ⭐ LOW PRIORITY
Status: NOT in Saleor
Solutions:
- Stripe Billing - Best integration
- Recharge - $300/mo+ (Shopify-focused)
- Chargebee - $249/mo+
- Build custom with Stripe
8. Wishlist/Favorites ⭐ MEDIUM PRIORITY
Status: NOT in Saleor
Simple Implementation:
CREATE TABLE wishlist_item (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES account_user(id),
product_variant_id INTEGER REFERENCES product_productvariant(id),
added_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, product_variant_id)
);
9. Recently Viewed Products ⭐ LOW PRIORITY
Implementation:
// Store in localStorage or Redis
const trackProductView = (productId: string) => {
const recentlyViewed = JSON.parse(localStorage.getItem('recentlyViewed') || '[]');
recentlyViewed.unshift(productId);
localStorage.setItem('recentlyViewed', JSON.stringify(recentlyViewed.slice(0, 10)));
};
10. Product Comparison ⭐ LOW PRIORITY
Implementation:
// Allow users to compare 2-3 products side-by-side
const ProductComparison = ({ products }) => {
return (
<table>
<thead>
<tr>
<th>Feature</th>
{products.map(p => <th key={p.id}>{p.name}</th>)}
</tr>
</thead>
<tbody>
<tr>
<td>Price</td>
{products.map(p => <td key={p.id}>${p.price}</td>)}
</tr>
<tr>
<td>Volume</td>
{products.map(p => <td key={p.id}>{p.volume}</td>)}
</tr>
</tbody>
</table>
);
};
11. Quick View (Modal) ⭐ LOW PRIORITY
Implementation:
// Product card with quick view button
<ProductCard>
<Image src={product.thumbnail} />
<h3>{product.name}</h3>
<button onClick={() => openQuickView(product.id)}>
Quick View
</button>
</ProductCard>
// Modal fetches product details
<QuickViewModal productId={selectedProductId} />
12. AJAX Add to Cart (No Page Reload) ⭐ MEDIUM PRIORITY
Implementation:
const AddToCartButton = ({ variantId }) => {
const [adding, setAdding] = useState(false);
const handleAdd = async () => {
setAdding(true);
await saleorClient.mutate({
mutation: ADD_TO_CART,
variables: { variantId, quantity: 1 }
});
setAdding(false);
showToast('Added to cart!');
updateCartCount(); // Update header cart icon
};
return <button onClick={handleAdd} disabled={adding}>Add to Cart</button>;
};
13. Dynamic Pricing / Volume Discounts ⭐ LOW PRIORITY
Example:
- Buy 1: $12
- Buy 2: $11 each (save $2)
- Buy 3+: $10 each (save $6)
Saleor Native: Not supported
Custom:
const getVolumePrice = (basePrice: number, quantity: number) => {
if (quantity >= 3) return basePrice * 0.83; // 17% off
if (quantity >= 2) return basePrice * 0.92; // 8% off
return basePrice;
};
14. Back in Stock Notifications ⭐ MEDIUM PRIORITY
Implementation:
CREATE TABLE stock_notification_request (
id SERIAL PRIMARY KEY,
email VARCHAR(255),
product_variant_id INTEGER REFERENCES product_productvariant(id),
is_notified BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
-- When stock is updated, check and send emails
Recommended Priority Order
Phase 1: Essential (Launch)
- Saleor core products
- Reviews (Judge.me or custom)
- Upsells/Cross-sells (manual assignment)
- AJAX cart
- Mautic abandoned cart
Phase 2: Growth (1-3 months post-launch)
- Email marketing (Mautic or Klaviyo)
- Wishlist
- Bundles
- Recently viewed
Phase 3: Advanced (6+ months)
- Loyalty program
- AI recommendations
- Subscriptions
- Product comparison
Cost Summary
| Feature | DIY Build | Third-Party | Recommended |
|---|---|---|---|
| Reviews | 2-4 weeks | Judge.me FREE | Judge.me |
| Upsells | 1-2 weeks | N/A | Custom |
| Bundles | 2-3 weeks | N/A | Custom |
| Abandoned Cart | 2-3 days | Klaviyo $20/mo | Mautic FREE |
| Email Marketing | 1 week | Klaviyo $20/mo | Mautic FREE |
| Loyalty | 2-3 weeks | Smile.io $199/mo | Custom later |
| Subscriptions | 4-6 weeks | Recharge $300/mo | Stripe later |
Total Estimated Dev Time
Phase 1: 4-6 weeks
Phase 2: 3-4 weeks
Phase 3: 6-8 weeks
Total: 3-4 months for full-featured store