Blog with Next.js + Payload + Supabase
Works with AI coding agents
These blueprints are optimized for use with:
Overview
This blueprint walks you through building a real, deployable blog application using Next.js, Payload CMS, and Supabase.
It is designed for:
- people who don’t code every day and want safe defaults
- builders who want to ship quickly without assembling a heavy enterprise stack
- anyone experimenting with AI coding agents who wants repeatable results
The focus is not on novelty, but on confidence and completion.
What You’ll Build
By the end of this blueprint, you'll have:
- A Payload CMS-powered Admin UI
- A public blog index page (
/blog) - Individual blog post pages (
/blog/[slug]) - A working database backed by Supabase Postgres
- Media uploads that work in at least one mode:
- Supabase Storage (if S3-compatible credentials are available)
- Local filesystem fallback otherwise
How to Use This Blueprint
This blueprint is meant to be followed step by step using an AI coding agent such as Cursor.
Important rules:
- Follow the sequence as written
- Do not skip verification steps
- Ignore agent suggestions that expand scope
The goal is to finish with something working, not perfect.
Pre-requisites
Accounts & Tools
- A Supabase account and project
- Node.js (LTS recommended)
- pnpm, npm, or yarn
- An AI-enabled code editor (Cursor recommended)
- A Vercel account (for deployment)
- A GitHub account/repo (recommended for Vercel deployments)
Add Documentation as Agent Context (Strongly Recommended)
Keep these docs open or add them as context in your editor:
- Payload Database Overview: https://payloadcms.com/docs/database/overview
- Payload Storage Adapters: https://payloadcms.com/docs/upload/storage-adapters
- Supabase Storage: https://supabase.com/docs/guides/storage
- Supabase MCP: https://supabase.com/docs/guides/getting-started/mcp
- Cursor: Adding Your Own Documentation: https://cursor.com/docs/context/mentions#adding-your-own-documentationcu
Prompt 0 — Agent Working Agreement
You are my senior full-stack engineer working inside this repo.
Rules:
- Keep scope minimal and shippable.
- Prefer boring defaults.
- Do not add dependencies unless necessary; ask first.
- Make small, reviewable changes.
- Explain which files you touched.
- Stop after completing each task.
- Follow the blueprint sequence. Do not jump ahead.
Verification:
- The agent acknowledges the rules
- No scope expansion is proposed
Prompt 1 — Scaffold with Payload CLI (Manual)
Goal: Start from a known-good, compatible scaffold.
This step must be done manually because the Payload CLI is interactive.
Task: Instruct me to scaffold a new Payload + Next.js project using the official Payload CLI.
Requirements:
- Use the official [Payload](https://payloadcms.com) [Next.js](https://nextjs.org) template (App Router)
- Keep defaults unless there is a strong reason to change
- If prompted for a database connection:
- Paste a [Supabase](https://supabase.com) Postgres URL if available
- Otherwise skip and we'll wire it later
- Do NOT introduce additional services or architectures
Deliverables:
- Exact CLI command to run
- High-level guidance for interactive prompts
- What success looks like
Stop after instructions and verification checklist.
Manual verification:
- Repo created
- Dependencies installed
- Dev server runs
- Payload Admin loads locally
Prompt 2 — Verify Scaffold (Read-Only)
Goal: Confirm the scaffold works before changing anything.
Task: Verify the scaffolded project without modifying code.
Explain:
- High-level folder structure
- Where Payload config lives
- Where collections are defined
- Where Next.js routes live
- Which URLs should load locally
Do NOT change any files.
Stop after verification.
Prompt 3 — Supabase Database Setup (Conditional)
Goal: Ensure Payload is connected to Supabase Postgres without redoing work.
Inspect the current database configuration.
If [Payload](https://payloadcms.com) is already connected to [Supabase](https://supabase.com):
- Verify the connection works
- Document required env vars
If not:
- Provide [Supabase](https://supabase.com) setup steps
- Specify the exact Postgres connection string
- Update .env.example
- Wire Payload to Supabase
In all cases:
- Add fail-fast env validation
- Explain how to verify DB health
Stop after verification.
Prompt 3B — Supabase Storage for Uploads (Critical)
Goal: Enable media uploads with a safe fallback strategy.
Key constraint: Supabase Storage is REST-based by default; Payload's official plugin expects S3-compatible APIs.
Context:
- [Payload CMS](https://payloadcms.com) with [Supabase Postgres](https://supabase.com)
- Media uploads required
Task (Inspect → Decide → Act):
1) Create a [Supabase Storage](https://supabase.com/docs/guides/storage) bucket named `media` (public, images only) using MCP tools.
2) Determine if S3-compatible credentials are available.
If YES:
- Configure [@payloadcms/storage-s3](https://payloadcms.com/docs/upload/storage-adapters) conditionally
- Enable only if all SUPABASE_STORAGE_* env vars exist
- Use forcePathStyle: true
- Disable local storage when active
If NO:
- Keep local filesystem storage
- Document the limitation clearly
Always:
- Validate env vars (all-or-nothing)
- Fail fast on partial configuration
- Update documentation
Stop after an image uploads successfully in at least one mode.
Prompt 4 — Create Posts + Blog Index Page
Goal: Seed content and render a public blog list.
Inspect existing collections.
If a posts collection exists:
- Use it as-is
If not:
- Create a minimal posts collection:
- title
- slug
- excerpt
- content
- status (draft/published)
- publishedAt
Seeding:
- Prefer a seed script
- Otherwise document exact manual steps
Build `/blog`:
- Show published posts only
- Render title, excerpt, date
- Server-first data fetching
Stop after /blog renders content.
Prompt 5 — Blog Post Detail Page
Goal: Render individual blog posts.
Build `/blog/[slug]`.
Requirements:
- Fetch by slug
- Published posts only
- Render title, date, content
- Link back to /blog
Stop after page works.
Prompt 6 — Deploy to Vercel (Reusable)
Goal: Deploy your blog to production so you can share a real URL.
This step is intentionally reusable across many Voie blueprints. Rather than repeating every detail here, follow the deployment guide and come back to this blueprint for the final verification.
This blueprint explicitly depends on the Vercel deployment guide. If you skip it, you may miss required production configuration for Payload, Supabase, or storage.
Required guide: Deploying Voie.io Blueprints to Vercel
- Guide: /guides/deploy-to-vercel
- Follow the guide end-to-end, then return here to complete the verification checklist below.
What you'll do (high level)
- Push your project to GitHub
- Create a new Vercel project from the repo
- Set environment variables
- Deploy and verify Payload Admin + public pages
What to prepare before deploying
- Production secrets (do not reuse local dev values)
PAYLOAD_SECRET- any auth/session secrets used by the template
- Database URL for Supabase (production project)
- Public site URL (Vercel domain or custom domain)
- Storage choice
- If using Supabase Storage via S3-compatible credentials, ensure all
SUPABASE_STORAGE_*vars are set - Otherwise confirm local uploads are acceptable for your use case (usually not ideal for multi-instance production)
- If using Supabase Storage via S3-compatible credentials, ensure all
Deployment verification checklist
- Completed the Deploy to Vercel guide without skipping steps
- Site is reachable at the Vercel URL
- Payload Admin loads and you can log in
- /blog renders published posts
- /blog/[slug] renders a post page
- Media upload works in production (cloud storage preferred)
- No runtime errors in Vercel logs
Share checklist (the “done-done” moment)
- Add the live URL to the top of this blueprint (or your X article)
- Post the Voie blueprint link on X / LinkedIn
- Capture 1–2 learnings to improve v1.1
Known Pitfalls
- Payload CLI must be run manually
- Supabase Storage may not support S3
- Avoid scope creep suggested by agents
- Production deploys require correct env vars (secrets, database URL, storage). Don't debug this blindly—verify one variable at a time.
Definition of Done
- App runs locally
- Payload Admin works
- Supabase DB connected
- Media uploads work in at least one mode
- /blog and /blog/[slug] render correctly
- Deployed to Vercel with a working production URL
Changelog
- v1.0 — Initial public MDX blueprint extracted from a real build
- v1.1 — Added Vercel deployment step + production readiness checklist