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
# Dosłownie jeden command
npm i -g vercel
vercel
# Lub połącz repo GitHub - każdy push = automatyczny deployPreview Deployments
Każdy Pull Request automatycznie dostaje:
- Unikalny URL do testowania
- Komentarz w PR z linkiem
- Możliwość sprawdzenia zmian przed merge
https://my-app-git-feature-branch-username.vercel.appGlobal 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
# Instalacja CLI
npm i -g vercel
# Deploy (interaktywny setup)
vercel
# Deploy do produkcji
vercel --prod
# Deploy z określoną konfiguracją
vercel --env NODE_ENV=productionMetoda 2: GitHub Integration
- Wejdź na vercel.com
- Kliknij "Add New Project"
- Wybierz repozytorium z GitHub
- Vercel automatycznie wykryje framework i skonfiguruje build
Metoda 3: Import z CLI
# Sklonuj i od razu zdeploy
npx create-next-app@latest my-app
cd my-app
vercelStruktura projektu Vercel
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.jsonKonfiguracja vercel.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)
// 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
// 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
// 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.
// 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
// 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
- Wejdź w Project Settings → Environment Variables
- Dodaj zmienne dla każdego environment (Production, Preview, Development)
CLI
# Dodaj zmienną
vercel env add DATABASE_URL production
# Lista zmiennych
vercel env ls
# Pull zmiennych do .env.local
vercel env pull .env.localTypy zmiennych
# 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=trueDomeny i SSL
Custom Domain
# Dodaj domenę przez CLI
vercel domains add example.com
# Lub w dashboard: Project Settings → DomainsAutomatyczny SSL
Vercel automatycznie:
- Generuje certyfikat SSL
- Odnawia certyfikat przed wygaśnięciem
- Obsługuje redirect z HTTP na HTTPS
Wildcard domains
*.example.com → Obsługuje wszystkie subdomenyAnalytics i Monitoring
Web Analytics
# Instalacja
npm i @vercel/analytics// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
</body>
</html>
)
}Speed Insights
npm i @vercel/speed-insights// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<SpeedInsights />
</body>
</html>
)
}Logs
# Real-time logs
vercel logs --follow
# Logs z production
vercel logs --production
# Filtrowanie
vercel logs --since 1hCron Jobs
// vercel.json
{
"crons": [
{
"path": "/api/daily-digest",
"schedule": "0 8 * * *"
},
{
"path": "/api/cleanup",
"schedule": "0 0 * * 0"
}
]
}// 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)
# Utwórz bazę w dashboard lub CLI
vercel postgres create my-database
# Połącz z projektem
vercel link
vercel env pull// lib/db.ts
import { sql } from '@vercel/postgres'
export async function getUsers() {
const { rows } = await sql`SELECT * FROM users`
return rows
}Blob Storage
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)
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
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
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}# Struktura
apps/
├── web/ # Next.js app
├── docs/ # Documentation site
└── admin/ # Admin panel
packages/
├── ui/ # Shared components
├── config/ # Shared config
└── database/ # Prisma clientVercel Monorepo Settings
W dashboard: Project Settings → Root Directory
apps/webdla projektu webapps/docsdla dokumentacji
CI/CD Customization
Ignore Build Step
# 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
{
"ignoreCommand": "bash vercel-ignore-build-step.sh"
}Custom Build
// vercel.json
{
"buildCommand": "npm run build:production",
"installCommand": "npm ci --legacy-peer-deps",
"framework": null
}Cennik (2025)
| Plan | Cena | Bandwidth | Serverless | Team |
|---|---|---|---|---|
| Hobby | Free | 100GB | 100GB-hrs | 1 user |
| Pro | $20/user/mo | 1TB | 1000GB-hrs | Unlimited |
| Enterprise | Custom | Unlimited | Unlimited | Custom |
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
| Aspekt | Vercel | Netlify | Railway | AWS Amplify |
|---|---|---|---|---|
| Next.js Support | Natywny | Adapter | Adapter | Adapter |
| Edge Functions | Tak | Tak | Nie | Tak |
| Preview Deploys | Tak | Tak | Tak | Tak |
| Pricing | Per-user | Per-site | Usage-based | Usage-based |
| Database | Postgres, KV | None | Postgres | DynamoDB |
| Best for | Next.js | Static/JAMstack | Full-stack | AWS ecosystem |
Best Practices
1. Optymalizuj build time
// 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
{
"build": {
"env": {
"VERCEL_FORCE_NO_BUILD_CACHE": "1"
}
}
}3. Używaj regions
// 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
# Sprawdź lokalne buildy
npm run build
# Sprawdź logi
vercel logs --followFunction timeout
// 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
# Wymuś rebuild bez cache
vercel --force
# Lub w dashboard: Redeploy with cleared cacheFAQ
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?
- Połącz repo z Vercel
- Skonfiguruj environment variables
- Dodaj custom domain
- 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