Vercel Edge Function
Generate optimized Vercel Edge Functions with geolocation, authentication, and data transformation
$ npx claude-code-templates@latest --command="nextjs-vercel/vercel-edge-function" --yesRequires Claude Code. The command adds this command to your project's .claudedirectory — nothing runs on ToolZip's servers.
What's inside this command
Component source (preview)
Vercel Edge Function Generator
Function Name: $ARGUMENTSCurrent Project Analysis
Project Structure
- Vercel config: @vercel.json (if exists)
- Next.js config: @next.config.js
- API routes: @app/api/ or @pages/api/
- Middleware: @middleware.ts (if exists)
Framework Detection
- Package.json: @package.json
- TypeScript config: @tsconfig.json (if exists)
- Environment variables: @.env.local (if exists)
Edge Function Implementation Strategy
1. File Structure Creation
Generate comprehensive edge function structure:
api/edge/[function-name]/
├── index.ts # Main edge function
├── types.ts # TypeScript types
├── utils.ts # Utility functions
├── config.ts # Configuration
└── __tests__/
└── [function-name].test.ts # Unit tests
2. Base Edge Function Template
// api/edge/[function-name]/index.ts
import { NextRequest, NextResponse } from 'next/server';
export const runtime = 'edge';
export async function GET(request: NextRequest) {
try {
// Get geolocation data
const country = request.geo?.country || 'Unknown';
const city = request.geo?.city || 'Unknown';
const region = request.geo?.region || 'Unknown';
// Get request metadata
const ip = request.headers.get('x-forwarded-for') || 'Unknown';
const userAgent = request.headers.get('user-agent') || 'Unknown';
const referer = request.headers.get('referer') || 'Unknown';
// Process request
const result = await processRequest({
geo: { country, city, region },
ip,
userAgent,
referer,
url: request.url,
});
return NextResponse.json(result, {
status: 200,
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=300',
'Content-Type': 'application/json',
'X-Edge-Location': region,
},
});
} catch (error) {
console.error('Edge function error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// Validate request body
const validationResult = validateRequestBody(body);
if (!validationResult.valid) {
return NextResponse.json(
{ error: 'Invalid request body', details: validationResult.errors },
{ status: 400 }
);
}
// Process POST request
const result = await processPostRequest(body, request);
return NextResponse.json(result, {
status: 201,
headers: {
'Content-Type': 'application/json',
},
});
} catch (error) {
console.error('Edge function POST error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
async function processRequest(metadata: RequestMetadata): Promise<any> {
// Implement your edge function logic here
return {
message: 'Edge function executed successfully',
metadata,
timestamp: new Date().toISOString(),
};
}
async function processPostRequest(body: any, request: NextRequest): Promise<any> {
// Implement POST logic here
return {
message: 'POST processed successfully',
data: body,
timestamp: new Date().toISOString(),
};
}
function validateRequestBody(body: any): ValidationResult {
// Implement validation logic
return { valid: true, errors: [] };
}
interface RequestMetadata {
geo: {
country: string;
city: string;
region: string;
};
ip: string;
userAgent: string;
referer: string;
url: string;
}
interface ValidationResult {
valid: boolean;
errors: string[];
}
Specialized Edge Function Types
1. Geolocation-Based Content Delivery
// api/edge/geo-content/index.ts
import { NextRequest, NextResponse } from 'next/server';
export const runtime = 'edge';
interface ContentConfig {
[country: string]: {
currency: string;
language: string;
content: string;
pricing: number;
};
}
const contentConfig: ContentConfig = {
'US': {
currency: 'USD',
language: 'en-US',
content: 'Welcome to our US store!',
pricing: 99.99,
},
'GB': {
currency: 'GBP',
language: 'en-GB',
content: 'Welcome to our UK store!',
pricing: 79.99,
},
'DE': {
currency: 'EUR',
language: 'de-DE',
content: 'Willkommen in unserem deutschen Shop!',
pricing: 89.99,
},
};
export async function GET(request: NextRequest) {
const country = request.geo?.country || 'US';
const config = contentConfig[country] || contentConfig['US'];
// Add region-specific headers
const response = NextResponse.json({
country,
...config,
edgeLocation: request.geo?.region,
timestamp: new Date().toISOString(),
});
response.headers.set('Cache-Control', 'public, s-maxage=3600, stale-while-revalidate=86400');
response.headers.set('Vary', 'Accept-Language, CloudFront-Viewer-Country');
response.headers.set('Content-Language', config.language);
return response;
}
2. Authentication Edge Function
// api/edge/auth-check/index.ts
import { NextRequest, NextResponse } from 'next/server';
import { jwtVerify } from 'jose';
export const runtime = 'edge';
const JWT_SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || 'your-secret-key'
);
export async function GET(request: NextRequest) {
try {
// Extract token from header or cookie
const authHeader = request.headers.get('authorization');
const cookieToken = request.cookies.get('auth-token')?.value;
const token = authHeader?.replace('Bearer ', '') || cookieToken;
if (!token) {
return NextResponse.json(
{ error: 'No token provided', authenticated: false },
{ status: 401 }
);
}
// Verify JWT token
const { payload } = await jwtVerify(token, JWT_SECRET);
// Return user info
return NextResponse.json({
authenticated: true,
user: {
id: payload.sub,
email: payload.email,
role: payload.role,
exp: payload.exp,
},
location: {
country: request.geo?.country,
city: request.geo?.city,
},
});
} catch (error) {
console.error('Auth verification failed:', error);
return NextResponse.json(
{ error: 'Invalid token', authenticated: false },
{ status: 401 }
);
}
}
export async function POST(request: NextRequest) {
try {
const { username, password } = await request.json();
// Validate credentials (implement your logic)
const user = await validateCredentials(username, password);
if (!user) {
return NextResponse.json(
{ error: 'Invalid credentials' },
{ status: 401 }
);
}
// Generate JWT token
const token = await generateJWT(user);
const response = NextResponse.json({
success: true,
user: {
id: user.id,
email: user.email,
role: user.role,
},
});
// Set secure cookie
response.cookies.set('auth-token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 24 * 60 * 60, // 24 hours
});
return response;
} catch (error) {
console.error('Authentication error:', error);
return NextResponse.json(
{ error: 'Authentication failed' },
{ status: 500 }
);
}
}
async function validateCredentials(username: string, password: string) {
// Implement credential validation
// This would typically involve database lookup
return null; // Placeholder
}
async function generateJWT(user: any): Promise<string> {
// Implement JWT generation
// This would use a proper JWT library
return 'jwt-token'; // Placeholder
}
3. Data Transformation Edge Function
``typescript
// api/edge/transform/index.ts
import { NextRequest, NextResponse } from 'next/server';
export const runtime = 'edge';
interface TransformConfig {
format: 'json' | 'xml' | 'csv';
fields?: string[];
transforms?: Record<string, (value: any) => any>;
}
const transformers = {
// Currency conversion
currency: (value: number, targetCurrency: string = 'USD') => {
const rates = { USD: 1, EUR: 0.85, GBP: 0.73 };
return value * (rates[targetCurrency as keyof typeof rates] || 1);
},
// Date formatting
date: (value: string, format: string = 'ISO') => {
const date = new Date(value);
if (format === 'ISO') return date.toISOString();
if (format === 'US') return date.toLocaleDateString('en-US');
return date.toString();
},
// Text formatting
text: (value: string, caseType: string = 'lower') => {
if (caseType === 'upper') return value.toUpperCase();
if (caseType === 'title') return value.replace(/\w\S*/g, txt =>
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
);
return value.toLowerCase();
},
};
export async function POST(request: NextRequest) {
try {
const { data, config }: { data: any; config: TransformConfig } = await request.json();
if (!data || !config) {
return NextResponse.json(
{ error: 'Missing data or config' },
{ status: 400 }
);
}
// Apply transformations
const transformedData = await transformData(data, config, request);
// Format output based on requested format
const output = await formatOutput(transformedData, config.format);
const response = new NextResponse(output, {
status: 200,
headers: {
'Content-Type': getContentType(config.format),
'Cache-Control': 'public, s-maxage=300',
},
});
return response;
} catch (error) {
console.error('Transform error:', error);
return NextResponse.json(
{ error: 'Transformation failed' },
{ status: 500 }
);
}
}
async function transformData(data: any, config: TransformConfig, request: NextRequest) {
const country = request.geo?.country || 'US';
// Apply field filtering if specified
if (config.fields && Array.isArray(data)) {
data = data.map(item => {
const filtered: any = {};
config.fields!.forEach(field => {
if (item.hasOwnProperty(field)) {
filtered[field] = item[field];
}
});
return filtered;
});
}
// Apply custom transforms
if (config.transforms) {
Object.entries(config.transforms).forEach(([field, transformFunc]) => {
if (Array.isArray(data)) {
data = data.map(item => ({
...item,
[field]: transformFunc(item[field]),
}));
} else if (data.hasOwnProperty(field)) {
data[field] = transformFunc(data[field]);
}
});
}
// Add geo context
return {
...data,
_meta: {
transformedAt: new Date().toISOString(),
location: country,
edgeRegion: request.geo?.region,
},
};
}
async function formatOutput(data: any, format: string): Promise<string> {
switch (format) {
case 'xml':
return jsonToXml(data);
case 'csv':
return jsonToCsv(data);
case 'json':
default:
return JSON.stringify(data, null, 2);
}
}
function getContentType(format: string): string {
switch (format) {
case 'xml': return 'application/xml';
case 'csv': return 'text/csv';
case 'json':
default: return 'application/json';
}
}
function jsonToXml(data: any): string {
// Simple XML conversion (implement proper XML library for production)
return
}
function jsonToCsv(data: any): string {
// Simple CSV conversion (implement proper CSV library for production)
if (Array.isArray(data) && data.length > 0) {
const headers = Object.keys(data[0]);
co
Preview truncated. View the full source on GitHub →
Related Claude Code Commands
Nextjs Component Generator
Generate optimized React components for Next.js with TypeScript and best practices
Nextjs Performance Audit
Comprehensive Next.js performance audit with actionable optimization recommendations
Nextjs Bundle Analyzer
Analyze and optimize Next.js bundle size with detailed recommendations
Vercel Deploy Optimize
Optimize and deploy Next.js application to Vercel with performance monitoring
Nextjs Api Tester
Test and validate Next.js API routes with comprehensive test scenarios
Vercel Env Sync
Synchronize environment variables between local development and Vercel deployments
Catalog data and component content are sourced from the open-source davila7/claude-code-templates project (MIT license). ToolZip curates the listing and writes original descriptions; every component links back to its original source. Claude Code is a product of Anthropic. ToolZip is an independent catalog and is not affiliated with or endorsed by Anthropic.