Creator Plugin Event Tracking
Event tracking in Creator Plugins uses @lottiefiles/event-store (Jitsu + Amplitude). Events fire from UI code only — the plugin sandbox cannot make network requests.
Architecture
UI (src/) Plugin Sandbox (plugin/)
───────────────── ────────────────────────
initializeEventTracker() (optional) handles 'get-user-id' →
configures Jitsu + Amplitude responds with creator.user?.id
(optional) requests user ID
fireEvent({ eventType, params })
→ sends to Jitsu host
→ sends to Amplitude
File Structure
A plugin with event tracking has these files:
my-plugin/
├── src/
│ ├── data/
│ │ └── eventStore.ts # Event type constants + parameter interfaces
│ ├── utils/
│ │ └── eventStoreUtils.ts # initializeEventTracker() + fireEvent()
│ └── main.tsx # Calls initializeEventTracker() on startup
├── .env.development # Dev API keys + host
└── .env.production # Prod API keys + host
Setup Steps
1. Install dependencies
pnpm add @lottiefiles/event-store @lottiefiles/plugin-tracker
2. Copy environment files
Copy .env.development and .env.production from an existing plugin. All internal plugins share the same keys:
VITE_EVENTSTORE_API_KEY=...
VITE_EVENTSTORE_HOST=https://events.lottiefiles.dev # .com for production
VITE_PLUGIN_TRACKER_API_KEY=...
3. Ensure Vite defines APP_NAME and APP_VERSION
In vite.config.ts, the define block must include:
import packageJSON from './package.json';
export default defineConfig({
define: {
APP_NAME: JSON.stringify(packageJSON.name),
APP_VERSION: JSON.stringify(packageJSON.version),
},
// ...plugins
});
4. Create eventStoreUtils.ts
Copy the template from references/eventStoreUtils-template.md to src/utils/eventStoreUtils.ts.
This file provides:
initializeEventTracker()— configures Jitsu with strict cookie policy (required for sandboxed iframe) and Amplitude, then sets the user IDfireEvent()— sends events to both Jitsu and Amplitude backends
5. (Optional) Set up user ID tracking
Skip this step if the user doesn't need to associate events with a user ID. If they do:
First, ensure plugin/manifest.json includes the "user" permission — without it, creator.user will be undefined:
{
"permissions": ["user"]
}
The eventStoreUtils.ts template imports a pluginMessage helper from '.' — most plugins already have this in src/utils/index.ts. Add get-user-id to the Message type if it's not already there:
type Message =
| { type: 'get-user-id'; output: string | undefined }
// ...other message types
If the plugin doesn't have a pluginMessage utility yet, copy the pattern from an existing plugin's src/utils/index.ts.
6. Define event types
Create src/data/eventStore.ts with your event constants and parameter interfaces. See references/event-definitions-example.md for examples.
Conventions:
- Every event should have a typed parameter interface
- Match the naming convention used by your plugin's existing events
7. (Optional) Handle get-user-id in plugin sandbox
Skip this step if not tracking user IDs (see step 5). Otherwise, the plugin sandbox must respond to the get-user-id message:
// plugin/plugin.ts
creator.ui.onMessage((msg: any) => {
if (msg.type === 'get-user-id') {
creator.ui.postMessage({
type: 'get-user-id',
data: creator.user?.id,
});
return;
}
// ...other message handlers
});
8. Initialize on startup
In src/main.tsx, call initializeEventTracker() before rendering:
import { initializeEventTracker } from './utils/eventStoreUtils';
const main = async () => {
await initializeEventTracker();
// ...render app
};
main();
9. Fire events
import { fireEvent } from './utils/eventStoreUtils';
import { EventType } from '../data/eventStore';
fireEvent({
eventType: EventType.LogoImported,
parameters: {
logo_id: 42,
logo_title: 'GitHub',
logo_category: 'Development',
},
});
Common Pitfalls
- Cookie errors in sandboxed iframe — The event store catch block handles
Failed to read the 'cookie' property from 'Document'. Events still fire despite this error. Do not remove the try/catch. - Missing .env files — Without
VITE_EVENTSTORE_API_KEYandVITE_EVENTSTORE_HOST, initialization silently fails. Copy from an existing plugin. - Calling fireEvent before init —
initializeEventTracker()must complete before anyfireEvent()calls. Initialize inmain.tsxbefore rendering. - Tracking from plugin sandbox — Event tracking only works in UI code (
src/). The plugin sandbox cannot make network requests.
Reference Files
| Reference | Contents |
|---|---|
references/eventStoreUtils-template.md |
Complete eventStoreUtils.ts implementation to copy into new plugins |
references/event-definitions-example.md |
Example eventStore.ts with event types and typed parameter interfaces |