Supercharge your analytics with real world context from Radar

In this recipe, you'll learn how to use location data to understand where your customers are when they engage with you.


Made by Radar

What do you need?

  • A website

  • A Segment Workspace

  • A Radar Account

Using Segment Destination Functions and Radar location enrichment, it is easy to build a solution that enables location data insights and activation.

Before building location based features to improve the customer experience and increase engagement, it is important to develop an understanding of which real-world locations are important customer touchpoints. 

It is critical to be able to answer questions like the examples below in order to effectively prioritize location based features:

  • Where are customers in the real world when they are searching for products on my mobile site? 

    • Are they searching while at competitor locations? 

    • Are they in our stores? 

    • Do certain locations generate more search requests than others? 

  • Where are customers when they first install our app? 

    • Are my in-store download incentives and signage leading to conversions? 

    • Are specific stores driving significantly more downloads than others?

  • How far are customers from my nearest store when they order delivery vs pickup?

Radar and Segment can be used to efficiently answer these types of questions and in turn influence location feature prioritization to maximize the customer impact.

In this example, we will analyze the physical locations from where customers search on our website. We will represent the American superstore Walmart and we are interested in seeing if we should prioritize specific offers when potential customers are on our website at competitors.

Step 1: Enrich Segment Events with location

The first step is to enrich existing Segment Track calls with location data following the common fields spec

As you can see in the code snippet below, Radar has a sample function that tracks mobile web searches in Segment and leverages built-in browser capabilities to get the current device position and add it as event context.

Step 2: Set up Radar

The next step is to set up Radar to enrich the location context that will be fed via Segment. You can configure both custom geofences specific to your business as well as tap into the Radar places database for out-of-the-box geofences.

Enabling places:

Configuring Radar

Adding Geofences:

Viewing Geofences

Step 3: Setup Segment Destination Function

Now that Radar is set up with the right context and your digital properties are sending through location data to Segment, you can forward that Segment data onto Radar for enrichment and analytics. 

In this case we will use a Segment Destinations Function to enrich Segment track events by forwarding them to Radar’s track API. When creating the function, you can add a setting for the Radar publishable key, which will be accessed via the Radar dashboard.

Adding the Radar Publishable Key:

// This example uses the Radar track API /** * Handle track event * @param {SegmentTrackEvent} event * @param {FunctionSettings} settings */ async function onTrack(event, settings) { const endpoint = ''; let response; try { if (hasRequiredIdentifiers(event) && hasRequiredLocationContext(event)) { radarTrackPayload = createPayload(event); setIfDefined(event,'anonymousId',radarTrackPayload,'metadata.segmentAnonymousId'); setIfDefined(event, 'userId', radarTrackPayload, 'userId'); setIfDefined(event, 'context.os.version', radarTrackPayload, 'deviceOS'); setIfDefined(event,'context.device.manufacturer',radarTrackPayload,'deviceMake'); setIfDefined(event,'context.device.model',radarTrackPayload,'deviceModel'); response = await fetch(endpoint, { method: 'POST', headers: { Authorization: `${settings.radarPublishableKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(radarTrackPayload) }); } else { throw new InvalidEventPayload('Missing required attributes'); } } catch (error) { // Retry on connection error throw new RetryError(error.message); } if (response.status >= 500 || response.status === 429) { // Retry on 5xx (server errors) and 429s (rate limits) throw new RetryError(`Failed with ${response.status}`); } } const setIfDefined = ( sourceObject, sourcePath, destObject, destPath, defaultValue ) => { let value = _.get(sourceObject, sourcePath); if (value !== undefined) { _.set(destObject, destPath, value); } else if (defaultValue !== undefined) { _.set(destObject, destPath, defaultValue); } }; /** * Handle identify event * @param {SegmentIdentifyEvent} event * @param {FunctionSettings} settings */ async function onIdentify(event, settings) { throw new EventNotSupported('identify is not supported'); } /** * Handle group event * @param {SegmentGroupEvent} event * @param {FunctionSettings} settings */ async function onGroup(event, settings) { throw new EventNotSupported('group is not supported'); } /** * Handle page event * @param {SegmentPageEvent} event * @param {FunctionSettings} settings */ async function onPage(event, settings) { throw new EventNotSupported('page is not supported'); } /** * Handle screen event * @param {SegmentScreenEvent} event * @param {FunctionSettings} settings */ async function onScreen(event, settings) { throw new EventNotSupported('screen is not supported'); } /** * Handle alias event * @param {SegmentAliasEvent} event * @param {FunctionSettings} settings */ async function onAlias(event, settings) { throw new EventNotSupported('alias is not supported'); } /** * Handle delete event * @param {SegmentDeleteEvent} event * @param {FunctionSettings} settings */ async function onDelete(event, settings) { throw new EventNotSupported('delete is not supported'); } function hasRequiredLocationContext(event) { if (event.context?.location?.latitude && event.context?.location?.longitude) { return true; } else { return false; } } function hasRequiredIdentifiers(event) { if (event.context?.device?.id || event.anonymousId) { return true; } else { return false; } } function deviceTypeTransform(deviceType) { if (deviceType) { switch (deviceType.toLowerCase()) { case 'ios': return 'iOS'; case 'android': return 'Android'; default: return 'Web'; } } else { return 'Web'; } } const createPayload = e => { var date = new Date(); return { deviceId: e.context.device?.id ?? e.anonymousId, latitude: e.context.location.latitude, longitude: e.context.location.longitude, accuracy: e.context.location.accuracy ?? 65, deviceType: deviceTypeTransform(e.context.device?.type), foreground: true, stopped: true, metadata: {}, updatedAt: e.sentAt ?? date.toISOString() }; };

Once the function is set up, you can establish the connection from the relevant sources feeding in events with location data to the Radar Enrichment destination function.

When events are fed through Segment, they will show up both in Segment’s debugger and Radar Locations and Events streams.




Step 4: Analyze Data

Now that we have event data in Radar, we can analyze real world engagement patterns to drive location feature prioritization. Radar will be generating events which can be filtered and pivoted to drive location contextualized insights and decisions around feature development.

In the competitive analysis example below, it appears many customers are searching for our products at Walgreens and CVS. This allows us to decide on how best to engage them to drive sales away from the competition via in-app offers or free delivery when customers are at these locations.

Radar Analytics Filtering:

Example competitive analysis:

Step 5: Wrapping up

Here’s what we’ve done in this recipe:

  • Setup Segment tracking to send location data with relevant events

  • Enabled Radar to enrich location data with context relevant to my business

  • Configured Segment to feed Radar location data for enrichment via a Segment Destinations function

  • Analyzed data in Radar to develop insights and decide on location features to prioritize to drive engagement

Getting started is easy

Start connecting your data with Segment.