The Sentry Vercel Edge Runtime SDK provides error monitoring and performance tracking for Edge Functions and Edge Middleware running on Vercel’s Edge Network.
The @sentry/vercel-edge package is a low-level building block. For Next.js applications on Vercel, use @sentry/nextjs which includes Edge Runtime support automatically.
Installation
npm install @sentry/vercel-edge
When to Use
Use @sentry/vercel-edge for:
Standalone Edge Functions on Vercel
Edge Middleware (if not using Next.js)
Custom Edge applications
For Next.js applications , use @sentry/nextjs instead, which includes full Edge Runtime support.
Basic Setup
Edge Function
// api/hello.ts
import * as Sentry from '@sentry/vercel-edge' ;
Sentry . init ({
dsn: 'YOUR_DSN_HERE' ,
tracesSampleRate: 1.0 ,
environment: process . env . VERCEL_ENV ,
});
export const config = {
runtime: 'edge' ,
};
export default async function handler ( request : Request ) {
try {
return new Response (
JSON . stringify ({ message: 'Hello from Edge!' }),
{
status: 200 ,
headers: { 'Content-Type' : 'application/json' },
},
);
} catch ( error ) {
Sentry . captureException ( error );
return new Response (
JSON . stringify ({ error: 'Internal Server Error' }),
{ status: 500 },
);
}
}
Edge Middleware
// middleware.ts
import * as Sentry from '@sentry/vercel-edge' ;
import { NextRequest , NextResponse } from 'next/server' ;
Sentry . init ({
dsn: 'YOUR_DSN_HERE' ,
tracesSampleRate: 1.0 ,
});
export function middleware ( request : NextRequest ) {
try {
// Your middleware logic
const response = NextResponse . next ();
// Add custom headers
response . headers . set ( 'x-custom-header' , 'value' );
return response ;
} catch ( error ) {
Sentry . captureException ( error );
return NextResponse . next ();
}
}
export const config = {
matcher: '/api/:path*' ,
};
Error Handling
Manual Error Capture
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
const url = new URL ( request . url );
const userId = url . searchParams . get ( 'userId' );
try {
const user = await fetchUser ( userId );
return new Response ( JSON . stringify ( user ));
} catch ( error ) {
Sentry . captureException ( error , {
tags: {
function: 'fetchUser' ,
userId: userId || 'unknown' ,
},
contexts: {
request: {
url: request . url ,
method: request . method ,
},
},
});
return new Response (
JSON . stringify ({ error: 'User not found' }),
{ status: 404 },
);
}
}
Validation Errors
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
if ( request . method !== 'POST' ) {
return new Response ( 'Method not allowed' , { status: 405 });
}
try {
const body = await request . json ();
if ( ! body . email ) {
const error = new Error ( 'Email is required' );
Sentry . captureException ( error , {
level: 'warning' ,
tags: { validation: 'email' },
});
return new Response (
JSON . stringify ({ error: 'Email is required' }),
{ status: 400 },
);
}
// Process valid request
return new Response ( JSON . stringify ({ success: true }));
} catch ( error ) {
Sentry . captureException ( error );
return new Response ( 'Internal Server Error' , { status: 500 });
}
}
Custom Spans
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
return await Sentry . startSpan (
{
name: 'edge-function-handler' ,
op: 'function.edge' ,
},
async () => {
const data = await fetchData ();
return new Response ( JSON . stringify ( data ));
},
);
}
External API Calls
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
async function fetchExternalData ( id : string ) {
return await Sentry . startSpan (
{
name: 'external-api-call' ,
op: 'http.client' ,
attributes: {
'http.method' : 'GET' ,
'http.url' : `https://api.example.com/data/ ${ id } ` ,
},
},
async () => {
const response = await fetch ( `https://api.example.com/data/ ${ id } ` );
return response . json ();
},
);
}
export default async function handler ( request : Request ) {
const url = new URL ( request . url );
const id = url . searchParams . get ( 'id' );
const data = await fetchExternalData ( id ! );
return new Response ( JSON . stringify ( data ));
}
Database Queries
import * as Sentry from '@sentry/vercel-edge' ;
import { createClient } from '@vercel/edge-config' ;
const edgeConfig = createClient ( process . env . EDGE_CONFIG );
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
const value = await Sentry . startSpan (
{
name: 'edge-config.get' ,
op: 'db.query' ,
attributes: {
'db.system' : 'edge-config' ,
},
},
async () => {
return await edgeConfig . get ( 'feature-flag' );
},
);
return new Response ( JSON . stringify ({ value }));
}
Context and User Information
Request Context
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
const url = new URL ( request . url );
Sentry . setContext ( 'request' , {
url: request . url ,
method: request . method ,
headers: Object . fromEntries ( request . headers ),
});
Sentry . setContext ( 'geo' , {
city: request . headers . get ( 'x-vercel-ip-city' ),
country: request . headers . get ( 'x-vercel-ip-country' ),
region: request . headers . get ( 'x-vercel-ip-country-region' ),
});
// Your handler logic
return new Response ( 'OK' );
}
User Identification
import * as Sentry from '@sentry/vercel-edge' ;
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
// Extract user from JWT or cookie
const token = request . headers . get ( 'authorization' )?. replace ( 'Bearer ' , '' );
if ( token ) {
const user = await verifyToken ( token );
Sentry . setUser ({
id: user . id ,
email: user . email ,
username: user . username ,
});
}
// Your handler logic
return new Response ( 'OK' );
}
Edge Runtime Limitations
The Edge Runtime has limitations:
No Node.js APIs (fs, path, etc.)
Smaller bundle size limits
Limited execution time
No native modules
Sentry automatically adjusts for these constraints.
Environment Variables
Configure via Vercel dashboard or .env:
# Required
SENTRY_DSN = your-dsn-here
# Optional
SENTRY_TRACES_SAMPLE_RATE = 1.0
SENTRY_ENVIRONMENT = production
SENTRY_RELEASE = 1.0.0
Access Vercel system environment variables:
import * as Sentry from '@sentry/vercel-edge' ;
Sentry . init ({
dsn: process . env . SENTRY_DSN ,
environment: process . env . VERCEL_ENV , // 'production', 'preview', or 'development'
release: process . env . VERCEL_GIT_COMMIT_SHA ,
});
Vercel Integration
Preview Deployments
import * as Sentry from '@sentry/vercel-edge' ;
Sentry . init ({
dsn: process . env . SENTRY_DSN ,
environment: process . env . VERCEL_ENV ,
// Only sample in production
tracesSampleRate: process . env . VERCEL_ENV === 'production' ? 0.1 : 1.0 ,
beforeSend ( event ) {
// Add deployment URL to events
if ( process . env . VERCEL_URL ) {
event . tags = event . tags || {};
event . tags . deployment_url = process . env . VERCEL_URL ;
}
return event ;
},
});
Edge Config
Use Vercel Edge Config for feature flags:
import * as Sentry from '@sentry/vercel-edge' ;
import { createClient } from '@vercel/edge-config' ;
const edgeConfig = createClient ( process . env . EDGE_CONFIG );
export const config = { runtime: 'edge' };
export default async function handler ( request : Request ) {
const sentryEnabled = await edgeConfig . get ( 'sentry-enabled' );
if ( ! sentryEnabled ) {
// Skip Sentry initialization
return new Response ( 'OK' );
}
// Your handler with Sentry
}
Best Practices
Use Next.js SDK For Next.js apps, use @sentry/nextjs instead of this package.
Minimize Bundle Keep edge function bundles small for fast cold starts.
Set Context Add geo and request data for better debugging.
Sample Wisely Use lower sample rates in production to control volume.
Troubleshooting
Edge functions have strict size limits:
Minimize dependencies
Use dynamic imports where possible
Check bundle analyzer output
Edge functions have execution time limits:
Optimize async operations
Use appropriate timeouts for external calls
Consider moving heavy operations to serverless functions
Next Steps
Next.js Use Next.js SDK for full framework support
Edge Middleware Advanced middleware patterns
Edge Config Use Vercel Edge Config
Vercel Vercel deployment best practices