Index

Ndito Travel

A high-performance safari booking platform and multi-locale expedition catalog engineered for an Arusha-based tour operator in Tanzania.

Lead Full-Stack Engineer2024 — PresentClient projectView live ↗
50Catalog routes & packages
113+Indexable static pages
< 800msLead dispatch latency

High-Ticket Tourism Logistics & Conversion Latency

Ndito Travel is an accredited Tanzanian expedition outfitter and tour operator headquartered in Arusha and Moshi, running Mount Kilimanjaro summit climbs across all 7 routes, Northern and Southern circuit wildlife safaris, and Zanzibar beach holidays. In high-ticket adventure travel, transaction sizes range from $750 budget camping trips to $5,000+ luxury fly-in expeditions, with international guests researching itineraries months in advance across North America, Europe, and the Middle East.

Traditional East African safari operators rely heavily on static PDF brochures and unformatted email contact forms. This structure forces international travelers into 12- to 24-hour asynchronous email exchanges merely to obtain basic vehicle day rates, seasonal migration windows, or altitude acclimatization profiles, resulting in significant funnel drop-off during peak booking seasons.

The objective was to architect a high-performance, statically pre-rendered platform featuring dynamic tiered group pricing matrices, an intent-propagating booking wizard, an in-memory grounded AI safari consultant, and an asynchronous dual-channel dispatch engine that pairs Cloud Firestore logging with local Tanzanian SMS gateway webhooks to alert operations guides immediately in the field.

Ndito Travel safari package catalog, day-by-day itinerary timeline, and booking wizard interface
Multi-locale expedition catalog and responsive multi-step booking engine engineered for Ndito Travel in Arusha, Tanzania.

Static Generation, Localized Routing, and Grounded Context Architecture

To deliver sub-second page loads across both high-bandwidth international travelers and low-bandwidth local cellular networks, the application was built with the Next.js App Router using full Static Site Generation (SSG). Over 113 indexable routes—spanning 50 safari packages, 31 destination directories, 6 Kilimanjaro route guides, and 14 technical preparation articles—are pre-rendered at build time with comprehensive Schema.org JSON-LD structured data(TouristTrip, TouristDestination, TouristExperience, and FAQPage schemas). Subpath internationalization with next-intl manages 6 locales (English, German, French, Spanish, Chinese, and Arabic), applying dynamic layout direction switching (dir="rtl") for Arabic visitors.

To provide instant 24/7 technical route guidance without expensive vector database infrastructure or LLM hallucination risks, the AI consultation endpoint compiles static TypeScript domain catalogs directly into zero-shot system instructions in server memory. This enables the model to cite exact inclusion lists, summit success probabilities, and parameterized booking URLs (/book?package=...&source=chat-assistant) without incurring external retrieval latency.

The booking pipeline uses a multi-step state machine with smart URL query parameter resolution, mapping visitor entry points directly into pre-populated form steps. Upon submission, the engine writes atomic booking records to Firebase Firestore and triggers an asynchronous, non-blocking webhook to Tanzania's local Meseji SMS gateway (meseji.co.tz). This dispatches passenger counts, travel dates, and guest contact channels directly to field coordinators over standard GSM cellular networks without stalling the client-side UI confirmation.

src/app/api/chat/route.ts
    const activeSessionId =
      sessionId || `chat_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;

    const contents = [
...(history || []).slice(-10).map((m) => ({
        role: m.role,
        parts: [{ text: m.content }],
      })),
      { role: "user", parts: [{ text: message }] },
    ];

    const response = await fetch(`${GEMINI_URL}?key=${apiKey}`, {
      method: "POST",
      headers: { "Content-Type":  "application/json" },
      body: JSON.stringify({
        contents,
        systemInstruction: { parts: [{ text: SYSTEM_CONTEXT }] },
  generationConfig: { temperature: 0.5, maxOutputTokens: 500 },
      }),
    });

    if (!response.ok) {
      if (response.status === 429) {
 return NextResponse.json({ error: "rate_limited" }, { status: 429 });
      }
      return NextResponse.json({ error: "Upstream AI error" }, { status: 502 });
    }

    const data = await response.json();
    const reply =
      data?.candidates?.[0]?.content?.parts?.[0]?.text ??
      "Sorry, I couldn't come up with a response — please try rephrasing, or reach us directly.";

    // Asynchronously log full conversation thread to Firebase Firestore ('chat_conversations')
    const fullHistoryForLog = [
      ...(history || []),
      { role: "user" as const, content: message },
      { role:  "model" as const, content: reply },
    ];

    saveChatConversationToFirestore(activeSessionId, message, reply, fullHistoryForLog).catch((err) =>
 console.error("Failed to log chat conversation to Firestore:", err)
    );

    return NextResponse.json({ reply, sessionId: activeSessionId });

Grounded AI chat endpoint utilizing Gemini Flash-Lite with in-memory catalog context compiled from static domain registries. Asynchronous fire-and-forget logging to Cloud Firestore maintains a CRM audit trail without adding latency to the client response.

113+Indexable static pages
< 720msFirst contentful paint
6Supported locales
< 800msLead dispatch latency

Operational Impact & Technical Takeaways

Transitioning from static brochure pages to structured, intent-propagating booking funnels and instantaneous cellular SMS dispatch dropped operational quote turnaround from over 18 hours to under 15 minutes. Dispatching SMS payloads to field guides guarantees immediate situational awareness during game drives across the Serengeti and Ngorongoro conservation zones where mobile internet data coverage is intermittent.

Client-side telemetry was instrumented through a custom PostHog wrapper that enforces privacy-first data collection: guest names, emails, phone numbers, passport details, and medical dietary requirements are strictly stripped in the browser prior to event dispatch. This preserves visitor conversion funnel visibility across wizard steps without storing sensitive traveler identifiers in external analytics infrastructure.

The project demonstrates that high-craft engineering for East African commercial enterprises requires synthesizing modern edge web standards—pre-rendered static HTML, subpath locale negotiation, and zero-CLS image pipelines—with pragmatic regional operational primitives like local GSM SMS gateways and WhatsApp routing.