DevOps & Cloud

Vercel: Frontend Cloud Platform

TOKEN

Panduan lengkap Vercel β€” deploy Next.js, serverless functions, edge functions, preview deployments, environment variables, domain management, dan best practices untuk frontend deployment

1. Pengenalan Vercel

Vercel adalah cloud platform yang dirancang khusus untuk frontend developer. Didirikan oleh Guillermo Rauch (pembuat Socket.io dan Mongoose), Vercel adalah perusahaan di balik Next.js β€” framework React paling populer saat ini. Platform ini menyediakan infrastruktur yang dioptimalkan untuk frontend, memungkinkan developer untuk deploy dengan mudah dan cepat.

Vercel menawarkan pendekatan Git-centric deployment β€” setiap push ke repository secara otomatis menghasilkan deployment baru. Tidak perlu mengkonfigurasi CI/CD pipeline, Docker, atau server. Cukup hubungkan repository, dan Vercel menangani sisanya.

Mengapa Vercel Populer?

Keunggulan Penjelasan
Zero-Config DeployAuto-detect framework, build, dan deploy tanpa konfigurasi
Preview DeploymentsSetiap PR mendapatkan URL preview untuk review
Edge NetworkGlobal CDN β€” konten disajikan dari edge terdekat ke user
Serverless FunctionsBackend API tanpa mengelola server
Edge FunctionsCode yang berjalan di edge β€” latency sangat rendah
Next.js OptimalFirst-class support untuk Next.js β€” ISR, SSR, SSG, App Router
Free TierHobby plan gratis untuk personal project β€” cukup generous
DX TerbaikDeveloper experience yang sangat baik β€” logs, analytics, speed insights
Diagram: Vercel Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          β”‚     β”‚              VERCEL PLATFORM                   β”‚
β”‚  Users   │────►│  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚ (Global) │◄────│  β”‚         EDGE NETWORK (CDN)            β”‚     β”‚
β”‚          β”‚     β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”          β”‚     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚  β”‚  β”‚ US   β”‚ β”‚ EU   β”‚ β”‚ APAC β”‚  ...     β”‚     β”‚
                 β”‚  β”‚  β”‚ Edge β”‚ β”‚ Edge β”‚ β”‚ Edge β”‚          β”‚     β”‚
                 β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜          β”‚     β”‚
                 β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
                 β”‚                 β”‚                              β”‚
                 β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
                 β”‚  β”‚         RUNTIME                       β”‚     β”‚
                 β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚     β”‚
                 β”‚  β”‚  β”‚ Static   β”‚  β”‚ Serverless       β”‚  β”‚     β”‚
                 β”‚  β”‚  β”‚ Assets   β”‚  β”‚ Functions (Node)  β”‚  β”‚     β”‚
                 β”‚  β”‚  β”‚ (ISR/SSG)β”‚  β”‚ Edge Functions    β”‚  β”‚     β”‚
                 β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚     β”‚
                 β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β–Ό            β–Ό            β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Database β”‚ β”‚  CMS     β”‚ β”‚  APIs    β”‚
              β”‚ (Planet β”‚ β”‚ (Content β”‚ β”‚ (Custom) β”‚
              β”‚  Scale)  β”‚ β”‚  ful)    β”‚ β”‚          β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ’‘ Tips

Vercel bukan hanya untuk Next.js β€” mendukung React, Vue, Svelte, Astro, Nuxt, Remix, Gatsby, dan banyak lagi. Namun integrasi terbaik memang dengan Next.js karena Vercel adalah pengembangnya.

2. Memulai dengan Vercel

Instalasi Vercel CLI

Bash
# Install Vercel CLI global
npm install -g vercel

# Atau gunakan npx (tanpa install global)
npx vercel --version

# Login ke akun Vercel
vercel login
# Browser akan terbuka untuk autentikasi

# Verifikasi login
vercel whoami

Deploy Pertama

Bash
# Buat project Next.js baru
npx create-next-app@latest my-vercel-app
cd my-vercel-app

# Deploy ke Vercel (preview)
vercel

# Deploy ke production
vercel --prod

# Deploy dengan nama project spesifik
vercel --name my-awesome-app --prod

# Tampilkan URL deployment
vercel ls

# Lihat log deployment
vercel logs https://my-awesome-app.vercel.app

Deploy dari Git Repository

Cara termudah untuk deploy adalah menghubungkan repository Git. Setiap push akan otomatis trigger deployment.

Bash
# Cara 1: Import dari Vercel Dashboard (https://vercel.com/new)
# - Pilih repository dari GitHub/GitLab/Bitbucket
# - Vercel auto-detect framework settings
# - Klik Deploy

# Cara 2: Link existing project
vercel link

# Cara 3: Deploy dari Git dengan Vercel CLI
vercel --git-url https://github.com/username/repo

3. Deploy Next.js

Vercel memberikan dukungan terbaik untuk Next.js. Semua fitur Next.js β€” SSR, SSG, ISR, App Router, Server Components, dan Streaming β€” berfungsi optimal di Vercel tanpa konfigurasi tambahan.

Routing di Next.js (App Router)

TypeScript
// app/page.tsx β€” Home page
export default function HomePage() {
  return (
    <main>
      <h1>Selamat Datang di Aplikasi Saya</h1>
      <p>Dideploy dengan Vercel πŸš€</p>
    </>
  );
}

// app/about/page.tsx β€” Static page (SSG)
export default function AboutPage() {
  return <h1>Tentang Kami</h1>;
}

// app/blog/[slug]/page.tsx β€” Dynamic page (SSR/ISR)
interface Props {
  params: Promise<{ slug: string }>;
}

export default async function BlogPost({ params }: Props) {
  const { slug } = await params;
  const post = await fetch(
    `https://api.example.com/posts/${slug}`,
    { next: { revalidate: 3600 } } // ISR: revalidate setiap jam
  ).then(r => r.json());

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

// app/api/users/route.ts β€” API Route
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const users = await db.user.findMany();
  return NextResponse.json(users);
}

export async function POST(request: NextRequest) {
  const body = await request.json();
  const user = await db.user.create({ data: body });
  return NextResponse.json(user, { status: 201 });
}

Rendering Modes di Vercel

Mode Kapan Render Contoh
Static (SSG)Saat buildHalaman About, Landing page
SSRSaat requestDashboard user, Search results
ISRSaat build, revalidate berkalaBlog post, Product pages
Streaming SSRProgressive streamingHalaman dengan slow data fetch
πŸ’‘ Tips

Gunakan Static (SSG) sebisa mungkin untuk performa terbaik. Gunakan ISR untuk konten yang berubah sesekali. Gunakan SSR hanya ketika data harus selalu fresh berdasarkan request user.

4. Serverless Functions

Serverless Functions di Vercel memungkinkan Anda menjalankan backend code tanpa mengelola server. Setiap file di folder api/ (Pages Router) atau app/api/ (App Router) secara otomatis menjadi API endpoint.

Contoh Serverless Function

TypeScript
// app/api/hello/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  return NextResponse.json({
    message: 'Hello from Vercel Serverless!',
    timestamp: new Date().toISOString(),
    region: process.env.VERCEL_REGION || 'unknown'
  });
}

// app/api/users/[id]/route.ts β€” Dynamic API route
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { id } = await params;
  const user = await getUserFromDB(id);
  
  if (!user) {
    return NextResponse.json(
      { error: 'User not found' },
      { status: 404 }
    );
  }
  
  return NextResponse.json(user);
}

// app/api/upload/route.ts β€” File upload handler
export async function POST(request: NextRequest) {
  const formData = await request.formData();
  const file = formData.get('file') as File;
  
  if (!file) {
    return NextResponse.json(
      { error: 'No file uploaded' },
      { status: 400 }
    );
  }
  
  // Process file...
  const bytes = await file.arrayBuffer();
  const buffer = Buffer.from(bytes);
  
  return NextResponse.json({
    filename: file.name,
    size: buffer.length,
    type: file.type
  });
}

Runtime & Configuration

JSON
// vercel.json β€” Konfigurasi serverless functions
{
  "functions": {
    "app/api/heavy-task/**": {
      "maxDuration": 60,
      "memory": 1024
    },
    "app/api/quick/**": {
      "maxDuration": 10,
      "memory": 256
    }
  },
  "regions": ["sin1"],  // Deploy ke Singapore region
  "crons": [
    {
      "path": "/api/cron/daily-cleanup",
      "schedule": "0 0 * * *"
    }
  ]
}

// Runtime Node.js yang tersedia di Vercel:
// - Node.js 18 (default)
// - Node.js 20
// - Python 3.9
// - Go 1.x
// - Ruby 3.2

5. Edge Functions

Edge Functions berjalan di edge network Vercel β€” dekat dengan user. Berbeda dengan Serverless Functions yang berjalan di satu region, Edge Functions dieksekusi di lebih dari 70 edge locations secara global, menghasilkan latency yang sangat rendah.

Serverless vs Edge Functions

Aspek Serverless Functions Edge Functions
RuntimeNode.js (full)Edge Runtime (subset)
LokasiSatu region70+ edge locations
Cold Start🟑 Ada (50-250ms)🟒 Sangat cepat (<50ms)
BatasHingga 50MB bundle, 256MB RAM4MB bundle, 128MB RAM
NPM Packages🟒 Semua🟑 Edge-compatible only
Use CaseComplex logic, heavy computationAuth, A/B testing, geolocation, rewrites

Contoh Edge Function

TypeScript
// Middleware β€” Edge Function yang berjalan sebelum setiap request
// middleware.ts (di root project)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*']
};

export function middleware(request: NextRequest) {
  // Geolocation-based redirect
  const country = request.geo?.country || 'US';
  const locale = country === 'ID' ? 'id' : 'en';
  
  // Authentication check
  const token = request.cookies.get('auth-token')?.value;
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  
  // A/B testing β€” 50/50 split
  const bucket = request.cookies.get('ab-bucket')?.value;
  if (!bucket) {
    const newBucket = Math.random() < 0.5 ? 'A' : 'B';
    const response = NextResponse.next();
    response.cookies.set('ab-bucket', newBucket);
    return response;
  }
  
  // Add custom headers
  const response = NextResponse.next();
  response.headers.set('x-user-country', country);
  response.headers.set('x-ab-bucket', bucket || 'A');
  return response;
}

// app/api/geo/route.ts β€” Edge API Route
export const runtime = 'edge';

export async function GET(request: NextRequest) {
  const { geo, headers } = request;
  
  return new Response(JSON.stringify({
    country: geo?.country,
    city: geo?.city,
    region: geo?.region,
    latitude: geo?.latitude,
    longitude: geo?.longitude,
    ip: headers.get('x-forwarded-for'),
    userAgent: headers.get('user-agent')
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
}

6. Preview Deployments

Salah satu fitur terbaik Vercel adalah Preview Deployments. Setiap pull request di GitHub secara otomatis menghasilkan deployment preview dengan URL unik. Ini memungkinkan tim untuk review perubahan secara visual sebelum merge ke production.

Cara Kerja Preview Deployments

Diagram: Preview Deployments Flow
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Developerβ”‚    β”‚   GitHub     β”‚    β”‚     Vercel        β”‚
β”‚          │───►│   Pull       │───►│                   β”‚
β”‚ git push β”‚    β”‚   Request    β”‚    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚          β”‚    β”‚              β”‚    β”‚  β”‚ Preview     β”‚  β”‚
β”‚          β”‚    β”‚              │◄───│  β”‚ Deploy      β”‚  β”‚
β”‚          β”‚    β”‚              β”‚    β”‚  β”‚ (auto URL)  β”‚  β”‚
β”‚          β”‚    β”‚              β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚          β”‚    β”‚              β”‚    β”‚         β”‚         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β–Ό
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚  Preview URL:                β”‚
                              β”‚  my-app-abc123.vercel.app    β”‚
                              β”‚                              β”‚
                              β”‚  βœ… Auto comment di PR       β”‚
                              β”‚  βœ… Lighthouse score          β”‚
                              β”‚  βœ… Screenshot preview        β”‚
                              β”‚  βœ… Web Analytics preview     β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Team     β”‚    β”‚   Review     β”‚    β”‚     Vercel        β”‚
β”‚ Member   │◄──│   PR di      │◄──│                   β”‚
β”‚          │───►│   GitHub     │───►│  Comment otomatis β”‚
β”‚ Approve  β”‚    β”‚              β”‚    β”‚  dengan URL       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Branch Alias

Bash
# Preview deployments mendapatkan URL random
# Contoh: my-app-git-feature-login-username.vercel.app

# Set branch alias untuk URL yang lebih mudah diingat
# Di Vercel Dashboard > Project > Settings > Domains
# atau dengan CLI:
vercel alias set my-app-git-feature-login-username.vercel.app staging.myapp.com

# Set branch-level alias otomatis di vercel.json
{
  "git": {
    "deploymentEnabled": {
      "main": true,
      "develop": true,
      "feature/*": true
    }
  }
}
πŸ’‘ Tips

Aktifkan "Protect Preview Deployments" di settings untuk membatasi akses preview hanya ke tim Anda. Ini penting jika preview mengandung data sensitif atau belum siap untuk publik.

7. Environment Variables

Environment variables di Vercel digunakan untuk menyimpan konfigurasi yang berbeda per environment (development, preview, production). Vercel mendukung beberapa jenis variable yang bisa diakses di build time atau runtime.

Jenis Environment Variables

Jenis Penggunaan
NEXT_PUBLIC_*Exposed ke client browser (build-time)
Server-onlyHanya tersedia di server/API routes (runtime)
EncryptedTer-enkripsi di Vercel, tidak bisa dilihat lagi
Bash
# Set environment variable via CLI
vercel env add DATABASE_URL
# Pilih environment: Production, Preview, Development

# Set untuk semua environment sekaligus
vercel env add API_SECRET production preview development

# List semua environment variables
vercel env ls

# Pull environment variables ke .env.local
vercel env pull .env.local

# Hapus environment variable
vercel env rm DATABASE_URL
⚠️ Peringatan

Jangan pernah commit .env.local ke Git! Pastikan .env.local ada di .gitignore. Gunakan Vercel Dashboard atau CLI untuk mengelola environment variables di production.

8. Custom Domains

Vercel mendukung custom domains dengan SSL otomatis. Setiap project mendapatkan .vercel.app subdomain gratis, tetapi untuk production sebaiknya gunakan domain sendiri.

Menambah Custom Domain

Bash
# Tambah domain via CLI
vercel domains add myapp.com

# Tambah subdomain
vercel domains add blog.myapp.com

# List semua domains
vercel domains ls

# Konfigurasi DNS:
# Type: A Record, Name: @, Value: 76.76.21.21
# Type: CNAME, Name: www, Value: cname.vercel-dns.com

# Wildcard domain (Pro/Enterprise plan)
vercel domains add "*.myapp.com"

# Redirect www ke apex domain
# Di vercel.json:
{
  "redirects": [
    { "source": "https://www.myapp.com/:path*", "destination": "https://myapp.com/:path*", "permanent": true }
  ]
}

9. Caching & ISR

Vercel memiliki caching layer yang sangat canggih yang terintegrasi langsung dengan Next.js. Incremental Static Regeneration (ISR) adalah fitur unggulan yang memungkinkan Anda meng-update konten statis tanpa rebuild seluruh site.

ISR di Next.js

TypeScript
// app/products/[id]/page.tsx β€” ISR dengan revalidation
export const revalidate = 60; // Revalidate setiap 60 detik

export default async function ProductPage({ params }) {
  const { id } = await params;
  const product = await fetch(
    `https://api.store.com/products/${id}`,
    { next: { revalidate: 60, tags: ['products'] } }
  );
  
  return (
    <div>
      <h1>{product.name}</h1>
      <p>Harga: Rp {product.price}</p>
    </div>
  );
}

// On-demand revalidation via API route
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const { tag, secret } = await request.json();
  
  if (secret !== process.env.REVALIDATION_SECRET) {
    return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });
  }
  
  revalidateTag(tag); // 'products'
  return NextResponse.json({ revalidated: true, tag });
}

10. Best Practices

Performance

Deployment

Pricing Tips

Plan Harga Cocok Untuk
Hobby (Free)$0/bulanPersonal project, portfolio, belajar
Pro$20/user/bulanTim kecil, startup, production apps
EnterpriseCustomPerusahaan besar, SLA, SSO, advanced security

πŸ“ Quiz Pemahaman

Pertanyaan 1: Apa yang terjadi setiap kali Anda push code ke branch yang terhubung dengan Vercel?

a) Tidak ada yang terjadi
b) Deployment preview otomatis dibuat
c) Production langsung ter-update
d) Build error muncul di GitHub

Pertanyaan 2: Apa perbedaan utama antara Serverless Functions dan Edge Functions?

a) Edge Functions lebih mahal
b) Edge Functions berjalan di satu region, Serverless di banyak region
c) Edge Functions berjalan di 70+ edge locations, Serverless di satu region
d) Tidak ada perbedaan

Pertanyaan 3: Apa itu ISR (Incremental Static Regeneration)?

a) Build ulang seluruh site setiap kali ada perubahan
b) Render halaman di server setiap request
c) Regenerate halaman statis secara incremental tanpa rebuild seluruh site
d) Cache halaman secara permanen

Pertanyaan 4: Environment variable dengan prefix apa yang bisa diakses di client browser?

a) VERCEL_PUBLIC_*
b) PUBLIC_*
c) NEXT_PUBLIC_*
d) CLIENT_*

Pertanyaan 5: Berapa harga Vercel Hobby (Free) plan?

a) $10/bulan
b) $5/bulan
c) $0 (gratis)
d) $20/bulan
πŸ” Zoom
100%
🎨 Tema