Elysia Tools
Navigation
Deployment
Vercel Deployment Samples
Vercel deployment configuration examples including vercel.json, serverless functions, and edge functions
Samples
Entries inside this sample collection
Vercel Basic Configuration
Basic Vercel configuration with custom domains, build settings, and environment variables
Difficulty
2/10
Estimated time
10 min
Tags
vercel, configuration, deployment
Prerequisites
Vercel basics, JavaScript/TypeScript
{
"version": 2,
"name": "my-app",
"builds": [
{
"src": "package.json",
"use": "@vercel/static-build",
"config": {
"distDir": "build"
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/build/$1"
}
],
"env": {
"NODE_ENV": "production"
},
"build": {
"env": {
"CUSTOM_KEY": "value"
}
},
"functions": {
"pages/api/**/*.js": {
"maxDuration": 10
}
}
}Vercel Next.js Configuration
Advanced Next.js configuration with ISR, image optimization, and monorepo support
Difficulty
5/10
Estimated time
20 min
Tags
vercel, next.js, framework
Prerequisites
Next.js, Vercel deployment, JavaScript/TypeScript
{
"version": 2,
"name": "nextjs-app",
"buildCommand": "npm run build",
"outputDirectory": ".next",
"installCommand": "npm install",
"framework": "nextjs",
"builds": [
{
"src": "package.json",
"use": "@vercel/next"
}
],
"functions": {
"pages/api/**/*.js": {
"maxDuration": 30,
"memory": 1024
}
},
"rewrites": [
{
"source": "/blog/:path*",
"destination": "/blog?slug=:path*"
},
{
"source": "/((?!api|_next/static|_next/image|favicon.ico).*)",
"destination": "/pages/$1"
}
],
"redirects": [
{
"source": "/old-path/:path*",
"destination": "/new-path/:path*",
"permanent": true
}
],
"headers": [
{
"source": "/api/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "s-maxage=86400"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
},
{
"source": "/(.*)\.(js|css|png|jpg|jpeg|gif|ico|svg)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
],
"images": {
"domains": ["example.com", "cdn.example.com"],
"sizes": [16, 32, 48, 64, 96, 128, 256, 384],
"minimumCacheTTL": 60,
"format": ["image/webp", "image/avif"]
}
}Vercel Serverless Functions
Serverless functions examples with different runtimes and use cases
Difficulty
6/10
Estimated time
25 min
Tags
vercel, functions, serverless, api
Prerequisites
JavaScript/TypeScript, API development, Serverless concepts
// Vercel Serverless Functions Examples
// 1. API Route with Node.js (Next.js)
// pages/api/users.js
export async function usersHandler(req, res) {
if (req.method === 'GET') {
try {
// Fetch users from database
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const users = await response.json();
res.status(200).json(users);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch users' });
}
} else if (req.method === 'POST') {
try {
const user = req.body;
// Validate input
if (!user.name || !user.email) {
return res.status(400).json({ error: 'Name and email are required' });
}
// Create user logic here
const newUser = {
id: Date.now(),
...user,
createdAt: new Date().toISOString()
};
res.status(201).json(newUser);
} catch (error) {
res.status(500).json({ error: 'Failed to create user' });
}
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end('Method Not Allowed');
}
}
// 2. Edge Function with TypeScript
// api/edge-function.ts
import { NextRequest, NextResponse } from 'next/server';
export const config = {
runtime: 'edge'
};
export function edgeFunctionHandler(req: NextRequest) {
const url = req.nextUrl;
const searchParams = url.searchParams;
// Get IP address and user agent
const ip = req.ip || req.headers.get('x-forwarded-for');
const userAgent = req.headers.get('user-agent') || '';
// Get geolocation from headers
const country = req.headers.get('x-vercel-ip-country') || 'Unknown';
const region = req.headers.get('x-vercel-ip-country-region') || 'Unknown';
// Response with location data
const response = {
ip,
userAgent,
location: {
country,
region,
city: req.headers.get('x-vercel-ip-city') || 'Unknown'
},
timestamp: new Date().toISOString()
};
return NextResponse.json(response, {
status: 200,
headers: {
'Cache-Control': 's-maxage=60, stale-while-revalidate=300',
'Access-Control-Allow-Origin': '*'
}
});
}
// 3. Background Function
// api/background-task.js
export async function backgroundTaskHandler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const { email, data } = req.body;
// Start background processing
setTimeout(async () => {
try {
// Send email
await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.RESEND_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
from: '[email protected]',
to: [email],
subject: 'Your background task is complete',
html: `<p>Your data has been processed: ${JSON.stringify(data, null, 2)}</p>`
})
});
console.log('Background task completed successfully');
} catch (error) {
console.error('Background task failed:', error);
}
}, 0);
res.status(202).json({
message: 'Background task started',
taskId: Date.now()
});
} catch (error) {
res.status(500).json({ error: 'Failed to start background task' });
}
}
// 4. Cron Job Function
// api/cron-job.js
export async function cronJobHandler(req, res) {
// Verify cron secret
const cronSecret = req.headers['x-vercel-cron-secret'];
if (cronSecret !== process.env.CRON_SECRET) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
// Perform scheduled tasks
const tasks = await Promise.allSettled([
cleanupOldFiles(),
sendDailyReports(),
updateAnalytics()
]);
const results = tasks.map((task, index) => ({
task: ['cleanup', 'reports', 'analytics'][index],
status: task.status,
value: task.status === 'fulfilled' ? task.value : task.reason.message
}));
res.status(200).json({
message: 'Cron job completed',
timestamp: new Date().toISOString(),
results
});
} catch (error) {
res.status(500).json({ error: 'Cron job failed' });
}
}
async function cleanupOldFiles() {
// Cleanup logic here
return 'Cleaned up 125 old files';
}
async function sendDailyReports() {
// Report sending logic here
return 'Sent 45 daily reports';
}
async function updateAnalytics() {
// Analytics update logic here
return 'Updated analytics data';
}
// 5. Webhook Handler
// api/webhook.js
import crypto from 'crypto';
export async function webhookHandler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const signature = req.headers['x-webhook-signature'];
const secret = process.env.WEBHOOK_SECRET;
// Verify webhook signature
if (!verifySignature(req.body, signature, secret)) {
return res.status(401).json({ error: 'Invalid signature' });
}
try {
const event = JSON.parse(req.body);
switch (event.type) {
case 'user.created':
await handleUserCreated(event.data);
break;
case 'payment.completed':
await handlePaymentCompleted(event.data);
break;
default:
console.log('Unknown event type:', event.type);
}
res.status(200).json({ received: true });
} catch (error) {
res.status(500).json({ error: 'Failed to process webhook' });
}
}
function verifySignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const expectedSignature = hmac.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
async function handleUserCreated(userData) {
console.log('User created:', userData);
// Handle user creation logic
}
async function handlePaymentCompleted(paymentData) {
console.log('Payment completed:', paymentData);
// Handle payment logic
}Vercel Monorepo Configuration
Monorepo setup with multiple applications, shared packages, and workspace management
Difficulty
8/10
Estimated time
35 min
Tags
vercel, monorepo, workspace
Prerequisites
Monorepo concepts, Vercel advanced, Turborepo/NX
{
"version": 2,
"name": "monorepo-app",
"builds": [
{
"src": "apps/web/package.json",
"use": "@vercel/next",
"config": {
"distDir": "build"
}
},
{
"src": "apps/api/package.json",
"use": "@vercel/static-build",
"config": {
"outputDirectory": "dist"
}
},
{
"src": "apps/docs/package.json",
"use": "@vercel/static-build",
"config": {
"outputDirectory": ".vitepress/dist"
}
}
],
"installCommand": "npm install --workspaces --if-present",
"routes": [
{
"src": "/api/(.*)",
"dest": "/apps/api/$1"
},
{
"src": "/docs/(.*)",
"dest": "/apps/docs/$1"
},
{
"handle": "filesystem"
},
{
"src": "/(.*)",
"dest": "/apps/web/$1"
}
],
"functions": {
"apps/web/pages/api/**/*.js": {
"maxDuration": 30
},
"apps/api/dist/**/*.js": {
"maxDuration": 60
}
},
"env": {
"NODE_ENV": "production",
"TURBOREPO_CACHE": "BLOB"
},
"build": {
"env": {
"VERCEL": "1",
"TURBO_TOKEN": "@vercel/turbopack-token"
}
},
"regions": ["iad1", "sfo1"],
"framework": null
}Tools
Tools frequently paired with this sample
Related