Emmanuel Doji

Portfolio · 2026

000%

All case studies

Foniolabs · 2026 · Lead engineer

Foniolabs.xyz — Sanity + Next.js + Claude Code MCP

Document types modelled
9
Reusable section blocks
8
Lighthouse (mobile)
95+
SEO ranking drop after cutover
0

The brief

Foniolabs is my personal lab — where I experiment with tech for education and web3 in my own time. Its site was a Next.js static export on shared hosting, and every copy change ran through code. I wanted a CMS migration that didn't degrade SEO or shipping velocity, and three things specifically:

  1. Editor-friendly content modeling for fast, non-technical editing
  2. SEO continuity — no ranking drop after the cutover
  3. An AI-native workflow — content via natural language, not Studio clicking

Constraints

  • 14 calendar days, ~45 working hours of mine across that window
  • Zero downtime — DNS swap on Day 13
  • Free-tier infrastructure (Sanity free, Vercel hobby, GA4 free)
  • 100% of public URLs preserved with 301s where slugs changed

What I built

Content model — 9 documents (siteSettings, navigation, page, post, author, product, teamMember, seo, redirect) + 8 reusable section blocks (hero, featureGrid, richText, cta, testimonial, logoCloud, embedHtml, contactForm). Pages compose from sections; I recombine blocks without touching code.

Custom Studio components — a SlugInput that auto-creates a redirect document when a URL changes; a Google snippet SEOPreview; a live OGImagePreview that renders the /api/og edge route inline; a presentation tool wired to Next.js draft mode for true live preview.

Migration script — idempotent, asset-uploading, with a dry-run mode and seeded singletons that survive re-runs (createIfNotExists). Every legacy URL maps to a new Sanity document or a 301 redirect.

Claude Code + Sanity MCP — hosted MCP server registered at the repo root via .mcp.json. From inside Claude Code, "create a news post titled X, set publishedAt to today, assign author Z" lands real documents in production. Documented in OPERATING.md with a prompt cheat sheet I can come back to.

Results

  • Live on Vercel; Sanity Studio embedded at /studio
  • Lighthouse 95+ across Performance, Accessibility, Best Practices, SEO on mobile
  • Zero SEO ranking drop after DNS cutover — every legacy URL resolves via 301 or new page
  • I publish content by prompting; schema and blocks stay in code

What I learned

Sanity's "compose pages from section blocks" pattern is the difference between a CMS you actually use and a CMS you avoid. Modeling at the block layer — not the page layer — lets you recombine without ever reaching back into a new schema.