< back to work > case_study

> · featured

CyclingHero

CyclingHero: Bike Tours and Cycling Trips in Italy

Custom bike tours through the Dolomites, Veneto, and Tuscany — itineraries built around the rider, with the logistics quietly handled in the background.

Stack

  • Next.js
  • React
  • Node.js
  • TailwindCSS
  • CSS 3
  • Contentful API

Engagement

  • statuslive
  • modelretainer
  • since2022
  • > long-running engagement on the site + admin

CyclingHero runs custom bike tours through the prettier corners of Italy — Dolomites, Veneto, Tuscany, the climbs you’ve seen on Eurosport. Riders get a tailored itinerary, real human support on the road, and gear that handles the boring logistics so they can focus on suffering productively up a mountain.

The trip stack is hands-on: curated routes, hand-picked stays, daily van support, and a CyclingHero Companion App paired with a pre-loaded Hammerhead Karoo-2 so nobody has to wrestle with GPX files at 6 a.m. in a hotel lobby. Pitch is roughly: we’ll handle the wiring, you handle the riding.

~/cyclinghero

$ tplocic stats

  • years on the project 4+
  • content models in the system 48
  • lines in the i18n query engine 549
~/cyclinghero

The bits that make it different:

  1. Trip planning that’s actually personal — itineraries are sketched around the rider, not a prefab brochure. Beginner who wants long lunches? Fine. Returning ex-racer trying to relive their twenties? Also fine.
  2. The unsexy stuff is handled — airport transfers, luggage, bike box storage, bike build. Nobody brags about logistics, but they’re what stops a holiday from feeling like a project.
  3. Navigation that doesn’t fight you — multiple route options each day, served on the Karoo and in the app, with local context the route file alone won’t tell you.
  4. Van support on every ride — daily van, on-trip luggage transfers, and general “we’ll come find you” energy, which is more reassuring than it sounds when you’ve cracked at km 80.
  5. Boutique stays, real Italy — small accommodations with character, instead of chain hotels with breakfast buffets you’re already tired of.
~/cyclinghero

My role: frontend developer

Long-running engagement on the Companion App, the marketing site, and the admin environment that holds it all together. Not a “ship a site and disappear” relationship — more like four+ years of slowly turning something scrappy into something solid.

The work, in plain terms:

  • Core app & admin — built and maintain most of the customer-facing site and the admin tools the team plans trips with. The unglamorous half is usually where the leverage lives.
  • Performance — when the app is the thing on a rider’s bars at 8 a.m. on a foreign mountain, fast and predictable beats clever every time.
  • Steady, boring shipping — features land, bugs die, regressions stay rare. Less drama, more compounding improvement.
  • Working with design & product — translating intent into something that holds up on a small screen, in direct sunlight, with cold fingers.
  • Working with backend & mobile — keeping data flow and UX consistent across web and native, which is harder than the architecture diagrams suggest.

One bit worth pointing at

Instead of shipping the whole i18n bundle to every page, I built a tiny query language so each route declares only the categories, keys, and fields it actually renders — wildcards and filter conditions included for the awkward cases. The merger combines per-component queries server-side and ships back the smallest possible slice. Per-page payloads dropped a lot, and the app went from “fine” to genuinely snappy.

~/i18n
page route
│
├─ <ComponentA queries=…> ─┐
├─ <ComponentB queries=…> ─┤
└─ <ComponentC queries=…> ─┘
                           │
                           ▼
                ┌──────────────┐
                │    merger    │ ◀── full i18n catalog
                │ (server-side)│
                └──────┬───────┘
                       │
                       ▼
                trimmed payload
                (only the keys
                the page renders)
query
              
                {
  "query": {
    "generic_text": {
      "keys": [
        "homepage*"
      ],
      "fields": [
        "title",
        "body"
      ]
    },
    "static_page_content": {
      "keys": [
        "homepage"
      ],
      "fields": [
        "seotitle",
        "seoimage.url",
        "seodescription",
        "title",
        "header",
        "description",
        "splashimage.url",
        "cta_label",
        "cta_link"
      ]
    },
    "list.homepage-featured_trips.items": {
      "fields": [
        "title"
      ]
    }
  }
}
              
            
result
              
                {
  "generic_text": {
    "homepage_tours-title": {
      "title": "Dolor Sit Amet"
    },
    "homepage_regions-title": {
      "title": "Consectetur Adipiscing"
    },
    "homepage_how-we-roll": {
      "title": "Incididunt Ut Labore",
      "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
    },
    "homepage_choose-your-bike": {
      "title": "Ullamco Laboris",
      "body": "Nisi ut aliquip ex ea commodo consequat."
    },
    "homepage_tours-description": {
      "title": "Dolor Sit Amet",
      "body": "Error sit voluptatem accusantium doloremque laudantium."
    }
  },
  "static_page_content": {
    "homepage": {
      "seotitle": "Lorem Ipsum Dolor | Sit Amet",
      "seoimage": {
        "url": "https://images.example.com/space/asset-seo/hero-image.jpg"
      },
      "seodescription": "Consectetur adipiscing elit, sed do eiusmod.",
      "title": "Lorem Ipsum Dolor Sit",
      "splashimage": {
        "url": "https://images.example.com/space/asset-splash/splash.jpg"
      }
    }
  },
  "list": {
    "homepage-featured_trips": {
      "items": {
        "01_lorem-ipsum-a": {
          "title": "Lorem A"
        },
        "02_dolor-sit-b": {
          "title": "Dolor B"
        },
        "03_amet-consectetur-c": {
          "title": "Amet C"
        },
        "04_adipiscing-elit-d": {
          "title": "Elit D"
        },
        "05_sed-do-eiusmod-e": {
          "title": "Eiusmod E"
        },
        "06_tempor-incididunt-f": {
          "title": "Tempor F"
        },
        "07_ut-labore-g": {
          "title": "Labore G"
        }
      },
      "items__keys": {
        "uid": "items__keys",
        "name": "items__keys",
        "value": "01_lorem-ipsum-a,02_dolor-sit-b,03_amet-consectetur-c,04_adipiscing-elit-d,05_sed-do-eiusmod-e,06_tempor-incididunt-f,07_ut-labore-g"
      }
    }
  }
}
              
            

I have been working with Tomasz for over four years. Much of the CyclingHero website was built by him, as well as all of our admin environment. He is both a talented Frontend Engineer, and a great person to work with. Tomasz consistently follows through with his commitments, and is always open to feedback. I would not hesitate to recommend Tomasz for any software project.

— Bob Rogers, CyclingHero, inc.