Deployment

Last updated on 2026-09-03

This guide covers deploying the kit to production with Vercel (hosting) and Supabase (database and auth).

Prerequisites

Step 1 -- Prepare Supabase for Production

Run Migrations

In your production Supabase project, run the migration files in order via the SQL Editor:

  1. 001_schema.sql -- Blog tables (posts, categories, tags, comments, media, newsletters) with indexes
  2. 002_rls.sql -- Public read / authenticated write RLS policies
  3. 003_triggers.sql -- Profile auto-creation, updated_at timestamps, view count incrementing, comment count caching
  4. 004_storage.sql -- blog-assets storage bucket for media uploads

Configure Auth

  1. Go to Auth > URL Configuration

  2. Set Site URL to your production domain (e.g., https://blog.yourcompany.com)

  3. Add redirect URLs:

    • https://blog.yourcompany.com/auth/callback
    • https://blog.yourcompany.com/auth/confirm
  4. Enable OAuth providers (Google, GitHub) with production credentials if desired

Create Admin User

  1. Sign up on your production site
  2. In Supabase Dashboard, go to Table Editor > profiles
  3. Find your user's row and set role to admin

Seed Data (Optional)

For a fresh production site, you likely do not want the seed data. If you want to start with sample posts and categories for demo purposes, run seed.sql in the SQL Editor.

Step 2 -- Deploy to Vercel

Option A: Git Integration

# Push your code to GitHub
git push origin main

# Connect to Vercel
# 1. Go to vercel.com/new
# 2. Import your repository
# 3. Add environment variables (see below)
# 4. Deploy

Option B: Vercel CLI

npm i -g vercel
vercel --prod

Environment Variables

Set these in Vercel Dashboard > Project Settings > Environment Variables:

Variable Value Notes
NEXT_PUBLIC_SUPABASE_URL https://xxx.supabase.co Your project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY eyJ... Public anon key
SUPABASE_SERVICE_ROLE_KEY eyJ... Private service role key
NEXT_PUBLIC_APP_URL https://blog.yourcompany.com Your production URL

Important: The SUPABASE_SERVICE_ROLE_KEY is sensitive. Never expose it in client-side code. It is only used in Server Actions.

Step 3 -- Verify Production

After deployment, test the full flow:

  1. Visit the homepage and verify blog posts load
  2. Open a single post and confirm the article renders with correct typography
  3. Submit a comment on a post and verify it appears (or shows pending if moderation is on)
  4. Submit the newsletter signup form
  5. Visit the login page and create an admin account
  6. Make yourself an admin in Supabase (update profiles.role)
  7. Browse the admin dashboard and verify analytics data loads
  8. Create a new post from the admin editor and publish it
  9. Upload an image via the media library
  10. Check that the post appears on the public blog

Custom Domain

  1. In Vercel Dashboard > Project Settings > Domains
  2. Add your custom domain
  3. Update DNS records as directed by Vercel
  4. Update NEXT_PUBLIC_APP_URL to your custom domain
  5. Update Supabase Auth Site URL and redirect URLs to match

Performance

The kit is optimized for production:

  • Server Components for initial render -- blog posts, categories, and the homepage are server-rendered with no client-side data fetching
  • Route-level code splitting via the App Router -- the admin CMS bundle is not loaded on public blog pages
  • next/image for all post featured images and media library assets with automatic optimization and lazy loading
  • Supabase connection pooling for database queries
  • Static generation for public blog pages where possible, with ISR for dynamic content

Monitoring

  • Supabase Dashboard -- monitor database queries, auth events, storage usage, and RLS policy performance
  • Vercel Analytics -- monitor page load times and Web Vitals for both public blog and admin CMS
  • Vercel Logs -- check server-side errors in Server Actions (post creation, comment moderation, media uploads)
  • Supabase Logs -- review database query performance and identify slow queries