Skip to main content
Every request to your Conductor application includes rich location data from Cloudflare’s edge network. Use it for localization, privacy compliance, and intelligent routing.

Overview

The location context is available on every AgentExecutionContext and provides:
  • Geographic data: Country, city, region, coordinates, timezone
  • Jurisdiction detection: GDPR, CCPA, LGPD, and other privacy laws
  • Consent helpers: Check if consent is required for specific purposes
  • Language inference: Detect preferred language from headers or country
  • Timezone utilities: Format times, check business hours
import type { AgentExecutionContext } from '@ensemble-edge/conductor'

export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  // Geographic
  console.log(location?.country)      // "DE"
  console.log(location?.city)         // "Berlin"

  // Jurisdiction
  console.log(location?.isGDPR)       // true
  console.log(location?.jurisdiction) // "GDPR"

  // Consent
  if (location?.requiresConsent('analytics')) {
    return { needsConsent: true }
  }

  // Language
  const lang = location?.preferredLanguage(['en', 'de', 'fr'])

  // Time
  const greeting = location?.getTimeOfDay() // "morning"
}

Geographic Data

Access location information extracted from Cloudflare’s edge:
export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  return {
    // Country
    country: location?.country,           // "US" (ISO code)
    countryName: location?.countryName,   // "United States"

    // Region/State
    region: location?.region,             // "Texas"
    regionCode: location?.regionCode,     // "TX"

    // City & Postal
    city: location?.city,                 // "Austin"
    postalCode: location?.postalCode,     // "78701"

    // Continent
    continent: location?.continent,       // "NA"
    continentName: location?.continentName, // "North America"

    // Coordinates
    latitude: location?.latitude,         // 30.2672
    longitude: location?.longitude,       // -97.7431
    coordinates: location?.coordinates,   // { lat: 30.2672, lng: -97.7431 }
  }
}

Region Checking

Use isIn() to check if the user is in specific regions or groups:
export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  // Check region groups
  if (location?.isIn(['EU'])) {
    // User is in European Union
  }

  if (location?.isIn(['APAC'])) {
    // User is in Asia-Pacific
  }

  // Check specific countries
  if (location?.isIn(['US', 'CA', 'MX'])) {
    // User is in North America
  }

  // Check specific state/region
  if (location?.isIn(['US-CA'])) {
    // User is in California
  }

  // Mix groups and countries
  if (location?.isIn(['GDPR', 'BR'])) {
    // User is in GDPR region OR Brazil
  }
}

Available Region Groups

GroupCountries
EU27 EU member states
EEAEU + Iceland, Liechtenstein, Norway
GDPREEA + UK
APACAsia-Pacific (CN, JP, KR, SG, AU, IN, etc.)
LATAMLatin America (BR, MX, AR, CL, etc.)
MENAMiddle East & North Africa
NORTH_AMERICAUS, CA, MX
ASEANSoutheast Asian nations
FIVE_EYESUS, GB, CA, AU, NZ
NINE_EYESFive Eyes + DK, FR, NL, NO
FOURTEEN_EYESNine Eyes + DE, BE, IT, SE, ES
G7US, GB, CA, FR, DE, IT, JP
G20Major economies
BRICSBR, RU, IN, CN, ZA
MERCOSURBR, AR, UY, PY

Jurisdiction Detection

Automatically detect which privacy laws apply to the user:
export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  // Primary jurisdiction
  const jurisdiction = location?.jurisdiction  // "GDPR" | "CCPA" | "LGPD" | etc.

  // All applicable jurisdictions
  const all = location?.jurisdictions  // ["GDPR"] or []

  // Convenience booleans
  const isGDPR = location?.isGDPR   // true for EEA + UK
  const isEU = location?.isEU       // true for EU members only
  const isEEA = location?.isEEA     // true for EU + Iceland/Liechtenstein/Norway
  const isCCPA = location?.isCCPA   // true for California
  const isLGPD = location?.isLGPD   // true for Brazil
}

Supported Jurisdictions

JurisdictionRegionModel
GDPREU + EEA + UKOpt-in
CCPACalifornia, USAOpt-out
LGPDBrazilOpt-in
PIPEDACanadaOpt-in
POPIASouth AfricaOpt-in
PDPASingaporeOpt-in
APPIJapanOpt-in
Check if consent is required before processing user data:
export default async function handler(ctx: AgentExecutionContext) {
  const { location, input } = ctx

  // Check specific purpose
  if (location?.requiresConsent('analytics')) {
    // User is in opt-in jurisdiction (GDPR, LGPD, etc.)
    if (!input.consents?.analytics) {
      return {
        requiresConsent: true,
        purposes: location.getRequiredConsentPurposes()
      }
    }
  }

  // Track analytics only with consent
  trackUserActivity(input.userId)

  return { success: true }
}
PurposeDescriptionGDPRCCPA
essentialCore functionalityNo consent neededNo consent needed
analyticsUsage trackingRequires consentAllowed (opt-out)
marketingAds, promotionsRequires consentAllowed (opt-out)
personalizationRecommendationsRequires consentAllowed (opt-out)
third_partyPartner sharingRequires consentAllowed (opt-out)
Get the consent model to use:
const model = location?.consentModel  // "opt-in" | "opt-out" | "none"

if (model === 'opt-in') {
  // Must get consent BEFORE processing (GDPR)
} else if (model === 'opt-out') {
  // Can process until user opts out (CCPA)
} else {
  // No consent requirements
}
The cookies operation integrates directly with location context to automatically enforce consent rules. When you specify a purpose for a cookie, the operation checks if consent is required and granted before setting the cookie.
agents:
  # This cookie only sets if analytics consent is granted (or not required)
  - name: set-analytics-cookie
    operation: cookies
    config:
      action: set
      name: _analytics_id
      value: ${generate-id.output}
      purpose: analytics     # Integrates with location context
      maxAge: 31536000

  # Essential cookies don't require consent
  - name: set-session-cookie
    operation: cookies
    config:
      action: set
      name: session_id
      value: ${session.id}
      purpose: essential     # Always allowed
      httpOnly: true
      secure: true
If a GDPR user hasn’t consented to analytics, the first cookie returns:
{
  "success": false,
  "skipped": true,
  "reason": "consent_required",
  "purpose": "analytics"
}
Pass user consent from your cookie banner:
# Request body: { "consents": { "analytics": true, "marketing": false } }
agents:
  - name: set-tracking
    operation: cookies
    config:
      action: set
      name: _tracker
      value: ${input.trackingId}
      purpose: marketing  # Will check input.consents.marketing
See cookies operation for full documentation.

Language Inference

Detect the user’s preferred language:
export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  // Best guess from Accept-Language header or country
  const language = location?.language  // "de"

  // Country's official languages
  const languages = location?.languages  // ["de"]

  // Is the language RTL?
  const isRTL = location?.isRTL  // false

  // Get best match from your supported languages
  const lang = location?.preferredLanguage(['en', 'de', 'fr', 'es'])
  // Returns 'de' if user prefers German, or best alternative

  return {
    greeting: translate('hello', lang),
    direction: isRTL ? 'rtl' : 'ltr'
  }
}

Language Matching Priority

  1. Accept-Language header - User’s browser preference
  2. Country’s primary language - Fallback based on location
  3. First supported language - Ultimate fallback

Timezone Utilities

Work with the user’s local time:
export default async function handler(ctx: AgentExecutionContext) {
  const { location } = ctx

  // IANA timezone identifier
  const timezone = location?.timezone  // "America/Chicago"

  // Offset from UTC
  const offset = location?.timezoneOffset      // -360 (minutes)
  const offsetHours = location?.timezoneOffsetHours  // -6

  // Daylight saving time
  const isDST = location?.isDST  // true/false

  // Format current time in user's timezone
  const localTime = location?.formatTime()  // "Dec 6, 2024, 2:30 PM"

  // Format a specific date
  const formatted = location?.formatTime(new Date('2024-12-25'))

  // Get current time as Date object
  const now = location?.now()

  // Time of day for greetings
  const timeOfDay = location?.getTimeOfDay()  // "morning" | "afternoon" | "evening"

  // Business hours check
  const isOpen = location?.isBusinessHours()  // true if 9 AM - 5 PM
  const isCustomHours = location?.isBusinessHours(8, 18)  // 8 AM - 6 PM
}

Smart Scheduling

export default async function handler(ctx: AgentExecutionContext) {
  const { location, input } = ctx

  // Only send notifications during business hours
  if (!location?.isBusinessHours(9, 17)) {
    return {
      scheduled: true,
      message: 'Notification queued for business hours'
    }
  }

  // Personalized greeting
  const greeting = {
    morning: 'Good morning',
    afternoon: 'Good afternoon',
    evening: 'Good evening'
  }[location?.getTimeOfDay() ?? 'afternoon']

  return {
    message: `${greeting}, ${input.name}!`
  }
}

Real-World Example

A complete example showing consent gating and localization:
import type { AgentExecutionContext } from '@ensemble-edge/conductor'

interface ConsentState {
  analytics?: boolean
  marketing?: boolean
}

export default async function handler(ctx: AgentExecutionContext) {
  const { location, input } = ctx

  // 1. Check consent requirements
  const requiredConsents = location?.getRequiredConsentPurposes() ?? []
  const userConsents: ConsentState = input.consents ?? {}

  const missingConsents = requiredConsents.filter(
    purpose => !userConsents[purpose as keyof ConsentState]
  )

  if (missingConsents.length > 0) {
    return {
      requiresConsent: true,
      purposes: missingConsents,
      consentModel: location?.consentModel,
      jurisdiction: location?.jurisdiction
    }
  }

  // 2. Get localized content
  const lang = location?.preferredLanguage(['en', 'de', 'fr', 'es']) ?? 'en'
  const greeting = getGreeting(location?.getTimeOfDay() ?? 'afternoon', lang)

  // 3. Format times in user's timezone
  const localTime = location?.formatTime()

  // 4. Track analytics (consent verified above)
  if (userConsents.analytics) {
    await trackPageView({
      country: location?.country,
      region: location?.regionCode,
      language: lang
    })
  }

  return {
    greeting,
    localTime,
    language: lang,
    direction: location?.isRTL ? 'rtl' : 'ltr'
  }
}

function getGreeting(
  timeOfDay: 'morning' | 'afternoon' | 'evening',
  lang: string
): string {
  const greetings: Record<string, Record<string, string>> = {
    en: { morning: 'Good morning', afternoon: 'Good afternoon', evening: 'Good evening' },
    de: { morning: 'Guten Morgen', afternoon: 'Guten Tag', evening: 'Guten Abend' },
    fr: { morning: 'Bonjour', afternoon: 'Bon après-midi', evening: 'Bonsoir' },
    es: { morning: 'Buenos días', afternoon: 'Buenas tardes', evening: 'Buenas noches' }
  }
  return greetings[lang]?.[timeOfDay] ?? greetings.en[timeOfDay]
}

async function trackPageView(data: Record<string, unknown>) {
  // Analytics implementation
}

TypeScript Types

Import types directly from the package:
import type {
  LocationContext,
  Jurisdiction,
  ConsentPurpose,
  ConsentModel
} from '@ensemble-edge/conductor'

// Jurisdiction: 'GDPR' | 'CCPA' | 'LGPD' | 'PIPEDA' | 'POPIA' | 'PDPA' | 'APPI'
// ConsentPurpose: 'essential' | 'analytics' | 'marketing' | 'personalization' | 'third_party'
// ConsentModel: 'opt-in' | 'opt-out' | 'none'

Next Steps