
Healthcare · ServiHealth Tunisie
Problem
ServiHealth Tunisie sells medical tourism - cosmetic and dental procedures in Tunisia - to a French-speaking audience that compares clinics online before committing. The site has one job: turn a comparison-shopping visitor into a quote request. Its content changes constantly (procedures, surgeons, prices, FAQs, testimonials), and every lead has to reach the sales team inside Odoo. A lead sitting unread in a website inbox is a patient lost.
My scope
I built both halves of the system: the Next.js frontend and the Strapi 5 CMS behind it - the content model, the form and lead pipeline, the SEO plumbing, and the production deployment.
System architecture
The frontend is Next.js 15 (App Router) with locale-based routing and RTL support. It renders content from a separate Strapi 5 CMS on MySQL through typed fetchers, each with its own revalidation window so stable pages stay fast while prices and offers stay fresh. The CMS models the entire site across 31 content types: procedures and procedure categories, surgeons, pricing pages, FAQs, testimonials, blog articles, and every landing page from home to legal.
The conversion path is a pipeline, not a form post. The three form types (contact, quick quote, detailed quote) submit to the CMS, which forwards each lead to the client's Odoo CRM, emails a copy over SMTP, and records every delivery attempt in a delivery log the team can audit.
Key decisions
- Headless split. A fast, SEO-focused public frontend, and an editor-friendly Strapi admin the client team already knows how to drive. Neither side compromises for the other.
- Leads are a pipeline, not a form post. Odoo forwarding plus an email copy plus a delivery log means a failed send is visible and recoverable instead of silently lost.
- Content modelled, not hardcoded. Procedures, surgeons, tariffs and FAQs are CMS content types, so the team launches a new procedure page without touching code.
- SEO treated as a system. The sitemap is generated from live CMS content and deliberately excludes pages that refuse indexing, so search engines only receive URLs that are meant to rank.
Stack
- Frontend - Next.js 15 (App Router), React 19, TypeScript, Sass, Swiper
- CMS - Strapi 5, MySQL, Nodemailer (SMTP), Odoo CRM integration
- Deploy - Docker on EasyPanel; site at servihealth-tunisie.com, CMS at cms.servihealth-tunisie.com