Appearance
Custom Fields
Send additional user data and map it to your CRM fields.
Overview
Custom fields allow you to:
- Capture additional user information beyond email and name
- Track extension-specific data (version, install source, etc.)
- Map data to specific CRM fields
- Segment users based on custom attributes
Sending Custom Data
Use the metadata field to send custom data:
javascript
const result = await ExtensionLogin.identify({
email: 'user@example.com',
name: 'John Doe',
metadata: {
company: 'Acme Inc',
role: 'Developer',
plan: 'pro',
source: 'product_hunt'
}
});Common Custom Fields
Extension Information
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
extensionVersion: chrome.runtime.getManifest().version,
extensionId: chrome.runtime.id,
installedAt: new Date().toISOString()
}
});User Preferences
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
theme: 'dark',
language: navigator.language,
notifications: true
}
});Marketing Attribution
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
source: 'google_ads',
campaign: 'spring_2024',
referrer: document.referrer,
landingPage: window.location.href
}
});Subscription/Plan Data
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
plan: 'premium',
planStartDate: '2024-01-15',
trialEndsAt: '2024-01-29',
features: ['feature_a', 'feature_b']
}
});Supported Data Types
| Type | Example | Notes |
|---|---|---|
| String | "value" | Any text |
| Number | 42, 3.14 | Integers or floats |
| Boolean | true, false | |
| Array | ["a", "b"] | Arrays of primitives |
| Object | { key: "value" } | Nested objects (1 level) |
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
// String
company: 'Acme Inc',
// Number
employeeCount: 50,
revenue: 1000000.50,
// Boolean
isEnterprise: true,
// Array
interests: ['productivity', 'automation'],
// Nested object (1 level)
address: {
city: 'San Francisco',
state: 'CA'
}
}
});CRM Field Mapping
Dashboard Configuration
Map custom fields to CRM fields in the dashboard:
- Go to CRM Connections
- Select your connection
- Click "Field Mapping"
- Map your metadata fields to CRM fields
Mapping Examples
ClickFunnels
| Metadata Field | ClickFunnels Field |
|---|---|
metadata.company | custom_fields.company |
metadata.plan | tags (as tag) |
metadata.source | custom_fields.lead_source |
GoHighLevel
| Metadata Field | GoHighLevel Field |
|---|---|
metadata.company | companyName |
metadata.source | source |
metadata.plan | tags (as tag) |
Auto-Mapping
Some fields are automatically mapped:
| Metadata Field | Auto-Mapped To |
|---|---|
company | CRM company field |
phone | CRM phone field |
address | CRM address fields |
tags | CRM tags |
Dynamic Tags
Pass tags through metadata:
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
tags: ['new-user', 'chrome-extension', 'trial']
}
});Tags are automatically:
- Added to ClickFunnels contact tags
- Added to GoHighLevel contact tags
- Included in webhook payload
Conditional Tags
Add tags based on conditions:
javascript
const tags = ['chrome-user'];
if (isNewUser) {
tags.push('new-signup');
}
if (isPremium) {
tags.push('premium');
}
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: { tags }
});Updating Custom Fields
Custom fields are merged on subsequent identify calls:
javascript
// First identify
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: { plan: 'free', signupSource: 'organic' }
});
// Later update
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: { plan: 'pro' }
});
// Result: { plan: 'pro', signupSource: 'organic' }Retrieving Custom Fields
Access stored metadata from the user object:
javascript
const user = ExtensionLogin.getUser();
console.log(user.metadata);
// { plan: 'pro', signupSource: 'organic' }
console.log(user.metadata.plan);
// 'pro'Validation
Metadata is validated before sending:
javascript
// Valid
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: { plan: 'pro' }
}); // ✓
// Invalid - function not allowed
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: { callback: () => {} }
}); // ✗ Error: Invalid metadata type
// Invalid - too deeply nested
await ExtensionLogin.identify({
email: 'user@example.com',
metadata: {
level1: {
level2: {
level3: 'value' // Too deep
}
}
}
}); // ✗ Error: Metadata too deeply nestedSize Limits
| Limit | Value |
|---|---|
| Total metadata size | 10KB |
| Individual field value | 1KB |
| Field name length | 100 characters |
| Array items | 100 items |
Best Practices
Use Consistent Field Names
javascript
// Good - consistent naming
metadata: {
signupSource: 'google',
accountType: 'premium',
createdAt: '2024-01-15'
}
// Bad - inconsistent naming
metadata: {
signup_source: 'google', // snake_case
accountType: 'premium', // camelCase
CreatedAt: '2024-01-15' // PascalCase
}Don't Store Sensitive Data
javascript
// Bad - sensitive data
metadata: {
password: 'secret123',
ssn: '123-45-6789',
creditCard: '4111...'
}
// Good - non-sensitive data
metadata: {
accountTier: 'premium',
signupDate: '2024-01-15'
}Use Meaningful Names
javascript
// Bad - unclear names
metadata: {
f1: 'value',
x: true,
data: 'stuff'
}
// Good - descriptive names
metadata: {
featureFlags: 'value',
hasCompletedOnboarding: true,
referralSource: 'twitter'
}Examples
Full User Profile
javascript
await ExtensionLogin.identify({
email: 'user@example.com',
name: 'John Doe',
firstName: 'John',
lastName: 'Doe',
phone: '+1-555-123-4567',
metadata: {
// Company info
company: 'Acme Inc',
jobTitle: 'Senior Developer',
companySize: '50-100',
// Subscription
plan: 'pro',
billingCycle: 'monthly',
trialEndsAt: '2024-02-01',
// Attribution
source: 'google_ads',
campaign: 'developer_tools_q1',
medium: 'cpc',
// Extension data
extensionVersion: '1.2.3',
installedAt: '2024-01-15T10:30:00Z',
// Tags
tags: ['developer', 'pro-trial', 'google-ads']
}
});Next Steps
- CRM Integration - Map fields to CRM
- Webhooks - Receive custom data via webhook
- SDK Methods - Full API reference