Form Analytics

Track User Behavior & Performance

Track user behavior, measure form performance, and gain insights into how users interact with your forms using Formedible's comprehensive analytics system.

User Tracking
Performance Metrics
Event System

Overview

Comprehensive analytics that track user interactions and form performance.

Formedible provides built-in analytics that track various user interactions and form events. All analytics are optional and can be customized to fit your specific tracking needs.

Field Interactions

Track focus, blur, and change events for individual fields with timing data.

Form Completion

Monitor form start, completion, and abandonment with completion percentages.

Page Navigation

Track page changes in multi-step forms with time spent and completion context.

Performance Metrics

Monitor form rendering and submission performance with detailed timing data.

Enhanced Context

All events include rich metadata like validation errors and completion states.

Basic Setup

Enable analytics by adding an analytics configuration with event handlers.

Enable analytics by adding an analytics configuration with event handlers:

Basic Example

const { Form } = useFormedible({
fields: [
{ name: 'email', type: 'email', label: 'Email' },
{ name: 'name', type: 'text', label: 'Name' },
],
analytics: {
onFormStart: (timestamp) => {
console.log('Form started at:', new Date(timestamp));
},
onFieldFocus: (fieldName, timestamp) => {
console.log(`Field ${fieldName} focused at:`, new Date(timestamp));
},
onFieldBlur: (fieldName, timeSpent) => {
console.log(`User spent ${timeSpent}ms on ${fieldName}`);
},
onFormComplete: (timeSpent, formData) => {
console.log(`Form completed in ${timeSpent}ms`, formData);
}
}
});

Available Events

Complete reference of all analytics events available in Formedible.

Complete Analytics Configuration

analytics: {
// Form lifecycle events
onFormStart: (timestamp: number) => {
// Called when form is first rendered
analytics.track('form_started', { timestamp });
},
onFormComplete: (timeSpent: number, formData: any) => {
// Called when form is successfully submitted
analytics.track('form_completed', {
duration: timeSpent,
data: formData
});
},
onFormAbandon: (completionPercentage: number, context?: any) => {
// FIXED: Only fires on actual page leave, not form navigation
// Called when user leaves without completing
analytics.track('form_abandoned', {
completion: completionPercentage,
currentPage: context?.currentPage,
currentTab: context?.currentTab,
lastActiveField: context?.lastActiveField
});
},
// Field interaction events
onFieldFocus: (fieldName: string, timestamp: number) => {
// Called when a field receives focus
analytics.track('field_focused', {
field: fieldName,
timestamp
});
},
onFieldBlur: (fieldName: string, timeSpent: number) => {
// Called when a field loses focus
analytics.track('field_blurred', {
field: fieldName,
duration: timeSpent
});
},
onFieldChange: (fieldName: string, value: any, timestamp: number) => {
// Called when field value changes
analytics.track('field_changed', {
field: fieldName,
value,
timestamp
});
},
onFieldError: (fieldName: string, errors: string[], timestamp: number) => {
// Called when field validation errors occur
analytics.track('field_error', {
field: fieldName,
errorCount: errors.length,
firstError: errors[0],
timestamp
});
},
onFieldComplete: (fieldName: string, isValid: boolean, timeSpent: number) => {
// Called when field is successfully completed
analytics.track('field_complete', {
field: fieldName,
isValid,
timeSpent
});
},
// Multi-page form events
onPageChange: (fromPage: number, toPage: number, timeSpent: number, pageContext?: any) => {
// Called when navigating between pages with rich context
analytics.track('page_changed', {
from: fromPage,
to: toPage,
duration: timeSpent,
hasErrors: pageContext?.hasErrors,
completionPercentage: pageContext?.completionPercentage
});
},
// Tab-based form events
onTabChange: (fromTab: string, toTab: string, timeSpent: number, tabContext?: any) => {
// Called when navigating between tabs
analytics.track('tab_changed', {
fromTab,
toTab,
duration: timeSpent,
completionPercentage: tabContext?.completionPercentage,
hasErrors: tabContext?.hasErrors
});
},
onTabFirstVisit: (tabId: string, timestamp: number) => {
// Called when a tab is visited for the first time
analytics.track('tab_first_visit', {
tabId,
timestamp
});
},
// Performance tracking
onSubmissionPerformance: (totalTime: number, validationTime: number, processingTime: number) => {
// Called after form submission to track performance
analytics.track('form_performance', {
totalTime,
validationTime,
processingTime,
efficiency: (processingTime / totalTime) * 100
});
}
}

Integration Examples

Real-world examples of integrating with popular analytics services.

Google Analytics 4

analytics: {
onFormStart: (timestamp) => {
gtag('event', 'form_start', {
form_name: 'contact_form',
timestamp: timestamp
});
},
onFormComplete: (timeSpent, formData) => {
gtag('event', 'form_submit', {
form_name: 'contact_form',
engagement_time_msec: timeSpent,
value: 1
});
},
onFormAbandon: (completionPercentage) => {
gtag('event', 'form_abandon', {
form_name: 'contact_form',
completion_percentage: completionPercentage
});
}
}

Custom Analytics Service

// Custom analytics service
class FormAnalytics {
static track(event: string, data: any) {
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event, data, timestamp: Date.now() })
});
}
}
// Usage in form
analytics: {
onFieldFocus: (fieldName, timestamp) => {
FormAnalytics.track('field_focus', {
field: fieldName,
timestamp
});
},
onFieldBlur: (fieldName, timeSpent) => {
FormAnalytics.track('field_blur', {
field: fieldName,
time_spent: timeSpent
});
}
}

Mixpanel Integration

import mixpanel from 'mixpanel-browser';
analytics: {
onFormStart: (timestamp) => {
mixpanel.track('Form Started', {
form_id: 'registration_form',
timestamp: timestamp
});
},
onFieldChange: (fieldName, value, timestamp) => {
mixpanel.track('Field Changed', {
field_name: fieldName,
field_value: typeof value === 'string' ? value.length : value,
timestamp: timestamp
});
},
onPageChange: (fromPage, toPage, timeSpent) => {
mixpanel.track('Page Changed', {
from_page: fromPage,
to_page: toPage,
time_on_page: timeSpent
});
}
}

Performance Metrics

Use analytics data to calculate important form performance metrics.

// Example metrics calculation
class FormMetrics {
private startTime: number = 0;
private fieldTimes: Record<string, number> = {};
analytics = {
onFormStart: (timestamp: number) => {
this.startTime = timestamp;
},
onFieldBlur: (fieldName: string, timeSpent: number) => {
this.fieldTimes[fieldName] = timeSpent;
// Calculate average time per field
const avgTime = Object.values(this.fieldTimes)
.reduce((sum, time) => sum + time, 0) / Object.keys(this.fieldTimes).length;
console.log(`Average time per field: ${avgTime}ms`);
},
onFormComplete: (timeSpent: number, formData: any) => {
const completionRate = this.calculateCompletionRate();
const fieldsCompleted = Object.keys(formData).length;
console.log('Form Metrics:', {
totalTime: timeSpent,
completionRate,
fieldsCompleted,
avgTimePerField: timeSpent / fieldsCompleted
});
}
};
private calculateCompletionRate(): number {
// Implementation depends on your tracking system
return 0.85; // 85% completion rate
}
}

Recent Improvements

Latest enhancements to the analytics system for better insights.

Fixed Abandonment Tracking

The onFormAbandon event now only fires when users actually leave the page, not when navigating between form pages or tabs. This provides accurate abandonment metrics.

Enhanced Context Data

All analytics events now include rich contextual information like validation errors, completion percentages, and performance metrics for better insights.

Performance Tracking

New performance metrics track form rendering, validation, and submission times to help optimize user experience.

Privacy Considerations

Important privacy guidelines when implementing form analytics.

Data Sensitivity

Be careful not to track sensitive field values. Consider tracking field interactions without actual values.

User Consent

Ensure you have proper user consent before tracking form interactions, especially in GDPR regions.

Data Anonymization

Consider anonymizing or hashing user data before sending to analytics services.

Best Practices

Guidelines for effective form analytics implementation.

Selective Tracking

Only implement the analytics events you actually need to avoid data overload.

Error Handling

Wrap analytics calls in try-catch blocks to prevent tracking errors from breaking your form.

Performance

Use debouncing for high-frequency events like field changes to avoid overwhelming your analytics service.