← Railwayhero
CRM Project

Railwayhero · Website

How Metawork set up Pipedrive CRM for an international luxury rail travel platform — B2B wholesale pipeline management and a custom importer for The Ghan and Rovos Rail booking data.

Duration 15 days
Tasks 36

africanexplorer.de

What was built

Railwayhero does not run one website. It runs one per destination, and the list keeps growing. So the job was never just "rebuild the African Explorer site". It was to rebuild it in a way that the next site costs a fraction of the first.

We moved the site off Next.js and onto Astro, static, with React kept only where something is actually interactive. The awkward part was the data. Nine thousand lines of trains, routes, cabins, departures and price tables sat in a single TypeScript file that every component imported directly. We split it into typed content collections on disk and repointed every consumer, then deleted the original file so there is one source of truth instead of two that drift. The build now emits 68 pages, all trip detail pages included.

Hosting moved from Firebase to GitLab Pages with a CI pipeline, and both domains moved onto Cloudflare. We ported the redirects, added the SEO layer the old site never had, Open Graph, Twitter cards, schema.org for the agency and for each journey, and kept a single switch that de-indexes a preview build so a staging copy can never compete with the live site in search.

The site is also the template

The reusable parts live as their own packages. A shared inquiry schema defines the shape of a request once. A funnel engine renders the six-step inquiry form from that schema, with the endpoint, the steps and the trip data supplied per site. Everything that is specific to a destination, the palette, the imagery, the routes, the price tables, sits in content collections and one site config file. A new destination site starts from that skeleton and replaces the content, not the code. African Explorer runs on it today. Kanada and Spanien are next in line.

This shape was chosen deliberately, because the quirks that used to be hardcoded now have to be data. Which cabins a departure offers, whether a step is skipped, which price table gates a transition, all of it moved into configuration so that the engine stays the same across sites.

The form pipeline

Inquiries used to be emailed. If the mail failed, the lead was gone, and the client retyped what survived into Pipedrive by hand. A Make scenario covered part of the hop.

We replaced that with one Cloudflare Worker serving a route per site. A submission is written to a D1 database first and answered immediately, so the record is durable before anything else can fail. The Pipedrive write happens after the response: person matched by email or created, deal created and linked, train, route, cabin, travel dates, party size and the free-text message mapped onto the real custom fields, and a note attached. Failures stay in the queue and a cron job re-drives them with backoff, with a fallback email if a submission cannot be delivered at all.

The middleware is the part that earns its keep. Each route accepts its own origin only, so a misconfigured origin fails loudly instead of silently dropping leads. A honeypot and a Turnstile check reject bots before anything is written. A per-IP rate limit absorbs bursts, and an idempotency key on site, email and minute means a double click never produces two deals in the CRM.

The cutover ran with the old path still live, then the Make scenario was switched off once the new one had run clean.

Changes in minutes, not weeks

This is the point of the whole project. The client changes his website through Claude. He describes what he wants, a new journey, a different price, another question in the inquiry form, and the change is live within minutes. Before, the same change meant days and weeks of back and forth with a design agency.

We built the site for that. The content sits in plain structured files. The Pipedrive field mapping is one readable file. The settings for each site are one config file. A new destination site is meant to start from a brand name and a domain. The client does not wait for us, and he does not wait for anyone else.

Tech stack

  • Astro: Static site framework for all Railwayhero destination sites, with React islands only where the page is interactive.
  • Tailwind CSS v4: Design tokens and the shared brand-agnostic layout skeleton.
  • GitLab Pages: Hosting and CI, custom domain with automatic certificates.
  • Cloudflare: DNS and proxy in front of the sites, plus Workers and D1 for the inquiry pipeline.
  • Cloudflare Turnstile: Bot defence on the inquiry form.
  • Pipedrive: Every inquiry lands as a linked person and deal in the client's CRM.

Recently touched

  • 2026-09-17 Analyse African Explorer Redesign repo and reformat to MWS website scaffolder Open
  • 2026-09-17 africanexplorer.de: Cloudflare-Proxy einrichten + Cache-Purge beim Deploy (Creatio-Parität) Open
  • 2026-09-17 Cloudflare Workers + D1: secure form submissions → Pipedrive (replace Make) Done
  • 2026-09-16 Extract "Railwayhero Core" repo from African Explorer Redesign; make existing sites children Open
  • 2026-09-16 Host all Railwayhero sites on GitLab Pages, retire Firebase Done

Other projects in this case study

  • Pipedrive Onboarding

    Railwayhero's Pipedrive CRM was configured to manage B2B wholesale booking operations for premium train journeys (The Ghan in Australia, Rovos Rail in Africa, and others). The system integrates…

    Read case study
  • Ghan Importer

    The Ghan Importer is a dedicated integration system that syncs booking data from The Ghan train operator's system into Railwayhero's Pipedrive CRM. This custom solution enables automatic deal…

    Read case study