Next.js
Supabase
Portfolio
CMS
Full-Stack
Admin Portal

How I Turned My Portfolio Into a Full-Stack CMS

A practical breakdown of how I transformed my developer portfolio from a static website into a content-managed full-stack application using Next.js, Supabase, Material UI, authentication, storage, and admin workflows.

Shevon Chisholm
Jun 4, 2026
6
How I Turned My Portfolio Into a Full-Stack CMS

How I Turned My Portfolio Into a Full-Stack CMS

A portfolio is usually treated as a simple marketing page: a hero section, a few projects, skills, contact information, and maybe a downloadable resume. That is useful, but I wanted my portfolio to become more than a static website. I wanted it to operate like a real application.

The goal was not to over-engineer it. The goal was to create a practical content-managed system that could demonstrate the same skills I use in client and product work: authentication, database design, admin workflows, storage, protected routes, public content rendering, and clean user experience.

Why I moved beyond a static portfolio

A static portfolio is easy to deploy, but it becomes harder to maintain as the content grows. Every project update requires a code change. Every new skill, experience entry, blog post, or resume update requires touching the codebase.

That works at first, but it does not scale well.

By adding a CMS layer, I can manage content from an admin portal while keeping the public site clean, fast, and focused on recruiters, clients, and collaborators.

The portfolio now behaves more like a real product:

  • Public users see published content only.
  • Admin users can create, edit, publish, unpublish, and manage content.
  • Projects can include tags, highlights, technical focus areas, links, and media.
  • Contact messages are stored and managed through an admin dashboard.
  • Resume and settings can be controlled without redeploying the application.

The stack

The core stack is:

  • Next.js App Router for the public site and admin application
  • TypeScript for safer development
  • Material UI for the interface
  • Supabase Auth for authentication
  • Supabase Postgres for content storage
  • Supabase Storage for media and documents
  • Supabase RLS for access control
  • Resend for email notifications
  • Vercel for deployment

I chose Supabase because it gives a strong backend foundation without needing to maintain a separate server for this project. For a portfolio CMS, that balance matters. The project needed to be production-ready, but also low-maintenance and cost-conscious.

Database design

The CMS is built around structured tables rather than one large JSON blob. This makes the content easier to manage and query.

The main tables include:

  • projects
  • project_tags
  • project_images
  • project_highlights
  • project_technical_focus
  • blog_posts
  • experience_items
  • education_items
  • skill_categories
  • skills
  • contact_messages
  • site_settings
  • admin_profiles

The projects section is the most detailed because projects are the strongest evidence of engineering ability. Each project can have its own tags, highlights, technical focus points, gallery images, links, role, status, impact, SEO fields, and published state.

Admin protection

The admin area is protected using Supabase Auth and an admin_profiles table. Authentication alone is not enough, because any authenticated user should not automatically become an admin.

The logic is:

1. User signs in. 2. The system checks the authenticated user's id. 3. The user must exist in admin_profiles. 4. Only then can the user access the admin CMS.

This keeps the admin portal controlled and avoids relying only on client-side checks.

Row Level Security

RLS is one of the most important parts of the system.

The public site can read published content. The admin can manage both published and unpublished content. Contact messages can be inserted from the public contact form, but only admins can read and manage them.

That structure allows the public site and admin portal to use Supabase safely without exposing a service role key in the browser.

Media handling

Media upload is handled through Supabase Storage. For new records, files can be queued before the parent record exists. Once the record is created, the uploaded files are stored in organized paths and the database is updated with the final public URLs.

For existing records, uploads can be persisted immediately.

This makes the upload flow feel natural while keeping storage organized.

Contact form workflow

The contact form now does more than submit a basic email. It stores the message in Supabase and sends an email notification through Resend.

That gives two benefits:

  • I get notified immediately.
  • The message is still saved in the admin CMS.

If email delivery fails but the database insert succeeds, the message is not lost.

What this project demonstrates

This portfolio now demonstrates more than design taste. It shows practical full-stack application development:

  • Database modeling
  • Authentication
  • Authorization
  • Protected routes
  • CMS workflows
  • Public/private content handling
  • File uploads
  • Admin UX
  • Email notifications
  • Production-minded architecture

That matters because companies and clients do not only need someone who can build screens. They need someone who can think through product flow, data flow, permissions, maintainability, and deployment.

Final thoughts

Turning my portfolio into a CMS gave me a stronger way to present my work while also creating another real project I can discuss in interviews.

It shows that I do not just list technologies. I use them to build practical systems.

The result is a portfolio that is easier to maintain, more professional, and more aligned with the kind of full-stack work I want to keep doing.

Written by Shevon Chisholm

Full-Stack Engineer