Edge Functions

Run code globally at the edge for ultra-fast responses

⚡ What are Edge Functions?

Edge Functions run your code on servers close to your users worldwide, providing lightning-fast responses. They're perfect for dynamic content that needs to be fast and globally distributed.


// app/api/hello/route.js
export const runtime = 'edge'

export async function GET(request) {
  return new Response('Hello from the Edge!', {
    headers: { 'content-type': 'text/plain' }
  })
}
                                    

Key Concepts

🌍

Global Distribution

Runs close to your users

// Deployed to 100+ locations

Ultra-Fast

Minimal latency, instant responses

// Response in milliseconds
📦

Lightweight Runtime

Limited APIs, optimized for speed

export const runtime = 'edge'
🔄

Dynamic Content

Personalize at the edge

const country = request.geo.country

🔹 Basic Edge Function

Convert any API route or page to an Edge Function by adding the runtime export. Edge Functions use a lightweight runtime for maximum speed.

// app/api/edge/route.js
export const runtime = 'edge'

export async function GET(request) {
  return new Response(
    JSON.stringify({ 
      message: 'Hello from Edge!',
      timestamp: new Date().toISOString()
    }),
    {
      headers: { 'content-type': 'application/json' }
    }
  )
}

🔹 Geolocation Data

Edge Functions have access to user geolocation data, allowing you to personalize content based on where your users are located.

// app/api/location/route.js
export const runtime = 'edge'

export async function GET(request) {
  const { geo } = request

  return Response.json({
    country: geo?.country || 'Unknown',
    region: geo?.region || 'Unknown',
    city: geo?.city || 'Unknown',
    latitude: geo?.latitude || 'Unknown',
    longitude: geo?.longitude || 'Unknown'
  })
}

// Returns: { country: 'US', region: 'CA', city: 'San Francisco', ... }

🔹 Edge Function with Fetch

Edge Functions can make external API calls using the standard fetch API, perfect for aggregating data from multiple sources.

// app/api/weather/route.js
export const runtime = 'edge'

export async function GET(request) {
  const { searchParams } = new URL(request.url)
  const city = searchParams.get('city') || 'London'

  try {
    const response = await fetch(
      `https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q=${city}`
    )
    const data = await response.json()

    return Response.json({
      city: data.location.name,
      temperature: data.current.temp_c,
      condition: data.current.condition.text
    })
  } catch (error) {
    return Response.json({ error: 'Failed to fetch weather' }, { status: 500 })
  }
}

🔹 Personalized Responses

Use Edge Functions to deliver personalized content based on user location, device, or other request properties.

// app/api/personalize/route.js
export const runtime = 'edge'

export async function GET(request) {
  const country = request.geo?.country || 'US'
  const userAgent = request.headers.get('user-agent') || ''
  const isMobile = /mobile/i.test(userAgent)

  // Personalize content
  const greeting = {
    'US': 'Hello',
    'FR': 'Bonjour',
    'ES': 'Hola',
    'DE': 'Guten Tag'
  }[country] || 'Hello'

  return Response.json({
    greeting,
    country,
    device: isMobile ? 'mobile' : 'desktop',
    message: `${greeting}! You're visiting from ${country} on a ${isMobile ? 'mobile' : 'desktop'} device.`
  })
}

🔹 Edge Function with Caching

Add cache headers to Edge Function responses to improve performance by caching responses at the edge network.

// app/api/cached/route.js
export const runtime = 'edge'

export async function GET(request) {
  const data = {
    message: 'This response is cached',
    timestamp: new Date().toISOString()
  }

  return new Response(JSON.stringify(data), {
    headers: {
      'content-type': 'application/json',
      'cache-control': 'public, s-maxage=60, stale-while-revalidate=30'
      // Cache for 60 seconds, serve stale for 30 seconds while revalidating
    }
  })
}

🔹 A/B Testing at the Edge

Implement A/B testing by randomly assigning users to different variants at the edge, ensuring fast and consistent experiences.

// app/api/ab-test/route.js
export const runtime = 'edge'

export async function GET(request) {
  // Get or create user variant
  const cookies = request.cookies
  let variant = cookies.get('ab-variant')?.value

  if (!variant) {
    // Randomly assign variant
    variant = Math.random() < 0.5 ? 'A' : 'B'
  }

  const response = Response.json({
    variant,
    message: variant === 'A' 
      ? 'Welcome to Version A!' 
      : 'Welcome to Version B!'
  })

  // Set cookie to persist variant
  response.headers.set(
    'Set-Cookie',
    `ab-variant=${variant}; Path=/; Max-Age=2592000`
  )

  return response
}

🔹 Edge vs Serverless

Understanding when to use Edge Functions versus traditional serverless functions helps you optimize your application performance.

Use Edge Functions for:

  • Low latency: When speed is critical
  • Global users: Serving international audiences
  • Simple logic: Lightweight operations
  • Personalization: Location-based content

Use Serverless Functions for:

  • Complex operations: Heavy computations
  • Database access: Direct database connections
  • Large dependencies: Full Node.js APIs
  • Long-running tasks: Operations over 30 seconds
// Edge Function (fast, lightweight)
export const runtime = 'edge'
export async function GET() {
  return Response.json({ data: 'Quick response' })
}

// Serverless Function (default, full Node.js)
export async function POST() {
  // Can use full Node.js APIs, connect to databases, etc.
  return Response.json({ data: 'Complex operation' })
}

🧠 Test Your Knowledge

What is the main advantage of Edge Functions?