Content-managed web platform for a travel agency
Stack: Claude code · Next.js · Strapi · SASS · Resend · Vercel · Fly.io
A web platform for a travel agency, built on a modern architecture with a client-managed CMS. It lets them run destinations, itineraries and site content without going through a developer.
Context
A project to turn a static site into a modern, client-managed platform ready for production.
The visual starting point was an HTML template bought on Envato, used purely as a layout baseline. The design was already resolved, but it came with structural limits: hardcoded content, no CMS and no room to scale.
The client also had one clear requirement: they wanted to edit content, create new tours and update information without depending on a developer or running into technical hurdles.
Part of the work was building new components — the tour cards, for instance — and adapting elements of the template to what the project actually needed.
The goal was to turn that layout into a decoupled, flexible system centered on the client's autonomy.
Goal
Turn a static site into a platform that is:
- • Managed by the client.
- • Scalable to many destinations.
- • Decoupled (frontend + CMS).
- • Deployed on modern cloud infrastructure.
Architecture
A headless architecture was implemented, with a clear separation of responsibilities.
Tech stack
- • Frontend: Next.js (App Router)
- • CMS: Strapi
- • Styles: Modular SASS
- • Email: Resend API
- • Frontend deploy: Vercel
- • CMS deploy: Fly.io
Technical decisions
Frontend on Vercel
- • Native Next.js integration.
- • Environment variable handling.
- • Continuous deployment.
- • Automatic performance optimization.
CMS on Fly.io
- • A separate container for Strapi.
- • Fully separated from the frontend.
- • Scales independently.
- • An architecture ready to grow.
That separation lets the frontend and the backend evolve independently of each other.
Implementation
Migration to reusable components
The static HTML was turned into modular Next.js components, removing hardcoded content and structuring the application around reuse.
New components and adapted elements
New project-specific components were built — the tour cards, for example — which present each destination's information consistently (image, title, description, duration, price and so on) and get reused across listings and inner pages. Elements of the original template (sections, forms, content blocks) were also adapted to what was needed: the CMS data structure, responsive design and the site's navigation flows.
Data modeling
A structured Tours/Destinations collection was designed in Strapi, allowing for:
- • Configurable details.
- • Dynamic states.
- • Repeatable sections.
- • Day-by-day itineraries.
The focus was on a flexible model the client could manage without touching code.
Dynamic rendering
Pages are generated dynamically by slug from the CMS API, leaving the system ready for future additions such as filters, search or bookings.
Maintenance mode
If a page gets no data back from Strapi (the CMS is down, there is no published content, or a connection fails), the site automatically shows a maintenance view. That way visitors see a deliberate message instead of errors or blank screens.
The problem it solves
- • Complete client autonomy to update content.
- • Room to scale without duplicating code.
- • Decoupled, modern infrastructure.
- • A foundation ready to grow.
Result
- • A client-managed platform in production.
- • An optimized frontend in a serverless environment.
- • A backend deployed on its own cloud infrastructure.
- • An architecture ready for future integrations.
Built with care & love ❤️ 2026