Edge computing brings your code closer to users for ultra-fast response times.
Vercel Edge Middleware
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Geolocation
const country = request.geo?.country || 'US';
const city = request.geo?.city || 'Unknown';
// A/B Testing
const bucket = Math.random() < 0.5 ? 'a' : 'b';
const response = NextResponse.next();
response.cookies.set('bucket', bucket);
response.headers.set('x-user-location', `${city}, ${country}`);
return response;
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
Edge Authentication
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { jwtVerify } from 'jose';
export async function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
try {
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
await jwtVerify(token, secret);
return NextResponse.next();
} catch (error) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
export const config = {
matcher: '/dashboard/:path*',
};
Cloudflare Workers
// worker.ts
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
// Route handling
if (url.pathname === '/api/hello') {
return new Response(JSON.stringify({ message: 'Hello from the edge!' }), {
headers: { 'Content-Type': 'application/json' },
});
}
// Proxy to origin
return fetch(request);
},
};
KV Storage (Edge)
// Cloudflare KV
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const key = new URL(request.url).pathname.slice(1);
// Get from KV
const value = await env.MY_KV.get(key);
if (!value) {
return new Response('Not found', { status: 404 });
}
return new Response(value);
},
};
// Set values
await env.MY_KV.put('key', 'value', {
expirationTtl: 3600, // 1 hour
});
// Delete
await env.MY_KV.delete('key');
Edge Functions with Vercel
// app/api/edge/route.ts
import { NextRequest, NextResponse } from 'next/server';
export const runtime = 'edge';
export async function GET(request: NextRequest) {
const data = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
});
return NextResponse.json(await data.json());
}
Rate Limiting at Edge
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const RATE_LIMIT = 10; // requests
const WINDOW = 60000; // 1 minute
const requests = new Map<string, number[]>();
export function middleware(request: NextRequest) {
const ip = request.ip || 'unknown';
const now = Date.now();
const userRequests = requests.get(ip) || [];
const recentRequests = userRequests.filter((time) => now - time < WINDOW);
if (recentRequests.length >= RATE_LIMIT) {
return new NextResponse('Too many requests', { status: 429 });
}
recentRequests.push(now);
requests.set(ip, recentRequests);
return NextResponse.next();
}
Edge Caching
export async function GET(request: NextRequest) {
const url = new URL(request.url);
const cacheKey = url.pathname + url.search;
// Check edge cache
const cache = await caches.open('my-cache');
let response = await cache.match(cacheKey);
if (!response) {
// Fetch from origin
const data = await fetchData();
response = new NextResponse(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 's-maxage=60, stale-while-revalidate',
},
});
// Store in edge cache
await cache.put(cacheKey, response.clone());
}
return response;
}
Geolocation Routing
export function middleware(request: NextRequest) {
const country = request.geo?.country;
// Route based on country
const countryRoutes: Record<string, string> = {
US: '/en',
DE: '/de',
FR: '/fr',
JP: '/ja',
};
const route = countryRoutes[country || 'US'] || '/en';
if (!request.nextUrl.pathname.startsWith(route)) {
return NextResponse.redirect(new URL(route, request.url));
}
return NextResponse.next();
}
Bot Detection
export function middleware(request: NextRequest) {
const userAgent = request.headers.get('user-agent') || '';
const botPatterns = [/bot/i, /crawler/i, /spider/i, /scraper/i];
const isBot = botPatterns.some((pattern) => pattern.test(userAgent));
if (isBot) {
return new NextResponse('Bot detected', {
status: 403,
headers: {
'X-Robots-Tag': 'noindex',
},
});
}
return NextResponse.next();
}
Feature Flags at Edge
const FEATURES: Record<string, boolean> = {
'new-ui': true,
'beta-feature': false,
experimental: false,
};
export function middleware(request: NextRequest) {
const features = Object.entries(FEATURES)
.filter(([_, enabled]) => enabled)
.map(([name]) => name)
.join(',');
const response = NextResponse.next();
response.headers.set('x-enabled-features', features);
return response;
}
Cloudflare Durable Objects
export class Counter {
state: DurableObjectState;
value: number = 0;
constructor(state: DurableObjectState) {
this.state = state;
this.state.blockConcurrencyWhile(async () => {
this.value = (await this.state.storage.get('value')) || 0;
});
}
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === '/increment') {
this.value++;
await this.state.storage.put('value', this.value);
}
return new Response(this.value.toString());
}
}
Edge computing delivers low-latency experiences by running code close to users worldwide.
Posted ondevopswith tags: