YYour Name
  • Home
  • Experience
  • Work
  • Blog
  • Contact
  • Home
  • Experience
  • Work
  • Blog
  • Contact

© 2026 Cyborged. All rights reserved.

Cyber Security Anthusiast & Fullstack Web Developer

Back to blog
Next.jsSupabaseTypeScriptArchitecture

Building a personal CMS with Next.js and Supabase

How I built the content management backend for this portfolio — covering Server Actions, Row Level Security, and the admin dashboard architecture.

April 10, 2024
9 min read
All posts

Building a personal CMS with Next.js and Supabase

When I decided to rebuild my portfolio, I had one core requirement: I wanted to manage all my content — blog posts, projects, work experience — from a clean admin interface, without paying for a third-party CMS.

The Architecture

The solution I landed on uses:

  • Next.js 14 App Router for both the public site and the admin dashboard
  • Supabase for the database, auth, and file storage
  • Server Actions for all mutations (create, update, delete)

Row Level Security

The key insight is that Supabase's Row Level Security does the heavy lifting. Public visitors can only read published posts. The admin account can read and write everything.

create policy "Public can read published posts"
  on public.posts for select to anon
  using (published = true);

Server Actions

Server Actions make the CRUD layer almost trivial. A create action looks like:

async function createPost(data: PostInput) {
  "use server";
  const supabase = createClient();
  const { error } = await supabase.from("posts").insert(data);
  if (error) throw new Error(error.message);
  revalidatePath("/blog");
}

The revalidatePath call invalidates the Next.js cache so the public blog page reflects the change immediately.

What I Learned

The biggest gotcha was session management across Server Components and the Edge Runtime (middleware). The @supabase/ssr package handles this correctly by reading and writing cookies on both the request and response objects.