Elysia Tools
Navigation mobile
Deployment
Exemples Vercel Deployment
Exemples de configuration Vercel deployment incluant vercel.json, serverless functions et edge functions
Exemples
Entrées de cette collection
Configuration Vercel de Base
Configuration Vercel de base avec domaines personnalisés, paramètres de build et variables d'environnement
Difficulté
2/10
Temps estimé
10 min
Étiquettes
vercel, configuration, deployment
Prérequis
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
}
}
}Configuration Vercel Next.js
Configuration Next.js avancée avec ISR, optimisation d'images et support monorepo
Difficulté
5/10
Temps estimé
20 min
Étiquettes
vercel, next.js, framework
Prérequis
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
Exemples de serverless functions avec différents runtimes et cas d'usage
Difficulté
6/10
Temps estimé
25 min
Étiquettes
vercel, functions, serverless, api
Prérequis
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
}Configuration Vercel Monorepo
Setup monorepo avec applications multiples, paquets partagés et gestion de workspaces
Difficulté
8/10
Temps estimé
35 min
Étiquettes
vercel, monorepo, workspace
Prérequis
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
}Outils
Outils souvent utilisés avec cet exemple
Associé