GameCraftGameCraft

Deploy to Vercel

Deploy ProductReady to production in 5 minutes with Vercel's one-click deployment

Deploy to Vercel

Vercel is the fastest and easiest way to deploy ProductReady to production. This guide walks you through the entire process.

Why Vercel?

  • Zero configuration needed
  • Automatic HTTPS and CDN
  • Free tier includes hobby projects
  • Deploy on every git push
  • Built by the creators of Next.js

Prerequisites

Before deploying, you need:

  • ✅ GitHub account (to connect your repo)
  • ✅ Vercel account (sign up free)
  • ✅ Database (Neon, Supabase, or other PostgreSQL)
  • ✅ Environment variables ready (see below)

Quick Deploy (5 Minutes)

Push your code to GitHub

# Initialize git (if not already)
git init
git add .
git commit -m "Initial commit"

# Create repo on GitHub, then:
git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPO.git
git push -u origin main

Connect to Vercel

  1. Go to vercel.com/new
  2. Click "Import Git Repository"
  3. Select your ProductReady repository
  4. Click "Import"

First time? Vercel will ask to install the GitHub App - click "Install"

Configure project

Vercel auto-detects Next.js. Verify these settings:

  • Framework Preset: Next.js
  • Root Directory: apps/productready (if in monorepo) or ./ (if standalone)
  • Build Command: pnpm build (or npm run build)
  • Output Directory: .next (auto-detected)

Click "Deploy" - don't worry, it will fail first time (we need env vars!)

Add environment variables

After first deploy fails, go to: Project Settings → Environment Variables

Add these required variables:

# Database
PG_DATABASE_URL=postgresql://user:pass@host:5432/db

# Auth
BETTER_AUTH_SECRET=your-secret-32-chars-minimum
BETTER_AUTH_URL=https://your-app.vercel.app

# Optional: OAuth
GITHUB_CLIENT_ID=your-github-oauth-id
GITHUB_CLIENT_SECRET=your-github-oauth-secret
GOOGLE_CLIENT_ID=your-google-oauth-id
GOOGLE_CLIENT_SECRET=your-google-oauth-secret

Important: Update BETTER_AUTH_URL to your actual Vercel domain!

Redeploy

Click "Deployments" tab → Find latest deploy → Click "⋯""Redeploy"

Or just push a new commit:

git commit --allow-empty -m "Trigger deploy"
git push

This time it will succeed! 🎉

Run database migrations

After successful deploy, run migrations:

Option 1: Use Vercel CLI

# Install Vercel CLI
npm install -g vercel

# Login
vercel login

# Run migration
vercel env pull .env.production
pnpm db:migrate

Option 2: Connect to your database directly

# Set PG_DATABASE_URL from Vercel
export PG_DATABASE_URL="your-production-db-url"

# Run migrations
pnpm db:migrate

# Seed data (optional)
pnpm db:seed

Test your app

Visit your Vercel URL (e.g., https://your-app.vercel.app)

Test:

  • ✅ Landing page loads
  • ✅ Sign up / Login works
  • ✅ Dashboard accessible
  • ✅ Health check: https://your-app.vercel.app/api/health

Deployed! Every git push to main will now automatically deploy to production.


Environment Variables Explained

Required Variables

PG_DATABASE_URL

Your PostgreSQL connection string.

Format: postgresql://user:password@host:port/database

Where to get it:

  • Neon: Dashboard → Connection Details → Connection string
  • Supabase: Project Settings → Database → Connection string (use "Connection pooling")
  • Railway: Database → Connect → Postgres Connection URL

Use connection pooling for serverless (Vercel). Most providers offer pooled connections on a different port (usually 6543 instead of 5432).

BETTER_AUTH_SECRET

Secret key for signing sessions/tokens.

Generate:

openssl rand -base64 32

Copy the output and paste as BETTER_AUTH_SECRET.

Important: Use different secrets for dev and production!

BETTER_AUTH_URL

The public URL where your app is hosted.

  • Development: http://localhost:3000
  • Production: https://your-app.vercel.app (or your custom domain)

Custom domain? Update this after adding your domain in Vercel settings.


Optional Variables (OAuth)

GitHub OAuth

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. Fill in:
    • Application name: Your App Name
    • Homepage URL: https://your-app.vercel.app
    • Authorization callback URL: https://your-app.vercel.app/api/auth/callback/github
  4. Click "Register application"
  5. Copy Client ID and Client Secret

Add to Vercel:

GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret

Google OAuth

  1. Go to Google Cloud Console
  2. Create project → Enable "Google+ API"
  3. Create OAuth 2.0 credentials
  4. Add authorized redirect URI: https://your-app.vercel.app/api/auth/callback/google
  5. Copy Client ID and Client Secret

Add to Vercel:

GOOGLE_CLIENT_ID=your_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secret

Custom Domain

Add your domain

Buy a domain

Buy from: Namecheap, GoDaddy, Cloudflare, or any registrar.

Add to Vercel

  1. Go to Project Settings → Domains
  2. Enter your domain (e.g., myapp.com)
  3. Click "Add"

Update DNS

Vercel shows DNS records to add. Go to your domain registrar and add:

For root domain (myapp.com):

Type: A
Name: @
Value: 76.76.21.21

For www subdomain:

Type: CNAME
Name: www
Value: cname.vercel-dns.com

Wait for DNS propagation

Usually takes 5-30 minutes. Vercel will show "Valid Configuration" when ready.

Update environment variables

Update BETTER_AUTH_URL to use your custom domain:

BETTER_AUTH_URL=https://myapp.com

Redeploy for changes to take effect.


Monitoring & Analytics

View logs

Vercel Dashboard → Deployments → Click deployment → View Function Logs

You'll see:

  • API requests
  • Errors and stack traces
  • Console.log output
  • Performance metrics

Health check

ProductReady includes a health endpoint:

curl https://your-app.vercel.app/api/health

Response:

{
  "status": "healthy",
  "timestamp": "2024-03-15T10:30:00.000Z",
  "version": "1.0.0",
  "buildNumber": 42,
  "commit": "abc1234"
}

Use this for:

  • Uptime monitoring (UptimeRobot, Pingdom)
  • Health checks in load balancers
  • Deployment verification

Analytics

Option 1: Vercel Analytics (built-in)

  1. Go to Project → Analytics
  2. Enable Vercel Analytics
  3. Add package:
    pnpm add @vercel/analytics
  4. Add to src/app/layout.tsx:
    import { Analytics } from '@vercel/analytics/react';
    
    export default function RootLayout({ children }) {
      return (
        <html>
          <body>
            {children}
            <Analytics />
          </body>
        </html>
      );
    }

Option 2: Google Analytics Use env vars and add GA script to layout.


Performance Optimization

Enable caching

Add to next.config.mjs:

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Cache static pages for 1 year
  async headers() {
    return [
      {
        source: '/assets/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536000, immutable',
          },
        ],
      },
    ];
  },
};

export default nextConfig;

Image optimization

Use Next.js <Image> component:

import Image from 'next/image';

<Image 
  src="/logo.png" 
  alt="Logo" 
  width={200} 
  height={50}
  priority // for above-fold images
/>

Database connection pooling

Critical for Vercel! Use connection pooling to avoid exhausting database connections.

Neon/Supabase provide this automatically. If self-hosting, use PgBouncer.


CI/CD with GitHub Actions

Want more control? Use GitHub Actions before deploying to Vercel.

Create .github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - uses: pnpm/action-setup@v2
        with:
          version: 9
      
      - uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'pnpm'
      
      - run: pnpm install
      
      - run: pnpm lint
      
      - run: pnpm test
      
      - run: pnpm build

This runs on every push and blocks merge if tests fail.


Troubleshooting

"Build failed: Module not found"

Solution: Ensure dependencies are in package.json, not just installed locally.

# Re-install to update lock file
pnpm install

# Commit changes
git add package.json pnpm-lock.yaml
git commit -m "Update dependencies"
git push

"Database connection failed"

Check:

  1. Is PG_DATABASE_URL set in Vercel env vars?
  2. Is connection string correct? (Copy-paste carefully!)
  3. Is database accepting external connections?
  4. Using connection pooling? (Neon port 5432 → 6543)

"OAuth not working"

Check:

  1. OAuth callback URLs match your domain exactly
  2. BETTER_AUTH_URL is set to production URL (not localhost!)
  3. OAuth client secrets are correct
  4. Redeploy after changing env vars

"Deployment successful but site is blank"

Check browser console for errors.

Common issues:

  • Missing env vars → Functions fail silently
  • Database not migrated → API calls fail
  • CORS issues → Check BETTER_AUTH_URL

"Too many database connections"

Solution: Use connection pooling!

Neon example (note port 6543):

postgresql://user:pass@host:6543/db?sslmode=require

Or use Drizzle with pool:

import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

const client = postgres(process.env.PG_DATABASE_URL!, {
  max: 10, // Connection pool size
});

export const db = drizzle(client);

Production Checklist

Before going live:

  • All env vars set (especially BETTER_AUTH_SECRET, PG_DATABASE_URL)
  • Database migrated (pnpm db:migrate)
  • Health check works (/api/health returns 200)
  • OAuth configured (GitHub/Google redirect URIs)
  • Custom domain added (if applicable)
  • BETTER_AUTH_URL updated to production URL
  • Analytics enabled (Vercel or Google)
  • Error monitoring setup (Sentry optional)
  • Test signup/login flow
  • Test all main features
  • Check mobile responsiveness
  • Review security (no secrets in frontend code!)

Next Steps

🎉 Congrats on deploying to production! Now ship features, not infrastructure.

On this page