Customer.io
Customer.io is used for product analytics, user identification, and (optionally) in-app messaging via Gist.
Package: @customerio/cdp-analytics-browser (see client/package.json).
Where it’s implemented
| Piece | Path |
|---|---|
| SDK init | client/src/customerio-init.js (imported from client/src/index.js) |
| App helpers | client/src/utils/customerio.js |
| Auth lifecycle | SignIn.js, SignUp.js, SettingsModal.js, AuthContext.js |
| One-off tab events | AppTabs.js, Profile.js (trackTabClickOnce) |
| Venue check-in | RestaurantModal.js |
| Dev overlay | client/src/utils/CustomerIODebug.js (rendered from Home.js) |
CustomerIOMonitor exists but is commented out in App.js.
Environment variables
Set in client/.env (or your build env):
| Variable | Purpose |
|---|---|
REACT_APP_CUSTOMERIO_API_KEY | CDP write key passed to AnalyticsBrowser.load({ writeKey }) |
REACT_APP_CUSTOMERIO_SITE_ID | Used only when Gist in-app messaging is set up (see below) |
The Site ID is safe in client code. Do not put server-side Customer.io API secrets in the frontend.
Initialization
On app load, customerio-init.js:
- Loads
AnalyticsBrowserand assignswindow.cioanalytics - Attempts Gist setup — currently disabled:
loadGist()returnsfalseand thecustomerio-gist-webimport is commented out
Until Gist is re-enabled, in-app message helpers (forceCheckCustomerIOMessages, dismissCustomerIOMessage, etc.) will log that Gist is unavailable.
Automatic tracking
These run without extra setup when users use the app:
| Action | Where | Event / behavior |
|---|---|---|
| Sign up | SignUp.js | identifyUser + user_signup |
| Log in | SignIn.js | identifyUser + user_login |
| Log out | SettingsModal.js | user_logout + resetUser |
| Delete account | SettingsModal.js | account_deleted + resetUser |
| Session restore | AuthContext.js | restoreUserIdentification, logCustomerIOStatus |
| Venue check-in | RestaurantModal.js | Venue_Check_In |
| First-time tab clicks | AppTabs.js, Profile.js | Profile_click, Prize_clicked (once per user via localStorage) |
Identified users are persisted in localStorage under customerio_user so Gist can restore the token after reload (when Gist is enabled).
Manual usage
import {
trackEvent,
identifyUser,
resetUser,
trackTabClickOnce,
triggerBroadcast,
} from '../utils/customerio';
trackEvent('bet_placed', { amount: 50, fightId: 'fight_123' });
identifyUser('user_123', { email: 'user@example.com', name: 'Jane' });
resetUser();
// Fire once per user (uses a localStorage flag)
trackTabClickOnce('My_Event', userId, username, 'screen_name', 'seen_my_event');
Direct SDK access (after init):
window.cioanalytics.track('custom_event', { data: 'value' });
window.cioanalytics.identify('user_id', { email: 'user@example.com' });
window.cioanalytics.reset();
Server-triggered broadcasts
triggerBroadcast(broadcastId, eventData) POSTs to /api/user/trigger-customerio-broadcast with the user’s Cognito idToken. Use this when a journey/broadcast should be fired from the app (requires backend support).
In-app messages (Gist)
Gist integration is scaffolded in customerio-init.js (dismiss button overlay, message callbacks) but not active in the current tree. To turn it on:
- Uncomment the
customerio-gist-webimport inloadGist() - Set
REACT_APP_CUSTOMERIO_SITE_ID - Verify overlays in a production/staging build (Customer.io often needs a public URL)
Helpers in customerio.js: forceCheckCustomerIOMessages, dismissCustomerIOMessage, checkCustomerIOStatus, getCustomerIOMessageStatus.
For trivia prizes via Customer.io webhooks, see the contributing note: Customer.io Trivia.
Testing
Local (localhost)
- Analytics may initialize; Customer.io’s dashboard “connection” checks often expect a public URL, so localhost can look disconnected even when events fire.
- Watch the browser console for init errors and
identify/trackwarnings. CustomerIODebugon the home screen (when mounted) exposes stored user JSON and can dismiss Gist messages when Gist is available.
Staging / production
- Deploy or use a public preview URL
- Sign up or log in with a test user
- Confirm the user and events in the Customer.io workspace
- Network tab: requests to Customer.io track endpoints (e.g.
track.customer.io)
Unit tests: client/src/utils/__tests__/customerio.test.js.
Troubleshooting
| Symptom | Things to check |
|---|---|
Customer.io analytics not available | Init failed or window.cioanalytics missing; check console from customerio-init.js |
| Events missing in dashboard | User not identify’d before custom events; wrong workspace / write key |
| Gist / in-app never shows | loadGist() still returns false; enable import + SITE_ID |
| Broadcast trigger fails | Logged-in user, valid idToken, backend route /api/user/trigger-customerio-broadcast |
Related docs
- Push notifications — device tokens via Capacitor (separate from Customer.io campaigns)
- Source reference in repo:
client/CUSTOMER_IO_CONFIG.md(legacy; prefer this page)