Case Study
Building a Premium Personal Brand Platform with Next.js and Payload
A modern personal site should work like a product: structured, fast, deeply editable, and visually unforgettable.
Most personal websites fall into one of two traps: they are visually flat resumes, or they are visually loud without being strategically useful. I wanted a third option — a platform that earns trust in the first three seconds and stays editable for the next three years.
The stack
Next.js 16 App Router with React Server Components and the new Cache Components model
Payload CMS 3 backed by PostgreSQL for collections (Posts, Projects, Testimonials) and globals (SiteSettings, Homepage, About, Resume, Contact)
Lexical rich-text everywhere, with helper functions for programmatically generated content
@payloadcms/storage-s3 for media when an S3-compatible bucket is wired up
@payloadcms/plugin-mcp so the same content can be edited by Claude or another agent over MCP
The trick that made this work: a fallback content layer
The clean version of this stack is fragile. If Postgres goes down, the whole site goes with it. I did not want that, so I introduced a single typed fallbackContent object that mirrors the entire CMS model. The data layer (getSiteContent) tries Payload first, returns the fallback on any failure, and merges live CMS data on top of the fallback when it succeeds. Result: the database can be missing on day one, and the site still renders perfectly.
That same object also feeds the seed script. There is exactly one source of truth for "what the site says about me," and it is type-checked.
Where the MCP plugin pays for itself
Exposing the CMS over MCP means I can sit in a Claude conversation, say "publish a post titled X with body Y," and have it land in Payload as a real draft. For a personal site that publishes occasionally, this turns the friction of "open the admin, log in, write" into "talk to the agent." The trade-off is that you have to scope MCP exposure carefully — Contact Submissions, for example, has no business being agent-readable. That collection is explicitly disabled in the plugin config.
Cache strategy
I spent more time on caching than on layout. Cache Components let me mark whole pages as cacheable, tag them with site-content, and invalidate from a Payload afterChange hook. The result is sub-100ms server response for every static page, and edits in the admin show up on the public site within one request after save. Without that, the dev server feels great and the production site feels slow — a trap a lot of Payload sites fall into.
Why the system is built this way
The deeper lesson is that premium web experiences are not about decoration. They are about a system where narrative, speed, and aesthetics reinforce each other, and where the operator (me) can change anything in five minutes without breaking the design. Templates fail at all three. Hand-built systems with discipline pass.