Gerard Llanas Logo
● Freelance · Custom CMS · Not public

TRAVEL AGENCY

A bespoke mini-CMS for a real agency.

Countries, itineraries, gallery with lightbox, FAQs and home content — every block editable from a custom backoffice, without ever touching the SEO keyword set.

Travel agency itineraries list

A custom CMS, tuned for travel.

Not WordPress. Not Strapi. A bespoke admin built around the agency's real workflow — Countries, Itineraries, Gallery, FAQs and Home content, each with its own editor surface.

  • One menu per content domain
  • Auto-optimized image uploads (resize + webp)
  • Inline preview before publishing
  • SEO keywords kept separate from content
● Privacy notePublic site stays unlisted in this case study — only the backoffice is shown, to keep client's real data off the portfolio.
Travel agency custom dashboard

One country, one page.

Every country is created from the backoffice with its own hero image, copy blocks and metadata. Itineraries snap onto a country once it exists — country lives at the top of the content tree.

  • Hero image per country, uploaded + optimized
  • Rich content blocks (title, lead, sections)
  • Country page auto-published with SEO routes
  • Drives the itineraries filter on the public site
  NEW COUNTRYcms · v2
NameSenegal
Slug/senegal
Hero copyWhere the desert meets the Atlantic —  edit ▸
SEO termssenegal, sahel, dakar   edit ▸
Hero image · 1920×1080 · auto-webp

Cards on rails.

Itineraries are created and attached to a country. Each one gets two editable surfaces: the card (the preview tile in the list) and the content (the detail page).

The public itineraries page filters by country — pick a flag, see the trips. The card preview is faithful to what the visitor will see.

Card editorContent editorFilter by countryAuto-routed
Itineraries list with country filters

Every block, editable.

The detail page is composed from editable blocks: hero, day-by-day plan, highlights, gallery and pricing notes. Reorder, rewrite or replace any of them from the backoffice without touching the codebase.

● Content blocksHero · Highlights · Day-by-day · Gallery · Pricing · FAQs. Each block is its own row in the CMS — add, hide, reorder.
Itinerary detail page

Upload heavy, serve light.

The client uploads full-res photos straight from their phone. The server resizes, converts to webp and stores variants. Visitors browse the gallery through a lightbox — fast and smooth on mobile.

  • Auto resize + webp on upload
  • Responsive `srcset` per image
  • Lightbox viewer with keyboard navigation
  • Per-country galleries (Senegal, etc.)
Senegal gallery with lightbox

FAQs, home content, SEO.

Three more editor surfaces close the loop. The home page reshapes itself from the CMS without ever touching the indexed keyword set.

FAQs

Question / answer pairs, reorderable. Used on the landing and on each itinerary's detail page.

Home content

Hero block, intro copy, featured countries, gallery teaser. The landing is fully editable without code deploys.

SEO keywords

Keywords live on a separate config decoupled from the editable content — so daily content tweaks never pollute the indexed term set.

Pragmatic build.

Picked tools that the client could host cheaply, that handle media well, and that I can extend fast when the agency asks for the next feature.

Next.js
React
MongoDB
Tailwind CSS
Node.js
Image optimization
Lightbox
Admin UI
REST API
Auth
Webp pipeline
Vercel
● Status — Built · Live (private) · Owned by client

Built for the road.

The site is in production and serving real customers. It's not linked publicly here to protect the client's data — the case study lives entirely on these screens.

Freelance · 2025

Designed, built and handed over end-to-end. Client owns the code.

Bespoke CMS

Custom backoffice, not a CMS framework. Less surface area, tighter UX for the team.

SEO-safe

Keywords decoupled from content. Editing copy never affects the indexed term set.