Where I was before
For years my online presence lived across two stacks. Adobe Portfolio handled the visual work, the photography and videography, anything that needs to look good without me thinking about CSS. WordPress (with multisite) handled the writing and the case studies. It worked. But every time I sat down to publish something I had to remember which admin I was logged into, which theme owned which template, and which plugin was about to break on the next update.
WordPress multisite is fine for what it is. It's just heavier than I needed. I wanted one place to write, one place to deploy, and one design language across both surfaces.
What I wanted
A single CMS for both halves of the site:
- Long-form writing and project case studies on the design side
- Photography and videography on the creative side
- A shared category taxonomy and a shared media library
- A consistent UI I could lock down and stop touching
The visual direction was Swiss-leaning. Tight grid, big type, minimal chrome. Once the layout was right I wanted to spend my time writing posts, not fighting templates.
Why Payload
Payload is an open-source, code-first CMS built on Next.js. Collections are TypeScript files. The admin UI is generated from those collections. The rich text editor is Lexical with custom blocks that you define yourself.
For a content-focused team that has already settled on a design, that constraint is the feature. The admin only exposes the fields you wrote. There is no theme customizer for an editor to wander into and break the layout. If your goal is "write more, fiddle less," that is the trade you want.
This suited me better than WordPress. WordPress assumes you will keep changing the theme. I had stopped wanting to change the theme.
The architecture, in plain terms
One Next.js app. One Postgres database. One deploy. Two domains.
haikal-fikri.comserves the creative site (photo and video).design.haikal-fikri.comserves the design site (articles and projects)./adminis the single Payload admin shared by both.
The split between the two front-ends happens in a small piece of middleware. Next.js receives a request, reads the host header, and rewrites the URL to either /creative/... or /design/... internally. The visitor sees the clean domain they typed. Next.js sees a normal route group. No multisite, no second deploy, no DNS-level proxy.
Adding a third surface later is the same pattern: another host check, another route group.
The rest of the stack:
- Hosting: Netlify, with the
@netlify/plugin-nextjsadapter. One site, one build, both domains attached. - Database: Supabase Postgres. Payload's Postgres adapter derives the SQL schema directly from the collection configs, so during development I never wrote a migration file by hand.
- Media: Cloudflare R2 over the S3-compatible API. Uploaded files resolve directly from R2's public URL and skip Payload's file proxy. That keeps image delivery fast and avoids Netlify's 6 MB function response limit.
A couple of integration quirks were worth an evening of chasing. Netlify's build workers can't reach Supabase's IPv6-only direct connection, so the deploy uses Supabase's session pooler instead. The session pooler caps at 15 clients account-wide, so Payload's Postgres pool is capped to fit. None of this is in any tutorial; you find it out the first time a build fails.
Building it with Claude
I am not a formal engineer. I read code, I ship prototypes, and I lean on Claude in VS Code as a pair. Most of this build was conversational. I would describe a section, Claude would draft the component or the collection config, I would run it, push back where it was wrong, and move on.
The part of the workflow worth writing down is the inspiration step. There was a Swiss-style portfolio I liked. Instead of describing the layout in words and hoping the model guessed right, I used Claude for Chrome to walk through the live page and pull out the typographic scale, the spacing rhythm, and the grid structure. I pasted that structured brief into the agent in VS Code as the seed for the design system.
The result is not a clone. The content and brand are mine. But the underlying rhythm came from a real reference rather than a vague "make it feel Swiss" prompt, and that is what kept the output from looking like every other AI-built site.
What this stack is good for
If you are a content-focused team or a single author, and you have already made your design decisions, Payload removes most of the friction WordPress carries by default. You define the collections, the rich text blocks, and the media model. The admin is generated from that. Editors get fields, autosaved drafts, and a publish button. They do not get a customizer they can use to redesign the site at 11pm on a Friday.
If you want editors to redesign the site themselves, Payload is the wrong tool. WordPress or Webflow is probably right.
What I keep noticing is how few moving parts there are. One Next.js repo. One database. One deploy. Two domains served by a small piece of middleware. After WordPress multisite plus a separate Adobe Portfolio account, the new setup feels almost boring to maintain. Which was the point.
