> ## Documentation Index
> Fetch the complete documentation index at: https://docs.charle.agency/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel Deployment

> Vercel-specific configuration and features

CharleOS is hosted on **Vercel**, which provides seamless deployment for Next.js applications. This page covers Vercel-specific configuration.

## Vercel Setup

### Project Configuration

**Team:** Charle Agency\
**Project:** charle-os\
**Framework:** Next.js 16\
**Build Command:** `npm run build`\
**Output Directory:** `.next`

### Git Integration

Vercel is connected to the GitHub repository:

**Repository:** `charle/charle-os`\
**Production Branch:** `main`\
**Deploy Previews:** All branches

**Automatic deployments:**

* ✅ Push to `main` → Production deployment
* ✅ Open PR → Preview deployment
* ✅ Update PR → Preview update
* ✅ Merge PR → Production deployment

## Environment Variables

### Setting Environment Variables

<Tabs>
  <Tab title="Vercel Dashboard">
    1. Go to [Vercel Dashboard](https://vercel.com/charle/charle-os)
    2. Settings → Environment Variables
    3. Add variable:
       * **Name**: `DATABASE_URL`
       * **Value**: `postgresql://...`
       * **Environments**: Production, Preview, Development
    4. Click "Save"
  </Tab>

  <Tab title="Vercel CLI">
    ```bash theme={null}
    # Add variable
    vercel env add DATABASE_URL production

    # Pull variables to local
    vercel env pull .env.local

    # List all variables
    vercel env ls
    ```
  </Tab>
</Tabs>

### Environment Scopes

Variables can be scoped to specific environments:

| Scope           | When Used                            |
| --------------- | ------------------------------------ |
| **Production**  | `main` branch deployments            |
| **Preview**     | PR/branch preview deployments        |
| **Development** | Local development (via `vercel dev`) |

<Warning>
  **Never use production credentials in preview deployments.** Always use separate DEV database and test API keys.
</Warning>

### Required Variables

#### Core

```
DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=your-32-char-secret
BETTER_AUTH_URL=https://charle.agency
NEXT_PUBLIC_BETTER_AUTH_URL=https://charle.agency
NEXT_PUBLIC_APP_URL=https://charle.agency
NEXT_PUBLIC_CLIENT_PORTAL_URL=https://clients.charle.agency
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
```

#### Integrations

```
CLOUDFLARE_WORKER_URL=https://r2-api.charle.agency
R2_UPLOAD_SECRET=your-secret
CLOUDFLARE_R2_PUBLIC_URL=https://files.charle.agency
NEXT_PUBLIC_PUSHER_KEY=your-key
NEXT_PUBLIC_PUSHER_CLUSTER=eu
PUSHER_APP_ID=your-app-id
PUSHER_SECRET=your-secret
RESEND_API_KEY=re_your_key
ALGOLIA_APP_ID=your-app-id
ALGOLIA_ADMIN_API_KEY=your-admin-key
ALGOLIA_SEARCH_API_KEY=your-search-key
SENTRY_AUTH_TOKEN=your-token
```

## Deployment Configuration

### Build Settings

```json theme={null}
// vercel.json (optional - most settings in dashboard)
{
  "buildCommand": "npm run build",
  "devCommand": "npm run dev",
  "framework": "nextjs",
  "installCommand": "npm install"
}
```

### Regions

CharleOS is deployed to:

* **Primary:** London (lhr1) - Closest to users
* **Edge:** Global CDN for static assets

### Build Output

After successful build:

* `.next/` - Built application
* `public/` - Static assets
* `drizzle/` - Migrations (applied during build)

## Deployment Workflow

### Production Deployment

```
Developer pushes to main
  ↓
Vercel webhook triggered
  ↓
Build starts
  ├── Install dependencies (npm install)
  ├── Run migrations (postinstall hook)
  ├── Build app (next build)
  └── Upload to CDN
  ↓
DNS updated to new deployment
  ↓
Old deployment kept for rollback
```

**Deployment time:** \~2-3 minutes

### Preview Deployment

```
Developer opens PR
  ↓
Vercel creates preview
  ├── URL: charle-os-git-{branch}.vercel.app
  ├── Uses Preview environment variables
  └── Links to PR for easy access
  ↓
Update PR → Preview auto-updates
```

**Preview features:**

* Unique URL per branch
* Shareable for testing
* Auto-deleted after PR merge
* Comments added to PR with preview URL

## Vercel Features

### Analytics

Built-in analytics show:

* **Web Vitals**: LCP, FID, CLS, TTFB
* **Top Pages**: Most visited pages
* **Top Referrers**: Traffic sources
* **Real User Monitoring**: Actual user experience

**Access:** [Dashboard → Analytics](https://vercel.com/charle/charle-os/analytics)

### Logs

Real-time logs for debugging:

**Build Logs:**

* Dependency installation
* Database migration output
* Build errors/warnings

**Runtime Logs:**

* API route requests
* Server component logs
* Error stack traces

**Edge Logs:**

* Edge function execution
* Regional performance

**Access:** Dashboard → Deployments → Select deployment → Logs

### Speed Insights

Track performance metrics:

* Real User Monitoring (RUM)
* Core Web Vitals breakdown
* Page-by-page performance
* Regional performance data

### Monitoring

Uptime and performance monitoring:

* 99.99% uptime SLA
* Automated health checks
* Incident notifications
* Status page

## Custom Domains

CharleOS uses custom domains:

### Main App

**Domain:** `charle.agency`\
**DNS:** Managed by Cloudflare\
**SSL:** Automatic (Vercel)

**DNS Configuration:**

```
CNAME @ cname.vercel-dns.com
```

### Client Portal

**Domain:** `clients.charle.agency`\
**Subdomain:** Separate Next.js app deployment

**DNS Configuration:**

```
CNAME clients cname.vercel-dns.com
```

## Performance Optimization

### Caching

Vercel automatically caches:

**Static Assets:**

```
Cache-Control: public, max-age=31536000, immutable
```

**Server Components:**

```
Cache-Control: s-maxage=60, stale-while-revalidate
```

**API Routes:**

```typescript theme={null}
// Custom cache headers
export async function GET(req: Request) {
  return Response.json(data, {
    headers: {
      'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600',
    },
  });
}
```

### Image Optimization

Next.js Image component uses Vercel's optimizer:

```typescript theme={null}
import Image from "next/image";

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority  // Preload for above-fold images
/>
```

**Optimizations:**

* Automatic WebP/AVIF conversion
* Responsive sizing
* Lazy loading
* CDN caching

### Edge Functions

API routes run on Vercel Edge (close to users):

```typescript theme={null}
// app/api/fast/route.ts
export const runtime = 'edge';  // Run on edge

export async function GET() {
  return Response.json({ message: "Fast response!" });
}
```

## Security

### HTTPS/SSL

* Automatic SSL certificate provisioning
* TLS 1.3 encryption
* HTTP → HTTPS redirect
* HSTS enabled

### DDoS Protection

Vercel provides:

* Edge network DDoS mitigation
* Automatic rate limiting
* IP blocking for abuse

### Security Headers

```typescript theme={null}
// next.config.ts
const securityHeaders = [
  { key: 'X-DNS-Prefetch-Control', value: 'on' },
  { key: 'Strict-Transport-Security', value: 'max-age=63072000' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
];

module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: securityHeaders,
      },
    ];
  },
};
```

## Vercel CLI

### Installation

```bash theme={null}
npm install -g vercel
```

### Common Commands

```bash theme={null}
# Link project
vercel link

# Deploy to production
vercel --prod

# Deploy to preview
vercel

# View deployments
vercel ls

# View logs
vercel logs

# Pull environment variables
vercel env pull .env.local

# Add environment variable
vercel env add DATABASE_URL production

# Remove deployment
vercel remove [deployment-url]
```

## Troubleshooting

### Build Failures

**Error:** "Command 'npm run build' exited with 1"

**Fix:**

1. Check build logs in Vercel dashboard
2. Run `npm run build` locally
3. Fix TypeScript errors
4. Check environment variables are set
5. Verify migrations don't have errors

### Deployment Timeout

**Error:** "Build exceeded maximum duration"

**Fix:**

* Optimize build (remove unnecessary dependencies)
* Enable build cache
* Contact Vercel support for timeout increase

### Environment Variable Not Found

**Error:** "Missing environment variable: X"

**Fix:**

1. Go to Vercel Dashboard → Settings → Environment Variables
2. Add missing variable
3. Select correct environments (Production/Preview)
4. Redeploy

### Domain Not Resolving

**Error:** "ERR\_NAME\_NOT\_RESOLVED"

**Fix:**

1. Check DNS configuration in Cloudflare
2. Verify CNAME points to `cname.vercel-dns.com`
3. Wait for DNS propagation (up to 48 hours)
4. Use `dig charle.agency` to check DNS

## Best Practices

<AccordionGroup>
  <Accordion title="Use Preview Deployments" icon="eye">
    Always test in preview before merging:

    1. Open PR
    2. Wait for preview deployment
    3. Test preview URL thoroughly
    4. Merge to main when confirmed working
  </Accordion>

  <Accordion title="Separate Production and Preview Variables" icon="split">
    Use different credentials for preview:

    * **Production:** Real database, real API keys
    * **Preview:** DEV database, test API keys
    * Never mix environments
  </Accordion>

  <Accordion title="Monitor After Deployment" icon="chart-line">
    Check Vercel Analytics after deploying:

    * Verify traffic is flowing
    * Check for errors in logs
    * Monitor Core Web Vitals
  </Accordion>

  <Accordion title="Keep Build Fast" icon="bolt">
    Optimize build time:

    * Remove unused dependencies
    * Enable build caching
    * Minimize dynamic imports
  </Accordion>
</AccordionGroup>

## Related Documentation

<CardGroup cols={2}>
  <Card title="Deployment Overview" icon="cloud" href="/developer/deployment">
    General deployment process
  </Card>

  <Card title="CI/CD" icon="circle-check" href="/developer/deployment/ci-cd">
    Automated testing pipeline
  </Card>

  <Card title="Environment Variables" icon="gear" href="/developer/getting-started/environment">
    All environment variables
  </Card>

  <Card title="Vercel Docs" icon="book" href="https://vercel.com/docs">
    Official Vercel documentation
  </Card>
</CardGroup>
