Case Study - A Full-Stack Content Platform for Chip Reviews

My own chip-review platform, where one review becomes an article, social videos, and a newsletter in one brand voice. Built on Sanity, Next.js, and Remotion.

Client
Chipter
Year
Service
Web App Development · Headless CMS · Video Automation
The Chipter homepage: "Chips, rated by magnitude." above the latest reviews and their Chipter Scale scores

Overview

Chipter is a product I built for myself — a chip-review site with the ambitions of a media company and none of the staff. Every review has to go out as a polished article, a set of social videos sized for every platform, and an email, and all of it has to sound like the same opinionated narrator. So I built it as a content engine: the editor writes the review, and the platform handles the rest.

It's also my proving ground. Client work comes with budgets and deadlines; Chipter is where I get to find out how far a content platform can go when video, AI, and email live inside the CMS instead of being bolted on. What I learn here ends up in client builds.

The stack: Next.js 16, React 19, Sanity, Remotion, Cloudinary, Resend, and Clerk. See it live at chipter.io.


The Challenge

A review site lives or dies on its publishing cadence, and the work that usually slows that cadence isn't the writing — it's everything after. Each review wanted a square card for the feed, a vertical reel, a YouTube-ready cut, and an animated preview for Bluesky. That normally means a motion designer and a render farm. Chipter had neither.

Voice was the second problem. A chip review, a blog post, a newsletter subject line, and a 30-second video caption all have to sound like the same opinionated narrator — across hundreds of pieces, written on different days. A style guide alone won't get you there.

And it all had to behave as one system: the CMS, the video renderer, the asset CDN, the email platform, and user accounts couldn't be four disconnected tools bolted together.

If you run a marketing team, none of this is unique to chips.


The Solution

Automated video generation. The centerpiece. I built 15 Remotion video templates — compact review cards, dramatic score reveals, an oscilloscope-styled score trace, a terminal/ASCII cut, and long-form narrative pieces up to 75 seconds (a papercut "origin story" of the potato, a kinetic-typography brand manifesto). An editor picks a template inside Sanity Studio and the platform renders it on demand: serverless, in the cloud, no local tooling. The pipeline is idempotent — it never re-renders a video that already exists for a given review, template, format, and orientation — and it produces both MP4 and animated-GIF outputs, in portrait, landscape, or square.

A Chipter review page: Late July Jalapeño Lime, scored 8.7 on the Chipter Scale

AI that writes in the brand's voice. I wrote Chipter's editorial voice down as structured context the AI actually reads. A context agent, connected over Sanity's MCP integration, drafts entire reviews and posts against a canonical voice document. Inside the Studio, AI Assist field actions handle the surgical edits: Rewrite in Chipter voice, a softer laid-back register, Generate verdict from review, Generate video copy, and Suggest section subheads — each governed by the same voice rules so a one-line verdict sounds like the 800-word review above it.

One asset and delivery pipeline. Rendered videos land in Cloudinary, which derives every social variant — Instagram, TikTok, YouTube Shorts, square, vertical, thumbnail — from a single master file. Resend powers the newsletter and lifecycle email, authored as React components and sent in rate-safe batches straight from the Studio. Clerk handles accounts, syncing users into the CMS so readers can like and comment. Editors preview everything live against the real site before publishing.

Automation with a human in the loop. Nothing goes out on its own. A finished video attaches to the review's draft, not the live page, so an editor sees it before readers do — and the Bluesky auto-poster only fires when an editor hits publish.


The Results

What used to take a handful of tools and specialists now happens in one place. An editor can take a review from blank document to published article, a full set of platform-sized videos, a newsletter, and a social post — without leaving Sanity Studio or waiting on a motion designer for every clip. The voice system keeps hundreds of pieces sounding like one narrator, and the render pipeline clears the production bottleneck that usually caps how often a small team can publish video.

The video panel on a Chipter review: a vertical origin-story video the pipeline rendered for that review

The same pipeline produces long-form narrative pieces — a papercut "origin story" of the potato and a chaptered history of the chip — rendered entirely in code, frame by frame.

Chipter's history page: "A brief history of the chip," a 60-second papercut film rendered by the pipeline
Frame from the chip history — the 1960s "flavor revolution" chapter

Chipter is also my reference build: live visual editing, on-demand serverless video, AI-assisted authoring, and headless asset delivery, all working as one system. When a client asks whether something is possible, there's a good chance I've already tried it here. (If you're weighing a web app of your own, here's how I build them.)

What I Built

  • Designed and built a custom Sanity Studio — schema, live visual editing, and bespoke plugins for newsletters, contacts, and video rendering
  • Built a serverless Remotion video pipeline with 15 templates rendering to Cloudinary on demand
  • Implemented an AI voice system — an MCP context agent plus in-Studio AI Assist field actions
  • Integrated Cloudinary, Resend, and Clerk into a single CMS-driven workflow
  • Shipped a Next.js 16 front end with live preview and reader engagement (likes, comments, submissions)

Under the Hood

The technical tour, for the developers on your team. Everything below comes straight from the production codebase.

Architecture

Chipter is a pnpm monorepo:

  • apps/web — the Next.js 16 App Router front end and all API routes
  • apps/studio — the Sanity Studio (CMS)
  • packages/video-core — shared Remotion compositions, fonts, types, and the composition registry
  • apps/video / apps/cloudinary — auxiliary Sanity SDK apps for render UI and asset management

The web app consumes @chipter/video-core as a workspace package, so the same composition definitions power both the Studio's render UI and the server-side renderer — no duplication between authoring and rendering.

The Video Pipeline

A single registry, packages/video-core/src/registry.ts, is the source of truth: it declares every composition (dimensions, fps, duration, Zod prop schema), every Cloudinary delivery variant, and any alternate-orientation renditions. Because it's pure metadata with no React imports, the Sanity schema layer can import it without pulling Remotion into the bundle.

Rendering runs through POST /api/video/render:

  1. Validates input props against the composition's Zod schema.
  2. Idempotency check — queries Sanity for an existing video doc matching (template, format, orientation, source); returns early if one is already ready, rendering, or uploading.
  3. Creates a video document at status: 'rendering'.
  4. Renders with @remotion/renderer, using @sparticuz/chromium on Vercel (system Chrome locally) in headless-shell mode.
  5. MP4 uploads to Cloudinary under chipter/videos/; GIF uploads to Sanity's asset store (so Bluesky can embed it as an image under its 1 MB animation cap).
  6. Patches the doc to status: 'ready' with the Cloudinary URL/public ID, or failed with an error message.

Long-form pieces (60s+) render at a reduced renderScale to stay inside Vercel's function timeout, then upscaleDeliveryUrl() injects a Cloudinary c_scale transform so consumers still receive full-resolution video — the upscale happens free, at the CDN edge.

The Vercel deploy depends on a precise next.config.ts setup: serverExternalPackages keeps the native renderer and Chromium unbundled, and outputFileTracingIncludes explicitly ships the Remotion bundle plus the hoisted Chromium binaries (loaded at runtime via fs, which static tracing can't see on its own).

The AI Voice System

The voice is encoded as three seeded sanity.agentContext documents, generated from markdown sources by apps/studio/scripts/seed-agent-context.ts:

  • chipter-voice — the deep reference for the MCP context agent that drafts full documents
  • chipter-voice-assist — a leaner cut for in-Studio AI Assist field actions (the strict house voice)
  • chipter-voice-laidback — the same voice in a casual register

The agentContextPlugin() exposes an MCP endpoint so a model can draft entire reviews against the canonical voice. For inline edits, the @sanity/assist plugin registers five custom field actions in apps/studio/sanity.config.ts — Rewrite in Chipter voice, Rewrite in laid back voice, Generate verdict from review, Generate video copy in Chipter voice, and Suggest section subheads — each routing through the appropriate voice document via instructionParams. The markdown sources are the source of truth; editors never hand-edit the voice docs in the Studio.

Cloudinary Delivery

Every rendered master is uploaded once; Cloudinary derives the rest. The registry's variant catalog declares site-playback, per-platform social (Instagram/TikTok/YouTube/square/vertical), and thumbnail transforms. Variants marked eager are materialized at upload; the rest derive lazily. Helpers variantUrl() and upscaleDeliveryUrl() build the delivery URLs, and the apps/cloudinary Studio app provides browse/search/transform/sync tooling over the media library. The cloud is fortivex-partner.

Resend Email

Emails are React Email components rendered to HTML at send time. /api/newsletter handles signup with a dual-write — a contact document in Sanity and a contact in the Resend audience — and gracefully re-subscribes returning addresses. /api/newsletter/send reads draft content (so editors can send unpublished drafts), then dispatches in batches of 10 with a delay to respect Resend rate limits. A custom newsletter builder plugin replaces the Studio's publish button with Preview (desktop/mobile mockups) and Send actions; a contact manager tool provides full subscriber CRUD with stats.

Auth & Engagement

Clerk is the identity source of truth. A Svix-verified webhook at /api/webhooks/clerk syncs user.created / updated / deleted events into Sanity userProfile documents, so a reader is immediately available in the CMS for commenting. Engagement is privacy-conscious: likes are session-based with SHA-256-hashed IPs for rate limiting (never stored raw) and committed atomically with the parent's like count; comments require authentication with server-verified author identity; chip submissions run through banned-word moderation before emailing the team.

Editor Experience

Sanity's presentationTool drives live preview against the running Next.js app, with draft mode and stega-encoded visual editing wired through lib/sanity.live.ts. Social automation respects editorial control: when a video render completes, the pipeline patches the draft review's socialImage (never the published document) so the GIF surfaces for review in the Studio — and the Bluesky auto-poster only fires when an editor publishes, which also prevents accidental double-posts.

  • Custom Sanity Studio
  • Remotion Video Pipeline
  • AI Voice System
  • Cloudinary Delivery
  • Resend Email
  • Clerk Auth
  • Next.js 16

More case studies

We Move Montana

Moving On Up, a Missoula moving company with 123+ five-star Google reviews, traded a 2000s-era BlueVoda site for a phone-first Astro build with 99–100 Lighthouse scores and a perfect agent-readiness score, made to turn the traffic it already earns into calls, texts, and quotes.

Read more

Made in Montana for Montanans

Quality Pump Service, family-run well pump specialists in Potomac Montana, partnered with me to build a professional lead-generating website.

Read more

Tell me about your project.

Every message comes straight to me, and I write every reply myself. No sales team, no ticket queue.