Skip to main content

Overview

The Dzaleka Marketplace is a vibrant online marketplace where community members can buy and sell products and services. From handmade crafts and clothing to professional services and tutoring, the marketplace supports local entrepreneurs and connects buyers with unique, fair-trade items.
The marketplace includes both individual product/service listings AND a separate “Stores” section for registered brick-and-mortar businesses like restaurants and shops.

User Workflows

Browsing & Shopping

1

Explore Listings

Browse all active listings at /marketplace with visual grid display.
2

Filter by Type

Switch between Products and Services using filter buttons.
3

Filter by Category

Use dropdown to narrow by category (Arts & Crafts, Electronics, Food, Services, etc.).
4

View Details

Click any listing to see full description, pricing, and seller contact info.
5

Contact Seller

Reach out via WhatsApp, phone, or email to arrange purchase.

Listing Detail Page

Each listing (/marketplace/[slug]) displays:
  • Product/service photos: Image gallery with multiple views
  • Title & description: What’s being sold
  • Price: Fixed price, price range, “Contact for price”, or “Free”
  • Type badge: Product vs. Service indicator
  • Category tag: Classification (Arts, Electronics, Food, etc.)
  • Vendor information: Name, location, contact details
  • External link: Shop website if applicable (e.g., Kibebe store)
  • Status: Active, sold, or inactive
  • Featured badge: Highlighted premium listings

Local Economy

Support refugee entrepreneurs and artisans directly

Fair Trade Certified

Many products are ethically sourced and certified

Direct Contact

WhatsApp integration for instant seller communication

Free Listings

No fees to list products - 100% free for sellers

Content Schema

Marketplace listings are stored in src/content/marketplace/ as Markdown files:
title: "Product/Service Name"                 # Required
description: "Brief overview"                 # Required
type: "product"                               # Required: product | service
category: "arts-crafts"                       # Required - see categories below
price: "MWK 5000"                             # Price or range
currency: "MWK"                               # MWK | USD
priceType: "fixed"                            # fixed | range | contact | free
images:                                       # Array of image URLs
  - "https://example.com/image1.jpg"
  - "https://example.com/image2.jpg"
vendor:
  name: "Vendor Name"                         # Required
  phone: "+265 XXX XXX XXX"
  whatsapp: "+265 XXX XXX XXX"                # WhatsApp number (same or different)
  email: "vendor@email.com"
  location: "Dzaleka Refugee Camp"            # Physical location
status: "active"                              # active | sold | inactive
featured: true                                # Boolean - premium placement
datePosted: 2024-11-20                        # Date listed (YYYY-MM-DD)
tags:                                         # Array of keywords
  - handmade
  - eco-friendly
  - fair-trade
externalLink: "https://shop.com/product"      # Optional - link to external store

Real Example from Source

From kibebe-baby-products.md:
title: "Kibebe Handmade Baby Products"
description: "Fair Trade certified handmade baby items crafted in Malawi. Includes onesies, bibs, rattles, squeaky toys, and sensory play mats. Eco-friendly and sustainable."
type: "product"
category: "arts-crafts"
price: "USD 10 - 39"
currency: "USD"
priceType: "fixed"
images:
  - "https://kibebe.com/cdn/shop/products/2_6b9e5307-36d2-4392-b833-406e989a7075.png"
  - "https://kibebe.com/cdn/shop/files/2023usabib_2.png"
  - "https://kibebe.com/cdn/shop/files/toyskibebe.com2023edit_2.png"
vendor:
  name: "Kibebe"
  phone: ""
  whatsapp: ""
  email: "info@kibebe.com"
  location: "Dzaleka Refugee Camp, Malawi"
status: "active"
featured: true
datePosted: 2024-11-20
tags:
  - baby
  - handmade
  - fair-trade
  - eco-friendly
  - sustainable
externalLink: "https://kibebe.com/collections/baby"
With markdown content:
## Kibebe Baby Products

Fair Trade Certified artisan products handcrafted in Malawi.

### Available Items:
- **Baby Lion Onesie** - $26.00
- **Baby Bibs** - $10.00
- **Baby Squeaky Toys** - $10.00
- **Ecofriendly Baby Rattles** - $14.00
- **Baby Sensory Play Mat** - $39.00

All products are handmade by skilled artisans and are eco-friendly.

**Shop online:** [kibebe.com](https://kibebe.com)

How to List a Product or Service

1

Create Listing File

Create a Markdown file in src/content/marketplace/ with descriptive slug:
touch src/content/marketplace/handwoven-baskets.md
2

Add Listing Metadata

Fill in the frontmatter:
---
title: "Handwoven Traditional Baskets"
description: "Beautiful handmade baskets in various sizes, perfect for storage or decoration. Made from natural materials."
type: "product"
category: "arts-crafts"
price: "MWK 2000 - 8000"
currency: "MWK"
priceType: "range"
images:
  - "/images/marketplace/basket-1.jpg"
  - "/images/marketplace/basket-2.jpg"
vendor:
  name: "Amani Crafts Collective"
  phone: "+265 999 123 456"
  whatsapp: "+265 999 123 456"
  email: "amani@example.com"
  location: "Dzaleka Refugee Camp, Block 3"
status: "active"
featured: false
datePosted: 2025-03-09
tags:
  - handmade
  - baskets
  - traditional
  - storage
---
3

Write Product Details

Add rich markdown content:
## About Our Baskets

Each basket is carefully handwoven by skilled artisans using traditional 
techniques passed down through generations. Made from locally-sourced 
natural materials.

### Sizes Available
- **Small** (20cm) - MWK 2,000
- **Medium** (35cm) - MWK 5,000
- **Large** (50cm) - MWK 8,000

### Features
- Durable and long-lasting
- Eco-friendly materials
- Unique patterns and designs
- Supports local artisans

### How to Order

Contact us via WhatsApp at +265 999 123 456 or email amani@example.com.
Custom orders and bulk discounts available!
4

Preview Listing

Test locally:
npm run dev
# Visit: http://localhost:4321/marketplace

Seller Submission Flow

Vendors can submit listings via /marketplace/submit:
  1. Fill Form: Enter product/service details and upload photos
  2. Image Upload: Photos uploaded to cloud storage (Cloudinary/similar)
  3. Submit: Form data sent to admin for review
  4. Approval: Admin creates content file after verification
  5. Go Live: Listing appears on marketplace
  6. Success Page: Seller redirected to /marketplace/success
  7. Sales: Buyers contact seller directly via provided channels

Stores Feature

Separate from individual listings, the platform has a Stores section (/marketplace/stores) for brick-and-mortar businesses:

Store Registration

Businesses register at /marketplace/stores/register:
  • Restaurant/shop name
  • Business type (Restaurant, Cafe, Shop, Bakery, etc.)
  • Location and operating hours
  • Menu/product offerings
  • Contact information
  • Photos of establishment

Store Schema

Stores stored in src/content/stores/:
name: "Jali's Restaurant"                    # Required
type: "restaurant"                           # restaurant | cafe | shop | bakery | other
description: "Authentic Congolese cuisine"   # Required
location:
  address: "Main Street, Block 5"
  coordinates:
    lat: -13.7746
    lng: 33.9249
contact:
  phone: "+265 XXX XXX XXX"
  whatsapp: "+265 XXX XXX XXX"
  email: "jali@example.com"
hours:
  monday: "8:00 AM - 8:00 PM"
  tuesday: "8:00 AM - 8:00 PM"
  # ... etc
menu:                                        # For restaurants
  - name: "Fufu with Chicken"
    price: "MWK 1500"
  - name: "Sambusa"
    price: "MWK 500"
images:
  - "/images/stores/jali-interior.jpg"
featured: true
status: "active"

Technical Implementation

Client-side filtering for instant results:
Marketplace Filtering
let activeType = 'all';      // all | product | service
let activeCategory = 'all';  // category filter

function getFilteredCards() {
  return listingCards.filter(card => {
    const cardType = card.dataset.type;
    const cardCategory = card.dataset.category;
    const typeMatch = activeType === 'all' || cardType === activeType;
    const categoryMatch = activeCategory === 'all' || cardCategory === activeCategory;
    return typeMatch && categoryMatch;
  });
}

function updatePagination() {
  const filteredCards = getFilteredCards();
  const totalPages = Math.ceil(filteredCards.length / itemsPerPage);
  
  // Show only cards for current page
  const startIndex = (currentPage - 1) * itemsPerPage;
  const endIndex = startIndex + itemsPerPage;
  filteredCards.slice(startIndex, endIndex).forEach(card => {
    card.style.display = 'block';
  });
}

Price Display Logic

Handles different pricing scenarios:
Price Rendering
function renderPrice(listing) {
  if (listing.priceType === 'free') {
    return 'Free';
  } else if (listing.priceType === 'contact') {
    return 'Contact for price';
  } else if (listing.price) {
    // Auto-format if currency not included
    if (listing.price.includes('USD') || listing.price.includes('MWK')) {
      return listing.price;
    }
    return `MWK ${listing.price}`;
  }
  return 'Contact for price';
}

Book Detection

Books get special styling:
Book Category Handling
const isBook = listing.data.category === 'books-media';

// Different image display for books
<img 
  class={isBook ? 'object-contain p-4' : 'object-cover'}
  src={listing.data.images[0]}
/>

// Different badge color
<span class={isBook ? 'bg-amber-100 text-amber-800' : 'bg-green-100 text-green-800'}>
  {isBook ? 'Book' : listing.data.type === 'product' ? 'Product' : 'Service'}
</span>

Pagination

8 items per page with navigation:
Pagination Controls
const itemsPerPage = 8;
let currentPage = 1;

prevBtn?.addEventListener('click', () => {
  if (currentPage > 1) {
    currentPage--;
    updatePagination();
  }
});

nextBtn?.addEventListener('click', () => {
  const totalPages = Math.ceil(filteredCards.length / itemsPerPage);
  if (currentPage < totalPages) {
    currentPage++;
    updatePagination();
  }
});

Categories

Product/Service Categories

  • food-beverages - Food & Beverages
  • clothing-fashion - Clothing & Fashion
  • electronics - Electronics
  • home-garden - Home & Garden
  • health-beauty - Health & Beauty
  • arts-crafts - Arts & Crafts
  • books-media - Books & Media
  • education-tutoring - Education & Tutoring (services)
  • repair-maintenance - Repair & Maintenance (services)
  • professional-services - Professional Services
  • other - Other

WhatsApp Integration

Direct WhatsApp links for instant contact:
WhatsApp Button
<a 
  href={`https://wa.me/${vendor.whatsapp.replace(/[^0-9]/g, '')}`}
  class="whatsapp-button"
  target="_blank"
>
  <svg><!-- WhatsApp icon --></svg>
  Chat on WhatsApp
</a>

Best Practices

High-Quality Photos

Use clear, well-lit images. Minimum 800x800px. Show multiple angles for products.

Accurate Descriptions

Be honest about condition, size, materials. Include measurements when relevant.

Responsive Pricing

Research market rates. Consider offering bundle discounts.

Fast Communication

Respond to buyer inquiries within 24 hours. Keep contact info current.

Seller Tips

  • Research similar items on the marketplace
  • Consider your costs (materials, time, overhead)
  • Factor in quality and uniqueness
  • Be willing to negotiate for bulk orders
  • Offer discounts for repeat customers
  • Use natural daylight when possible
  • Plain background (white or neutral)
  • Show product from multiple angles
  • Include size reference (coin, ruler, hand)
  • Display products in use when applicable
  • Avoid filters - show true colors
  • Meet in public places for in-person exchanges
  • Use trusted payment methods (mobile money: Airtel Money, TNM Mpamba)
  • For shipping, use tracked services
  • Keep records of all transactions
  • Get buyer confirmation before marking as sold

Troubleshooting

Images can be:
  • Local: /images/marketplace/item.jpg (in public/images/marketplace/)
  • External: Full HTTPS URL from image hosting service
Check that:
  • File extension is included (.jpg, .png)
  • URL is accessible (test in browser)
  • YAML array syntax is correct (dash, space, quoted URL)
Ensure category value matches exactly:
category: "arts-crafts"  # Correct - lowercase with hyphen
category: "Arts & Crafts" # Wrong - won't match filter
Use one of these formats:
price: "5000"            # Auto-adds MWK
price: "MWK 5000"        # Displays as-is
price: "USD 25"          # Displays as-is
price: "MWK 2000 - 8000" # Range
priceType: "contact"     # Shows "Contact for price"