Web Messenger Metadata
This document describes the metadata collected and available in the FlowXO Messenger widget, including automatic visitor information and methods for developers to add custom metadata.
Overview
Metadata in the Messenger widget comes from two main sources:
- Automatic Metadata — Collected automatically from the visitor's browser and request headers
- Developer-Provided Metadata — Set by developers through various APIs and configuration options
All metadata is merged together and sent to the server when a visitor connects to a channel.
Automatic Metadata
Server-Side Visitor Info
The server automatically extracts visitor information from Cloudflare request headers. This data is available in visitorInfo:
Geographic Information (visitorInfo.geo)
| Field | Type | Description | Example |
|---|---|---|---|
continent |
string | Continent code | "NA", "EU" |
country |
string | Country code (ISO 3166-1 alpha-2) | "US", "GB" |
city |
string | City name | "San Francisco" |
timezone |
string | IANA timezone identifier | "America/New_York" |
region |
string | Region/state name | "California" |
regionCode |
string | Region/state code | "CA" |
metroCode |
string | Metro code (US only) | "807" |
coordinate.latitude |
number | Latitude* | 37.7749 |
coordinate.longitude |
number | Longitude* | -122.4194 |
postalCode |
string | Postal/ZIP code* | "94102" |
Fields marked with * are privacy-sensitive and only collected when collectIp is enabled in privacy settings.
Environment Information (visitorInfo.environment)
Network (visitorInfo.environment.network)
| Field | Type | Description | Example |
|---|---|---|---|
origin |
string | Request origin header | "https://example.com" |
host |
string | Request host header | "messenger.flowxo.com" |
ipAddress |
string | Visitor IP address* | "203.0.113.1" |
realIp |
string | Real IP (from proxy)* | "203.0.113.1" |
asn |
number | Autonomous System Number | 13335 |
organization |
string | ISP/organization name | "Cloudflare, Inc." |
Fields marked with * are privacy-sensitive and only collected when collectIp is enabled.
User Agent (visitorInfo.environment.userAgent)
| Field | Type | Description | Example |
|---|---|---|---|
browser |
string | Browser name | "Chrome", "Firefox", "Safari" |
browserVersion |
string | Browser version | "120.0" |
os |
string | Operating system | "Windows", "macOS", "iOS", "Android" |
osVersion |
string | OS version | "10/11", "14.2" |
device |
string | Device type | "mobile", "tablet", undefined (desktop) |
Other Environment Fields
| Field | Type | Description | Example |
|---|---|---|---|
language |
string | Browser language preference | "en", "es" |
cloudflare.colo |
string | Cloudflare data center | "DFW", "LHR" |
Client-Side Host URL & Query Params
The widget automatically collects information about the host page and includes it in member.metadata:
| Field | Type | Description | Example |
|---|---|---|---|
hostUrl |
string | Full URL of the host page | "https://example.com/products?id=123" |
All query parameters from the host page URL are automatically included in member metadata:
URL: https://yoursite.com/page?campaign=summer2024&source=newsletter&theme=dark
Results in member metadata containing:
{
hostUrl: "https://yoursite.com/page?campaign=summer2024&source=newsletter&theme=dark",
campaign: "summer2024",
source: "newsletter",
theme: "dark"
}
Developer-Provided Metadata
Developers can add custom metadata through several methods. These are listed in order of priority (later methods override earlier ones).
1. URL Query Parameters
Simply add query parameters to the host page URL — they're automatically included:
https://yoursite.com/page?campaign=summer2024&source=newsletter&user_segment=premium
All query params appear directly in member metadata.
2. Data Attributes (HTML)
Popup Mode (Script Tag)
<script src="https://messenger.flowxo.com/loader.js"
data-connection="your-connection-id"
data-user-id="user_12345"
data-user-email="user@example.com"
data-user-name="John Doe"
data-user-avatar="https://example.com/avatar.jpg"
data-user-metadata='{"plan":"premium","role":"admin"}'></script>
Inline/Embedded Mode (Div Element)
<div data-fxo-connection="your-connection-id"
data-fxo-user-id="user_12345"
data-fxo-user-email="user@example.com"
data-fxo-user-name="John Doe"
data-fxo-user-avatar="https://example.com/avatar.jpg"
data-fxo-user-metadata='{"plan":"premium","role":"admin"}'></div>
Available Attributes:
| Popup Attribute | Inline Attribute | Description |
|---|---|---|
data-user-id |
data-fxo-user-id |
Unique user identifier |
data-user-email |
data-fxo-user-email |
User's email address |
data-user-name |
data-fxo-user-name |
User's display name |
data-user-avatar |
data-fxo-user-avatar |
URL to user's avatar image |
data-user-metadata |
data-fxo-user-metadata |
JSON string of custom metadata |
3. Initialization Hook (onFlowXOInit)
Use the onFlowXOInit callback to set metadata dynamically before the widget connects. This is called for each widget instance and can return user identity, custom metadata, and configuration overrides:
<script>
window.onFlowXOInit = function(connectionId) {
return {
member: {
id: getCurrentUserId(),
email: getCurrentUserEmail(),
name: getCurrentUserName(),
avatar: 'https://example.com/avatar.jpg',
metadata: {
plan: 'premium',
companyId: 'company_789',
role: 'admin',
accountType: getAccountType(),
lastLogin: getLastLoginDate()
}
},
metadata: {
pageCategory: getPageCategory(),
productViewed: getProductId()
}
};
};
</script>
<script src="https://messenger.flowxo.com/loader.js"
data-connection="your-connection-id"
async></script>
The callback can return:
member: User identity information (id, email, name, avatar, metadata)metadata: Additional metadata (merged with other sources)config: Configuration overrides (optional)
See this article for more on the JavaScript API
4. FlowXO.setMetadata() API
Dynamically update metadata after the widget has loaded:
// Set/update metadata at any time
FlowXO.setMetadata({
currentPage: '/checkout',
cartValue: 299.99,
itemCount: 3
});
// For multi-widget pages, specify the connection ID
FlowXO.setMetadata({
currentPage: '/checkout'
}, 'specific-connection-id');
Key Behaviors:
- Metadata is deep-merged with existing metadata
- If the widget is open, the update is sent immediately
- If the widget is closed, metadata is included when it opens
- Metadata persists across widget open/close cycles within a session
Metadata Priority (Merge Order)
When metadata from multiple sources conflicts, later sources override earlier ones:
- Existing member.metadata — Base layer
- hostUrl — Always included
- URL Query Parameters — All query params from host page
- Data Attributes (
data-user-metadata) - onFlowXOInit Callback (return value)
- setMetadata() API — Highest priority
Privacy Considerations
IP Collection Settings
The collectIp privacy setting controls whether sensitive location data is collected:
When collectIp is true (default):
- Full geo coordinates (latitude/longitude)
- Postal code
- IP address
When collectIp is false:
- These fields are suppressed
- General location info (country, city, timezone) is still collected
Sensitive Data Handling
The loader automatically redacts sensitive fields in debug logs:
token,password,secretapiKey,api_keyaccessToken,access_tokenrefreshToken,refresh_tokenemail
Example: Complete Metadata Flow
<!-- Page URL: https://shop.example.com/products/widget?source=email&campaign=spring -->
<script>
// Initialization hook — set user identity and metadata before the widget connects
window.onFlowXOInit = function(connectionId) {
return {
member: {
id: 'user_12345',
email: 'john@example.com',
name: 'John Doe',
metadata: {
accountTier: 'gold'
}
},
metadata: {
pageType: 'product',
productId: 'widget-123'
}
};
};
</script>
<script src="https://messenger.flowxo.com/loader.js"
data-connection="your-connection-id"
async></script>
<script>
// Later, when user adds to cart
document.addEventListener('flowxo:ready', function() {
FlowXO.setMetadata({
cartValue: 49.99,
lastAction: 'add_to_cart'
});
});
</script>
Resulting member.metadata:
{
// From host URL (automatic)
hostUrl: "https://shop.example.com/products/widget?source=email&campaign=spring",
// From query params (automatic)
source: "email",
campaign: "spring",
// From onFlowXOInit callback
accountTier: "gold",
pageType: "product",
productId: "widget-123",
// From setMetadata()
cartValue: 49.99,
lastAction: "add_to_cart"
}
Separate visitorInfo (from server):
{
geo: { country: "US", city: "San Francisco", timezone: "America/Los_Angeles" },
environment: {
userAgent: { browser: "Chrome", os: "macOS" },
language: "en"
}
}
Accessing Metadata in Flows
All collected metadata is available in your Flow XO workflows. Use this data to:
- Personalize responses based on location
- Track user journeys across pages
- Segment conversations by user type
- Integrate with CRM systems
- Analyze user behavior patterns
Next Steps
- JavaScript API — Full API reference including
FlowXO.identify(),FlowXO.setMetadata(), and event handling - Installation & Embedding Options — Data attributes for passing metadata via HTML
- Customizing the Web Messenger — Privacy settings that control what metadata is collected