Vercel
intermediate
25-30 minutes

Advanced Features

Master Vercel's advanced features: Analytics, Speed Insights, Image Optimization, ISR, and more.

What you'll accomplish

Production-optimized Vercel deployment with analytics and performance features

Prerequisites

  • Project deployed to Vercel
  • Next.js application (for some features)

Vercel Analytics

Track real user metrics without impacting privacy.

Enable Analytics

tsx
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

Or install separately:

bash
npm install @vercel/analytics

What Analytics Tracks

  • Page views - Real visitor counts
  • Unique visitors - Without cookies or fingerprinting
  • Top pages - Most visited content
  • Referrers - Where traffic comes from
  • Countries - Geographic distribution
  • Devices - Desktop vs mobile
  • Browsers - Chrome, Safari, Firefox, etc.

Custom Events

tsx
import { track } from '@vercel/analytics';

// Track custom events
track('signup_completed', {
  plan: 'pro',
  source: 'homepage',
});

// Track button clicks
<button onClick={() => track('cta_clicked')}>
  Sign Up
</button>
Note

Vercel Analytics is privacy-focused - no cookies, no personal data collection. GDPR compliant by default.

Speed Insights

Measure real Core Web Vitals from actual users.

Enable Speed Insights

tsx
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <SpeedInsights />
      </body>
    </html>
  );
}

Metrics Tracked

MetricWhat It MeasuresGood Score
LCPLargest Contentful Paint< 2.5s
FIDFirst Input Delay< 100ms
CLSCumulative Layout Shift< 0.1
TTFBTime to First Byte< 800ms
FCPFirst Contentful Paint< 1.8s
INPInteraction to Next Paint< 200ms

Viewing Results

  1. Go to your project in Vercel Dashboard
  2. Click Speed Insights tab
  3. View metrics over time, by page, by device

Image Optimization

Vercel automatically optimizes images for Next.js.

Basic Usage

tsx
import Image from 'next/image';

export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      width={1200}
      height={600}
      alt="Hero image"
      priority
    />
  );
}

Features

  • Automatic format conversion - WebP/AVIF when supported
  • Lazy loading - Images load as they scroll into view
  • Responsive sizing - Different sizes for different screens
  • CDN caching - Optimized images cached globally
  • Blur placeholder - Show blurred preview while loading

Remote Images

javascript
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.example.com',
        pathname: '/uploads/**',
      },
    ],
  },
};

Responsive Images

tsx
<Image
  src="/hero.jpg"
  alt="Hero"
  fill
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  style={{ objectFit: 'cover' }}
/>

Incremental Static Regeneration (ISR)

Update static pages without full rebuilds.

Time-Based Revalidation

tsx
// app/blog/[slug]/page.tsx
export const revalidate = 60; // Revalidate every 60 seconds

export default async function BlogPost({ params }) {
  const post = await getPost(params.slug);
  return <article>{post.content}</article>;
}

On-Demand Revalidation

tsx
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache';

export async function POST(request: Request) {
  const { path, tag, secret } = await request.json();

  // Verify secret
  if (secret !== process.env.REVALIDATION_SECRET) {
    return Response.json({ error: 'Invalid secret' }, { status: 401 });
  }

  if (path) {
    revalidatePath(path);
  }

  if (tag) {
    revalidateTag(tag);
  }

  return Response.json({ revalidated: true });
}

Call from your CMS or webhook:

bash
curl -X POST https://your-app.vercel.app/api/revalidate \
  -H "Content-Type: application/json" \
  -d '{"path": "/blog/my-post", "secret": "your-secret"}'

Preview Deployments

Every branch and PR gets a unique preview URL.

Automatic Previews

main branch      → your-app.vercel.app (production)
feature-branch   → your-app-git-feature-branch-user.vercel.app
PR #42           → your-app-pr-42-user.vercel.app

Comment Integration

Vercel automatically comments on PRs with:

  • Preview URL
  • Build status
  • Deployment details

Configure in vercel.json:

json
{
  "github": {
    "silent": false,
    "autoJobCancelation": true
  }
}

Preview Environment Variables

Set different values for preview deployments:

  • Database: staging connection
  • API keys: test credentials
  • Feature flags: enabled for testing

Branch Deployments

Protect Production Branch

Only allow production deploys from specific branches:

  1. Go to Project Settings → Git
  2. Set Production Branch to main
  3. Enable "Ignored Build Step" for other branches if needed

Deploy Hooks

Trigger deployments programmatically:

  1. Project Settings → Git → Deploy Hooks
  2. Create a hook with a name
  3. Use the webhook URL to trigger deploys
bash
curl -X POST https://api.vercel.com/v1/integrations/deploy/prj_xxx/yyy

Cron Jobs

Schedule serverless functions to run automatically.

Define in vercel.json

json
{
  "crons": [
    {
      "path": "/api/cron/daily-cleanup",
      "schedule": "0 0 * * *"
    },
    {
      "path": "/api/cron/hourly-check",
      "schedule": "0 * * * *"
    }
  ]
}

Create the Handler

typescript
// app/api/cron/daily-cleanup/route.ts
export async function GET(request: Request) {
  // Verify the request is from Vercel Cron
  const authHeader = request.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  // Run your scheduled task
  await cleanupOldData();

  return Response.json({ success: true });
}

Cron Schedule Syntax

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6)
│ │ │ │ │
* * * * *

Examples:

  • 0 0 * * * - Daily at midnight
  • 0 */6 * * * - Every 6 hours
  • 0 9 * * 1 - Monday at 9am
  • */15 * * * * - Every 15 minutes (Pro plan)

Web Analytics Firewall

Block bad bots and protect your site:

  1. Go to Project Settings → Firewall
  2. Enable protection rules
  3. Configure IP blocking, rate limiting

Vercel KV

Key-value storage at the edge.

bash
# Install
npm install @vercel/kv
typescript
import { kv } from '@vercel/kv';

// Set a value
await kv.set('user:123', { name: 'John', email: '[email protected]' });

// Get a value
const user = await kv.get('user:123');

// Set with expiration
await kv.set('session:abc', { userId: 123 }, { ex: 3600 });

// Increment
await kv.incr('page:views');

Vercel Postgres

Serverless Postgres with connection pooling.

bash
npm install @vercel/postgres
typescript
import { sql } from '@vercel/postgres';

// Query
const { rows } = await sql`SELECT * FROM users WHERE id = ${userId}`;

// Insert
await sql`INSERT INTO users (name, email) VALUES (${name}, ${email})`;

Vercel Blob

Store files in the cloud.

bash
npm install @vercel/blob
typescript
import { put, del } from '@vercel/blob';

// Upload file
const { url } = await put('avatars/user123.png', file, {
  access: 'public',
});

// Delete file
await del(url);

Monorepo Support

Vercel supports monorepos with Turborepo, Nx, and others.

Root Directory

json
// vercel.json in root
{
  "projects": {
    "apps/web": {
      "name": "web"
    },
    "apps/docs": {
      "name": "docs"
    }
  }
}

Turborepo Remote Caching

bash
npx turbo login
npx turbo link

Caches build artifacts across your team for faster builds.

Deployment Protection

Password Protection (Pro)

Protect preview deployments:

  1. Project Settings → Deployment Protection
  2. Enable "Vercel Authentication" or "Password Protection"
  3. Set a password

Trusted IPs (Enterprise)

Restrict access to specific IP ranges.

Build Optimization

Skip Builds

Ignore builds when only certain files change:

bash
# vercel.json
{
  "ignoreCommand": "git diff --quiet HEAD^ HEAD ./apps/web"
}

Build Cache

Vercel caches:

  • node_modules
  • .next/cache
  • Build outputs

Clear cache: Project Settings → General → Build Cache → Clear

Troubleshooting Performance

Slow Cold Starts

  1. Reduce function bundle size
  2. Use Edge runtime for simple functions
  3. Implement connection pooling for databases
  4. Use Vercel's managed services (KV, Postgres)

Large Bundle Size

bash
# Analyze bundle
ANALYZE=true npm run build

High Latency

  1. Check function region matches your users
  2. Use Edge functions for latency-sensitive operations
  3. Cache responses with proper headers
  4. Use ISR for static content
Note

Checkpoint: Enable Analytics and Speed Insights in your app, then check the dashboard after a few hours of traffic to see your metrics.