Best Practices
Learn how to get the most out of Tode analytics in your Figma plugins and widgets. Following these best practices will help you collect meaningful data, avoid common pitfalls, and build a robust analytics implementation.
Why Best Practices Matter
Good analytics implementation is the difference between actionable insights and noise. When you track the right events with clear naming conventions, you can:
- Understand how users actually interact with your plugin
- Identify which features drive engagement
- Make data-driven decisions about your product roadmap
- Debug issues by correlating user actions with errors
Initialization
Initialize Early
Call tode.init() immediately after figma.showUI() in your plugin controller. This ensures the SDK is ready before any user interactions occur.
import { tode } from '@tode-sdk/core';
// Show UI first
figma.showUI(__html__, { width: 400, height: 600 });
// Then initialize Tode
await tode.init({ apiKey: 'your-api-key' });
// Now safe to track
tode.trackAction('plugin_opened');Why this matters: Initializing too late means you might miss early user interactions. Initializing too early (before showUI()) can cause configuration issues.
Enable Debug Mode During Development
Use debug mode to see what's being tracked and catch issues early.
await tode.init({
apiKey: 'your-api-key',
debug: process.env.NODE_ENV === 'development'
});Why this matters: Debug mode logs all tracking calls to the console, making it easy to verify your implementation without checking the dashboard.
Tracking Events
Always Check Ready State
Before calling any tracking method from your UI, verify that Tode is initialized and ready.
// Good - checks ready state
if (isReady) {
tode.trackAction('export_clicked');
}
// Bad - might fail silently
tode.trackAction('export_clicked');Why this matters: The SDK needs time to establish a connection with the Figma plugin controller. Tracking before ready will silently fail, leading to missing data.
Track Meaningful Actions
Focus on tracking user interactions that provide actionable insights. Not every button click needs to be tracked.
// Good - tracks key user journeys
tode.trackAction('plugin_opened');
tode.trackAction('export_completed');
tode.trackAction('settings_changed');
tode.trackAction('premium_feature_used');
// Bad - too granular, creates noise
tode.trackAction('mouse_moved');
tode.trackAction('input_focused');
tode.trackAction('scroll_happened');What to track:
- Plugin open/close events
- Core feature usage (export, import, transform, etc.)
- Settings changes
- Error occurrences
- Conversion points (trial to paid, feature discovery)
What to avoid:
- Low-level UI interactions (hover, focus, scroll)
- Events that fire too frequently
- Redundant events that can be derived from others
Naming Conventions
Use Descriptive, Snake Case Names
Clear, consistent naming makes your analytics data much easier to analyze.
// Good - descriptive snake_case
tode.trackAction('export_to_png');
tode.trackAction('layer_renamed');
tode.trackAction('color_picker_opened');
tode.trackAction('batch_resize_completed');
// Bad - vague or inconsistent
tode.trackAction('click');
tode.trackAction('action1');
tode.trackAction('exportToPNG'); // camelCase
tode.trackAction('Export To PNG'); // spacesUse a Consistent Naming Pattern
Adopt a pattern like object_action or feature_action and stick to it throughout your plugin.
// Pattern: object_action
tode.trackAction('layer_selected');
tode.trackAction('layer_renamed');
tode.trackAction('layer_deleted');
// Pattern: feature_action
tode.trackAction('export_started');
tode.trackAction('export_completed');
tode.trackAction('export_failed');Why this matters: Consistent naming makes it easy to filter and group events in your analytics dashboard. You can quickly see all layer-related or export-related events.
Using Metrics
Track Numeric Values When Relevant
Use trackActionWithMetric() when a numeric value adds context to the action.
// Good - metric adds valuable context
tode.trackActionWithMetric('items_exported', 42);
tode.trackActionWithMetric('processing_time_ms', 1523);
tode.trackActionWithMetric('layers_selected', 5);
// Less useful - boolean as metric
tode.trackActionWithMetric('feature_enabled', 1); // Use trackAction insteadGood use cases for metrics:
- Count of items processed
- Processing duration
- File sizes
- Number of selected elements
- Numeric settings values
Performance
Don't Block User Interactions
Tracking calls are asynchronous and designed to not block the UI. Don't await them unless necessary.
// Good - fire and forget
const handleExport = () => {
tode.trackAction('export_started');
performExport(); // Don't wait for tracking
};
// Usually unnecessary - awaiting tracking
const handleExport = async () => {
await tode.trackAction('export_started'); // Blocks export
performExport();
};Clean Up Resources
When using framework adapters, clean up when components unmount to prevent memory leaks.
// React
useEffect(() => {
return () => {
// Cleanup handled by hook
};
}, []);
// Svelte
onDestroy(() => todeStore.destroy());
// Vanilla
window.addEventListener('beforeunload', () => client.destroy());Testing Your Implementation
Verify Events in Debug Mode
Before shipping, enable debug mode and walk through your plugin's user flows to verify all events fire correctly.
await tode.init({
apiKey: 'your-api-key',
debug: true
});Check the Dashboard
After testing, verify that events appear in your Tode dashboard with the expected names and values.
Common Mistakes to Avoid
| Mistake | Problem | Solution |
|---|---|---|
| Tracking before ready | Events are dropped | Check isReady before tracking |
| Vague event names | Hard to analyze data | Use descriptive names |
| Tracking too much | Noise drowns signal | Focus on key interactions |
| Inconsistent naming | Fragmented analytics | Adopt a naming convention |
| Not cleaning up | Memory leaks | Call destroy() on unmount |
Next Steps
- Review the API Reference for method details
- Check your framework guide: React, Vue, Angular, Svelte, Vanilla
- Return to the Introduction for setup instructions