Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik10 min czytania

Vercel

Vercel to platforma cloud dla frontend developerów z automatycznym CI/CD, preview deployments, serverless functions i edge computing. Poznaj deployment, konfigurację i integracje.

Vercel - Kompletny przewodnik po platformie dla frontend developerów

Czym jest Vercel i dlaczego dominuje rynek frontend hostingu?

Vercel to platforma cloud stworzona przez twórców Next.js, która zrewolucjonizowała sposób w jaki deployujemy aplikacje frontendowe. Oferuje zero-config deployment, automatyczne CI/CD, preview deployments dla każdego PR, serverless functions i edge computing - wszystko w jednym miejscu.

W przeciwieństwie do tradycyjnych hostingów, Vercel został zaprojektowany z myślą o nowoczesnym frontend development workflow. Każdy push do repozytorium automatycznie triggeruje build i deployment, a każdy Pull Request dostaje unikalny URL do testowania.

Dlaczego Vercel?

Zero-config deployment

Code
Bash
# Dosłownie jeden command
npm i -g vercel
vercel

# Lub połącz repo GitHub - każdy push = automatyczny deploy

Preview Deployments

Każdy Pull Request automatycznie dostaje:

  • Unikalny URL do testowania
  • Komentarz w PR z linkiem
  • Możliwość sprawdzenia zmian przed merge
Code
TEXT
https://my-app-git-feature-branch-username.vercel.app

Global Edge Network

Vercel deployuje Twoją aplikację na 100+ lokalizacji na całym świecie. Użytkownicy dostają content z najbliższego serwera.

Pierwszy deployment

Metoda 1: CLI

Code
Bash
# Instalacja CLI
npm i -g vercel

# Deploy (interaktywny setup)
vercel

# Deploy do produkcji
vercel --prod

# Deploy z określoną konfiguracją
vercel --env NODE_ENV=production

Metoda 2: GitHub Integration

  1. Wejdź na vercel.com
  2. Kliknij "Add New Project"
  3. Wybierz repozytorium z GitHub
  4. Vercel automatycznie wykryje framework i skonfiguruje build

Metoda 3: Import z CLI

Code
Bash
# Sklonuj i od razu zdeploy
npx create-next-app@latest my-app
cd my-app
vercel

Struktura projektu Vercel

Code
TEXT
my-project/
├── app/                    # Next.js App Router
├── pages/                  # Next.js Pages Router
├── api/                    # API Routes (serverless functions)
├── public/                 # Static files
├── vercel.json             # Konfiguracja Vercel (opcjonalna)
└── package.json

Konfiguracja vercel.json

Code
JSON
{
  "buildCommand": "npm run build",
  "outputDirectory": ".next",
  "devCommand": "npm run dev",
  "installCommand": "npm install",

  "framework": "nextjs",

  "regions": ["iad1", "cdg1"],

  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "*" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,POST,PUT,DELETE" }
      ]
    },
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "X-Frame-Options", "value": "DENY" }
      ]
    }
  ],

  "redirects": [
    {
      "source": "/old-blog/:slug",
      "destination": "/blog/:slug",
      "permanent": true
    },
    {
      "source": "/twitter",
      "destination": "https://twitter.com/mycompany",
      "permanent": false
    }
  ],

  "rewrites": [
    {
      "source": "/api/external/:path*",
      "destination": "https://external-api.com/:path*"
    },
    {
      "source": "/docs/:match*",
      "destination": "https://docs.example.com/:match*"
    }
  ],

  "cleanUrls": true,
  "trailingSlash": false
}

Serverless Functions

Vercel automatycznie wykrywa i deployuje serverless functions z folderu api/ lub app/api/.

API Route (Next.js App Router)

TSapp/api/users/route.ts
TypeScript
// app/api/users/route.ts
import { NextResponse } from 'next/server'

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const id = searchParams.get('id')

  // Twoja logika
  const users = await fetchUsers(id)

  return NextResponse.json(users)
}

export async function POST(request: Request) {
  const body = await request.json()

  // Twoja logika
  const user = await createUser(body)

  return NextResponse.json(user, { status: 201 })
}

Standalone Serverless Function

TSapi/hello.ts
TypeScript
// api/hello.ts (standalone, bez Next.js)
import type { VercelRequest, VercelResponse } from '@vercel/node'

export default function handler(req: VercelRequest, res: VercelResponse) {
  const { name = 'World' } = req.query

  res.status(200).json({
    message: `Hello ${name}!`
  })
}

Konfiguracja funkcji

TSapi/slow-function.ts
TypeScript
// api/slow-function.ts
export const config = {
  maxDuration: 60, // Max 60 sekund (Pro plan)
  memory: 1024,    // 1GB RAM
}

export default async function handler(req, res) {
  // Długo trwająca operacja
}

Edge Functions

Edge Functions działają na Cloudflare Workers - ultra szybkie, globalne, z minimalnym cold start.

TSapp/api/geo/route.ts
TypeScript
// app/api/geo/route.ts
export const runtime = 'edge'

export async function GET(request: Request) {
  // Dostęp do geo data z request headers
  const country = request.headers.get('x-vercel-ip-country')
  const city = request.headers.get('x-vercel-ip-city')
  const region = request.headers.get('x-vercel-ip-country-region')

  return Response.json({
    country,
    city,
    region,
    greeting: getLocalizedGreeting(country)
  })
}

function getLocalizedGreeting(country: string | null) {
  const greetings: Record<string, string> = {
    PL: 'Cześć!',
    US: 'Hello!',
    DE: 'Hallo!',
    FR: 'Bonjour!',
    ES: 'Hola!'
  }
  return greetings[country || 'US'] || 'Hello!'
}

Edge Middleware

TSmiddleware.ts
TypeScript
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Sprawdź auth token
  const token = request.cookies.get('auth-token')

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  // A/B testing
  const bucket = Math.random() < 0.5 ? 'a' : 'b'
  const response = NextResponse.next()
  response.cookies.set('ab-bucket', bucket)

  // Geo-based routing
  const country = request.geo?.country || 'US'
  if (country === 'DE' && request.nextUrl.pathname === '/') {
    return NextResponse.redirect(new URL('/de', request.url))
  }

  return response
}

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)']
}

Environment Variables

Dashboard

  1. Wejdź w Project Settings → Environment Variables
  2. Dodaj zmienne dla każdego environment (Production, Preview, Development)

CLI

Code
Bash
# Dodaj zmienną
vercel env add DATABASE_URL production

# Lista zmiennych
vercel env ls

# Pull zmiennych do .env.local
vercel env pull .env.local

Typy zmiennych

Code
TEXT
# Production-only secrets
DATABASE_URL=postgresql://...
API_SECRET=super-secret-key

# Public (dostępne w client-side)
NEXT_PUBLIC_API_URL=https://api.example.com

# Preview-specific
NEXT_PUBLIC_PREVIEW_MODE=true

Domeny i SSL

Custom Domain

Code
Bash
# Dodaj domenę przez CLI
vercel domains add example.com

# Lub w dashboard: Project Settings → Domains

Automatyczny SSL

Vercel automatycznie:

  • Generuje certyfikat SSL
  • Odnawia certyfikat przed wygaśnięciem
  • Obsługuje redirect z HTTP na HTTPS

Wildcard domains

Code
TEXT
*.example.com → Obsługuje wszystkie subdomeny

Analytics i Monitoring

Web Analytics

Code
Bash
# Instalacja
npm i @vercel/analytics
TSapp/layout.tsx
TypeScript
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}

Speed Insights

Code
Bash
npm i @vercel/speed-insights
TSapp/layout.tsx
TypeScript
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights />
      </body>
    </html>
  )
}

Logs

Code
Bash
# Real-time logs
vercel logs --follow

# Logs z production
vercel logs --production

# Filtrowanie
vercel logs --since 1h

Cron Jobs

vercel.json
JSON
// vercel.json
{
  "crons": [
    {
      "path": "/api/daily-digest",
      "schedule": "0 8 * * *"
    },
    {
      "path": "/api/cleanup",
      "schedule": "0 0 * * 0"
    }
  ]
}
TSapp/api/daily-digest/route.ts
TypeScript
// app/api/daily-digest/route.ts
export async function GET(request: Request) {
  // Sprawdź czy to cron request
  const authHeader = request.headers.get('authorization')
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 })
  }

  // Twoja logika cron job
  await sendDailyDigestEmails()

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

Integracje

Database (Vercel Postgres)

Code
Bash
# Utwórz bazę w dashboard lub CLI
vercel postgres create my-database

# Połącz z projektem
vercel link
vercel env pull
TSlib/db.ts
TypeScript
// lib/db.ts
import { sql } from '@vercel/postgres'

export async function getUsers() {
  const { rows } = await sql`SELECT * FROM users`
  return rows
}

Blob Storage

Code
TypeScript
import { put, del, list } from '@vercel/blob'

// Upload
const blob = await put('avatars/user-123.png', file, {
  access: 'public'
})

// Delete
await del(blob.url)

// List
const { blobs } = await list({ prefix: 'avatars/' })

KV (Redis)

Code
TypeScript
import { kv } from '@vercel/kv'

// Set
await kv.set('user:123', { name: 'Alice' })
await kv.set('session:abc', 'data', { ex: 3600 }) // TTL 1h

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

// Hash
await kv.hset('user:123', { visits: 1 })
await kv.hincrby('user:123', 'visits', 1)

Edge Config

Code
TypeScript
import { get } from '@vercel/edge-config'

// Ultra-szybki odczyt konfiguracji
const featureFlags = await get('feature-flags')

if (featureFlags?.newCheckout) {
  // Nowy checkout
}

Monorepo Support

Turborepo

turbo.json
JSON
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}
Code
Bash
# Struktura
apps/
├── web/           # Next.js app
├── docs/          # Documentation site
└── admin/         # Admin panel
packages/
├── ui/            # Shared components
├── config/        # Shared config
└── database/      # Prisma client

Vercel Monorepo Settings

W dashboard: Project Settings → Root Directory

  • apps/web dla projektu web
  • apps/docs dla dokumentacji

CI/CD Customization

Ignore Build Step

vercel-ignore-build-step.sh
Bash
# vercel-ignore-build-step.sh
#!/bin/bash

# Jeśli zmieniono tylko docs, pomiń build
if git diff --quiet HEAD^ HEAD -- docs/; then
  echo "No changes in source code. Skipping build."
  exit 0
fi

exit 1
vercel.json
JSON
// vercel.json
{
  "ignoreCommand": "bash vercel-ignore-build-step.sh"
}

Custom Build

vercel.json
JSON
// vercel.json
{
  "buildCommand": "npm run build:production",
  "installCommand": "npm ci --legacy-peer-deps",
  "framework": null
}

Cennik (2025)

PlanCenaBandwidthServerlessTeam
HobbyFree100GB100GB-hrs1 user
Pro$20/user/mo1TB1000GB-hrsUnlimited
EnterpriseCustomUnlimitedUnlimitedCustom

Hobby Limits

  • 100GB bandwidth/month
  • 100 deployments/day
  • Serverless function timeout: 10s
  • Edge function timeout: 30s
  • No team features

Pro Features

  • 1TB bandwidth
  • Serverless timeout: 60s
  • Password protection
  • Team collaboration
  • Priority support
  • Advanced analytics

Vercel vs Alternatywy

AspektVercelNetlifyRailwayAWS Amplify
Next.js SupportNatywnyAdapterAdapterAdapter
Edge FunctionsTakTakNieTak
Preview DeploysTakTakTakTak
PricingPer-userPer-siteUsage-basedUsage-based
DatabasePostgres, KVNonePostgresDynamoDB
Best forNext.jsStatic/JAMstackFull-stackAWS ecosystem

Best Practices

1. Optymalizuj build time

JSnext.config.js
JavaScript
// next.config.js
module.exports = {
  // Użyj standalone output dla mniejszych deploymentów
  output: 'standalone',

  // Wyłącz source maps w produkcji
  productionBrowserSourceMaps: false,
}

2. Cache dependencies

Vercel automatycznie cache'uje node_modules, ale możesz to kontrolować:

vercel.json
JSON
// vercel.json
{
  "build": {
    "env": {
      "VERCEL_FORCE_NO_BUILD_CACHE": "1"
    }
  }
}

3. Używaj regions

Code
TypeScript
// Określ region dla funkcji
export const config = {
  regions: ['iad1', 'cdg1'] // US East, France
}

4. Monitoruj usage

  • Sprawdzaj dashboard regularnie
  • Ustaw alerty na zbliżanie się do limitów
  • Analizuj funkcje zużywające najwięcej zasobów

Troubleshooting

Build fails

Code
Bash
# Sprawdź lokalne buildy
npm run build

# Sprawdź logi
vercel logs --follow

Function timeout

Code
TypeScript
// Zwiększ timeout (Pro plan required)
export const config = {
  maxDuration: 60
}

// Lub użyj Edge dla szybszych cold starts
export const runtime = 'edge'

Cache issues

Code
Bash
# Wymuś rebuild bez cache
vercel --force

# Lub w dashboard: Redeploy with cleared cache

FAQ

Czy mogę używać Vercel z innymi frameworkami niż Next.js?

Tak! Vercel obsługuje: React, Vue, Nuxt, Svelte, SvelteKit, Astro, Remix, Gatsby, Angular i wiele innych.

Jak przenieść się z innego hostingu?

  1. Połącz repo z Vercel
  2. Skonfiguruj environment variables
  3. Dodaj custom domain
  4. Zmień DNS na Vercel

Czy Vercel jest drogi?

Free tier jest bardzo hojny dla projektów osobistych. Pro ($20/user/mo) to standard dla komercyjnych projektów. Enterprise dla dużych firm.

Czy mogę self-hostować Next.js zamiast Vercel?

Tak, Next.js można hostować na dowolnym serwerze Node.js. Vercel oferuje jednak najlepszą integrację i wiele funkcji out of the box.

Podsumowanie

Vercel to najlepsza platforma dla projektów Next.js i nowoczesnego frontend development:

  • Zero-config - Deploy w sekundy
  • Preview Deployments - Testuj każdy PR
  • Edge Network - Globalnie szybkie
  • Serverless - Bez zarządzania serwerami
  • Integracje - Database, blob, KV, analytics