TL;DR
- Full rebuild of a legacy travel website on a custom WordPress framework: mobile-first Figma design system, repeatable modules via custom fields, modern travel-focused UI.
- Fully custom checkoutwired into the client's proprietary booking-availability API. No WooCommerce, no plugin chain: every checkout validation, real-time availability check, and rules engine written from scratch.
- Complex booking logic spanning quads, buggies, tuk-tuks, and boat rides; individual rider vs rider plus passenger configurations; adult, child, and infant validation; per-tour capacity and date logic.
- Performance budget held all the way through: 90+ PageSpeed scores on both desktop and mobile, achieved via dynamic transient caching, Redis object cache, image optimisation, and a hand-audited frontend bundle.
- Engagement is ongoing. We support the business day-to-day, run security and observability post-launch, and are in scoping for the next phase of work.
How the engagement started
Yippee Malta is the country's most-booked Gozo tour operator: quad and buggy day trips, tuk-tuks, sunset-edition versions of each, and a separate boat-charter line. The booking surface is genuinely complex: per-vehicle rider and passenger combinations, age tiers (adult, child, infant), per-day capacity, seasonal tours that only run mid-April through mid-October, and a proprietary in-house availability API the company already owned.
The client came to us with a fully built but ageing website. The UI was several brand cycles behind, the conversion path was leaky, and the underlying framework was an old WordPress build whose plugin chain had grown into a maintenance burden. They wanted a custom WordPress rebuild with a modern travel-focused design, a clean editorial backend, and a checkout that finally respected the complexity of their actual booking logic.
Stage 1: audit, analytics, and a mobile-first design system
The first month was deliberately not about code. We ran a full audit of the existing analytics (conversion funnel, drop-off heatmaps, device split, query intent across the highest-traffic landing pages) alongside a comparative industry scan of how the best tour-operator websites globally handle the same surfaces.
The dominant finding was not surprising but it was measurable: more than 80% of inbound traffic landed on mobile, and the existing site treated mobile as a second-class viewport. We made the call early to design mobile-first, with the desktop layout following the mobile flow rather than the other way around, the opposite of how most travel sites are still built.
Several Figma rounds followed. Each one focused on a specific surface in isolation (the homepage, the category index, the individual tour page, the booking widget) with the client reviewing and refining before we composed them into the full design system. Once the design system was locked, every subsequent page was built from the same components rather than designed individually.
The mobile-first decision shows up most clearly on the homepage. The booking entry point, the social proof, and the value summary all live above the fold on a mobile viewport, with no horizontal scroll, no hidden navigation, and a single primary call-to-action.
The desktop layout, when it loads, is the same flow expanded sideways: same primary CTA, same module order, same booking widget. Editors think in mobile first and the desktop view follows automatically.

Stage 2: custom WordPress framework with repeatable modules
The framework underneath the site is custom WordPress, no off-the-shelf theme. Every section the editor places on a page is a repeatable module backed by custom fields, so the marketing team can compose any new landing page from the same vocabulary without a developer in the loop. Hero, feature row, comparison grid, tour grid, testimonial strip, FAQ accordion, photo carousel, embedded video, and the booking-widget block all live as composable modules in the page builder.
The benefit is editorial speed: a new seasonal landing page for, say, Comino and Gozo boat trips can be drafted in 30 minutes from existing modules and published the same day. The benefit on the engineering side is that performance characteristics are predictable: every module has been hand-audited, so we know its render cost before it ever lands on a page.
Stage 3: the booking-availability API integration
Yippee Malta already owned a proprietary booking-availability API. That API knows, for any given tour and date, how many quad seats, buggy seats, tuk-tuk seats, or boat seats are still available, what the per-tier pricing is, what the cut-off windows are, and whether the tour is running at all (weather, operational holds, seasonal pauses). Our job was to wire the website's booking surface into that API cleanly, not to replace it.
The integration runs through a small server-side layer in WordPress that proxies the availability calls, applies short-lived caching (transients for under 5 minutes, invalidated on booking events), and returns a normalised shape that the frontend booking widget consumes. The widget itself is a small JavaScript component embedded into the tour page; it shows live availability the moment the user opens a calendar, updates as they pick participants, and surfaces real-time pricing without round-tripping the page.
Stage 4: a fully custom checkout
The checkout is where the rebuild paid for itself. The previous site relied on a plugin-driven booking flow that did not understand the product. Custom checkout means every validation rule lives in code we own:
- Per-vehicle rider and passenger rules. A buggy booking can be one driver alone, or one driver plus up to a configurable number of passengers, and the price tier changes accordingly. A quad booking can be solo rider only. The rules engine validates before the user can proceed, with inline error messages rather than checkout-page surprises.
- Age tier validation. Adult, child, and infant counts cross-check against per-tour rules. Some tours do not allow infants at all, some have a minimum child age, some allow a different child-to-adult ratio. All of these live as data, not as hard-coded conditionals.
- Real-time availability re-checks. A user can sit on the cart page for ten minutes, and by the time they hit pay the availability they originally saw may have moved. We re-validate against the API at the moment of payment intent creation, so a booking either confirms cleanly or fails into a user-friendly sold-out state before money moves.
- Multi-currency and multi-language. The checkout surface mirrors the rest of the site, serving the operator's European tourist mix in their own currency and language.
No WooCommerce. No plugin chain. Every line of checkout logic was written and audited by us.

Stage 5: performance, 90+ Core Web Vitals across both layouts
The performance budget was set early and we held it through every release. The site hits 90+ PageSpeed Insights mobile and desktop scores in production, uncommon for an image-heavy travel site, where image weight alone usually drives mobile LCP into the red.
The two main levers:
- Dynamic caching using WordPress transients.Per-page fragments (the tour grid, the testimonial strip, the booking-widget's availability digest) cache for short windows and invalidate on booking events. Most page loads serve fully cached HTML; only the user-specific widget state is fetched live.
- Redis object cache in front of the WordPress database to keep p50 server response times under 100ms even under burst traffic from a multi-language campaign push.
On the frontend, the bundle is hand-audited: no page-builder plugins, no globally loaded JS framework, no heavy carousel libraries. Images are served as WebP at real-size with explicit width and height attributes; the booking-widget JS is loaded only on tour pages, not globally.
The shape of these decisions lines up exactly with what we find when we audit slow WordPress sites, covered in our companion WordPress performance data study across 100 sites.
Stage 6: security, observability, and abandoned-cart recovery
Post-launch, the engagement turned into a continuous-improvement loop. The security layer is intentionally multi-tier: hardened WordPress core (admin-URL change, login lockout, two-factor for editorial accounts), an application-layer WAF, rate-limited public endpoints, and proactive logging on every API touchpoint so unusual activity surfaces in real time instead of through a support ticket.
We also instrumented abandoned-cart recovery flows tuned to the booking funnel. A user who opens the booking widget but does not complete checkout gets a follow-up email sequence on a schedule that respects their original date choice, with the original tour, the original date, and a one-click resume URL that pre-fills the checkout. The recovery sequence runs entirely server-side; no third-party cart-recovery SaaS is layered into the stack.
The same hardened-WordPress posture matches the patterns in our companion WordPress plugin vulnerability study: the lowest-risk WordPress sites are the ones with the smallest plugin surface and the most observability.
