All work / 05 of 07 · AI & web

Edith Moen Coaching.

A Next.js coaching website rebuilt in one day to replace a dated WordPress install — custom backend CMS, full UTM tracking, SEO-ready metadata, Resend transactional email, and a SQLite content layer. Better than what she had, faster than anyone expected.

Client
Edith Moen — Christelijke life coach, Netherlands
Role
Solo full-stack engineer & designer
Year
2026
Time to ship
One day
Live
edithmoencoaching.nl
Edith Moen Coaching homepage on a MacBook — Dutch life coaching site
01 · Context

A WordPress site that had done its job — once.

Edith Moen is a Christian life coach based in the Netherlands offering one-on-one coaching and her signature TotalBalance program. Her existing WordPress site was functional but dated — slow, visually heavy, hard for her to edit, and not built to track where her visitors were coming from.

The ask was simple: build something cleaner, faster, and better — with a CMS she could actually use herself, without calling a developer every time she needed to change a paragraph. The unstated ask was: do it fast.

02 · The constraint

One day. Full rebuild. Production-ready.

This wasn’t a sprint where “production-ready” means “it loads without erroring.” To call it done meant all of this had to work:

  • Full Dutch-language site with five pages (home, coaching, TotalBalance, blog, contact)
  • Custom admin CMS at /admin — login, dashboard, post editor, pricing editor, contact submissions inbox
  • Contact form with Resend transactional email (notification to Edith + auto-reply to visitor)
  • UTM parameter capture on every page load — source, medium, campaign, content, term
  • SEO: Open Graph, Twitter card, JSON-LD, canonical URLs, sitemap, robots.txt
  • Deploy to Fly.io (Docker-containerized Next.js + SQLite)
  • Client handoff doc with every credential and day-to-day how-to
03 · The CMS

A backend she can actually use — built from scratch in a few hours.

Instead of reaching for a headless CMS SaaS, I built a purpose-specific admin panel directly into the Next.js app. It has exactly the screens Edith needs and nothing she doesn’t.

Edith Moen CMS admin dashboard on a widescreen monitor

Admin dashboard: quick stats, recent submissions, one-click nav to every editable section.

Blog post list — draft/published status, edit buttons

Post list — draft / published status, instant edit.

Blog post editor with title, slug, content body, publish toggle

Post editor — title, slug, rich content, publish toggle.

Contact form submissions inbox — name, email, message, UTM data

Submissions inbox — every contact form entry with UTM attribution so Edith knows exactly which channel generated the lead.

04 · Architecture

Next.js App Router + SQLite. Small footprint, zero vendor lock-in.

Visitor lands → UTM params captured in middleware → stored per-session │ ▼ Next.js App Router (Server Components + API Routes) │ ├── / Home, coaching, TotalBalance, blog pages ├── /admin Custom CMS (auth-gated, cookie session) └── /api Contact form → Resend → notification + auto-reply │ ▼ SQLite (via Drizzle ORM) — posts, pricing, content, submissions │ ▼ Fly.io — Docker container, persistent volume for DB

Stack

Next.js (App Router) React 19 TypeScript Tailwind CSS SQLite + Drizzle ORM Resend Fly.io (Docker)

Key decisions

  • SQLite over Postgres. A single-author coaching site with low write volume. No connection pooling overhead, no cloud DB cost, ships inside the same Docker container. Drizzle migrations keep the schema clean.
  • Custom CMS instead of a headless SaaS. Edith needed exactly four editable surfaces: blog posts, pricing, page content, and her contact inbox. A bespoke panel with those four screens is faster to build and faster to use than explaining Sanity or Contentful to a non-technical client.
  • UTM middleware at the edge. Every page load captures UTM params server-side before any React hydration. They land in the submissions table alongside every contact form so attribution is never lost.
  • Resend over SMTP. The hosting provider’s SMTP was unreliable. Resend gives deliverability, API-key rotation without code changes, and a free tier that easily covers Edith’s volume.
  • One-day scope discipline. No animations, no image optimization pipeline, no analytics dashboard. Everything that mattered shipped; everything that could wait didn’t make the cut.
05 · SEO & UTM setup

Fully instrumented on day one.

Every page exports a generateMetadata() function — unique title, description, Open Graph tags, Twitter card, and JSON-LD structured data. A dynamic sitemap.ts includes all published blog posts automatically. robots.txt blocks the /admin subtree.

UTM tracking is captured in Next.js middleware so it runs before any client-side JavaScript. The values are stored with every contact form submission, giving Edith a clear picture of which campaigns drive leads — even if she never opens Google Analytics.

06 · Outcome

A production site and a handoff doc, delivered in a day.

The rebuild went live at edithmoencoaching.nl. Edith received a full client handoff document covering every credential, every day-to-day task (how to add a post, how to read her contact inbox, how to reset her password), and escalation contacts for hosting and email issues.

The old WordPress site had no UTM tracking, no submission inbox, and no way for Edith to update content without FTP access. The new one does all three from a browser tab — and it loads faster.

Edith Moen coaching page on a MacBook — services and process

Coaching page — services, process, and a clear path to the contact form.