Esprit Guitare – Headless Migration

Cover Image for Esprit Guitare – Headless Migration
Pierre-Yves Léglise
Pierre-Yves Léglise
Posted underProjects


From Classic WordPress to a Headless Production Site

Production-ready migration for a local lutherie workshop


Esprit Guitare is a lutherie and electronics repair workshop based in Schœlcher, Martinique. The public website originally ran as a classic WordPress install (OceanWP theme, multiple plugins for booking, opening hours, reviews, forms, and SEO).

In July–August 2026, the site was migrated to a headless architecture: WordPress remains the editorial CMS, while a Next.js application serves the public frontend, APIs, and workshop admin tools. The visual identity stays close to the original site, with custom replacements for the heaviest plugins — especially appointment booking.

Live site: <https://www.espritguitare.fr/>

Context & Goals

  • Keep WordPress for content editing (pages, posts, media)
  • Remove front-end dependency on heavy WordPress plugins
  • Rebuild booking, opening hours, contact/quote forms, and reviews in the Next.js app
  • Preserve SEO (canonical URLs, redirects, sitemaps, cutover without downtime)
  • Deploy on a self-hosted VPS with Coolify (same pattern as other axialdata projects)

Technical Stack

Frontend:

  • Next.js 16 (App Router) + React 19
  • TypeScript 5.9
  • Tailwind CSS 4
  • Local SVG icons (no Font Awesome)
  • Zod 4 for validation
  • Cloudflare Turnstile on public forms and workshop login

CMS & content:

  • Headless WordPress
  • WPGraphQL with a custom endpoint slug (not the default `/graphql`)
  • HTML rewrite layer for media URLs, shortcodes, and image optimization via `/_next/image` (AVIF/WebP)
  • BreadcrumbList JSON-LD on marketing pages

Business data & APIs:

  • MongoDB + Mongoose 9 (opening hours, appointments, clients, reviews, blacklist, admin sessions, error logs)
  • Custom booking module (30-minute slots, date/slot blocks, blacklist by email / phone / name)
  • Twilio SMS + SMTP (Proton) for confirmations, J−1 reminders, review asks, and “instrument ready” notices
  • Nextcloud **CalDAV** push (create / update / cancel events) — public ICS subscription feed retired (`410`)
  • Nextcloud **CardDAV** sync (upsert client contacts via Mongo `Client` records)
  • Client self-service (`/mon-rdv`) + downloadable client ICS
  • Reviews: MongoCRUD in workshop admin; homepage carousel (`showOnHome`); `/avis` platform cards + paginated list

Deployment & ops:

  • Docker standalone image (`node:22-alpine`) on Coolify
  • pnpm via Corepack (`packageManager` in `package.json`)
  • GitLab self-hosted (`gitlab.axialdata.app`)
  • Rybbits analytics (`analytics.axialdata.app`) without visitor tracking cookies
  • Traefik rules: block legacy WP paths on `www` (`/wp-json`, `/wp-admin`, …) and redirect `/wp-content/…` crawls

Architecture

WordPress CMS (Hostinger)          Next.js app (Coolify VPS)
cms on espritguitare.fr            www + apex espritguitare.fr
• pages / posts / media            • public site + API routes
• WPGraphQL                        • workshop admin 
• no public front                  • staging: preprod (noindex)
        │                                    │
        └──────── GraphQL ───────────────────┤
                                             ▼
                              MongoDB · SMTP · Twilio · Nextcloud
                              (RDV, hours, clients, reviews,
                               blacklist, CalDAV, CardDAV)

Menus, phone, address, and review outbound links live in the Next.js codebase (siteConfig) — not WordPress menus — to keep the CMS thin.

Security & Hardening

  • Strict Content Security Policy with nonces
  • Security headers (HSTS, frame denial, referrer policy, etc.)
  • Turnstile on contact, quote, booking, and workshop login
  • Workshop admin: password auth, HTTP-only session cookie, Mongo-backed rate limit (5 failures / 15 min / IP)
  • Signed tokens for client self-service and review opt-out
  • Preprod blocked from search indexing (robots, X-Robots-Tag, empty sitemap when not production)
  • WordPress front disabled after cutover — CMS only
  • Edge filtering of legacy WordPress attack / scrape paths on the public host

Main Features

Public site:

  • Marketing pages and blog / réalisations listings from WordPress
  • Layout close to the legacy OceanWP design
  • Contact and quote forms (file upload on quote) with e-mail delivery
  • Search over published content (/recherche)
  • Opening hours status on the homepage (Mongo-driven)
  • Reviews page (/avis): leave-a-review CTAs, platform cards with per-source counts, paginated list of all Mongo reviews
  • Homepage reviews carousel (random mix by platform, showOnHome flag)
  • Article lightbox, TOC, reading time, SEO metadata (Open Graph / Twitter) + breadcrumbs JSON-LD

Booking (replaces Appointment Hour Booking):

  • Calendar wizard with available days and time slots
  • Blacklist enforcement server-side
  • Client + admin e-mail confirmations; SMS confirmation and reminder (~24h before)
  • Nextcloud CalDAV sync for the workshop agenda
  • Nextcloud CardDAV upsert on booking (via Client fiche)
  • Client ICS download + self-service cancel / reschedule (/mon-rdv)

Workshop back-office:

  • Ops dashboard (today / this week)
  • Appointments: create, reschedule, cancel, notification history
  • Instrument deposit flag (skipReviewAskAt — excludes auto review ask)
  • Manual review solicit + “instrument ready for pickup” mail/SMS
  • Clients CRUD (search, merge by phone/email rules, CardDAV)
  • Opening hours: weekly schedule + exceptional closures (create / edit / delete)
  • Slot blocks, blacklist, reviews CRUD, settings (timezone, slot duration)
  • App error log

SEO cutover:

  • DNS: apex + www → Next.js
  • Permanent redirects for legacy WordPress URLs
  • Trailing-slash convention aligned with historical WordPress URLs
  • Sitemap and canonical URLs generated by Next.js

Migration Approach

Work was delivered in phases (all shipped):

  1. Foundation — Next.js scaffold, WPGraphQL content, design parity, forms, mail, SEO basics, Coolify deploy
  2. Opening hours — Mongo module + homepage integration
  3. Booking — full RDV stack (API, UI, SMS, admin, blacklist)
  4. Reviews — initially WP-backed display; later moved to Mongo (import one-shot, mu-plugin retired)
  5. Cutover — DNS, headless CMS, redirects, preprod noindex, production hardening (7–8 Aug 2026)
  6. Phase 7 — CalDAV push, ops week view, error logs, self-service /mon-rdv, client ICS (13 Aug 2026)
  7. Phase 8 — Mongo Client + CardDAV; automated review ask J+1 with opt-out; instrument deposit / ready-pickup flows (Aug–Sep 2026)

The portfolio’s own headless WordPress + Next.js pattern was reused as a baseline, then extended with workshop-specific booking and ops features.

Outcome

  • Public site served by Next.js in production since 7–8 August 2026
  • WordPress reduced to a content/media CMS
  • Booking, hours, clients, and reviews no longer depend on third-party WordPress front plugins
  • Staging environment available for safe iteration without SEO duplication
  • Ongoing: relocation checklist (timezone, address, Twilio FR, Google Business Profile, etc.)

Resources:

<< Back

More projects :

Cover Image for Game event landing page demo

Game event landing page demo

Form validation. Simple landing page example to play with form validation in Javascript. Ressources : Live demo Github repository

Cover Image for MongoDbUtils

MongoDbUtils

MongoDB Backup & Restore Web Application Secure and Lightweight Fullstack Architecture MongoDbUtils is a fullstack application for managing MongoDB backups and restores. It lets you configure databases to back up, run backups on demand or on a schedule, restore existing dumps, and download backups from the browser. The application is built with security in mind: encrypted credentials, password-based authentication, rate limiting, and a […]