๐ Privacy-Focused Analytics With Plausible
Hey guys! Let's dive into how we can integrate Plausible Analytics, a fantastic tool for collecting privacy-friendly usage data. This is super important because it helps us understand how people are using our app, identify any problems, and make data-driven decisions to improve things โ all without compromising anyone's privacy. We're talking about a fully opt-out setup, giving users complete control over their data. Sounds good, right?
๐ ๏ธ The Current Situation
- โ We have a data collection toggle in our privacy settings.
- โ It's set to opt-out by default (unchecked).
- โ No analytics implementation yet.
- โ We aren't tracking app usage.
- โ No visibility into how people are using the features.
- โ No error tracking.
- โ No performance metrics.
๐ The Problem We're Solving
Without proper analytics, we're flying blind! We can't:
- Figure out which features are actually being used.
- Pinpoint any problem areas or pages that cause trouble.
- Track how quickly people are adopting new features.
- Measure any performance issues that might be slowing things down.
- Make smart decisions about improving the app.
But, we absolutely need analytics that:
- Respects user privacy โ no personal information (PII).
- Complies with GDPR/CCPA regulations right out of the box.
- Doesn't rely on cookies.
- Doesn't track users across different websites.
- Is completely transparent about what's being tracked.
- Gives users control over their data.
๐ Why Plausible? The Privacy-First Champion
๐ Privacy Benefits
- No Cookies: This is huge! It makes things fully GDPR compliant.
- No Personal Data: Plausible never collects IP addresses, device information, or anything that could identify an individual.
- No Cross-Site Tracking: It only tracks activity on our domain.
- Anonymous Data: We can't identify individual users.
- GDPR, CCPA, and PECR Compliant: It follows all the important privacy rules by default.
- EU-Owned Infrastructure: Data is hosted in the EU.
- Open Source: The code is transparent and available for anyone to see.
- Lightweight: The script is tiny (less than 1KB), so it won't slow down the app.
โ๏ธ Technical Benefits
- Easy Script Tag Integration: Simple to set up.
- Events API: Allows for custom tracking of specific actions.
- Real-time Dashboard: See what's happening in real-time.
- Easy to Self-Host: Gives us the option for complete control (if we want it).
- Great Documentation: Easy to understand.
- No Complex Setup: Gets you up and running quickly.
๐ User and Developer Requirements
๐งโ๐ป Developer Perspective
- I want to see which features are the most popular.
- I want to identify pages with high bounce rates.
- I want to track custom events, such as when a session starts or a task is completed.
๐ User Perspective
- I want to be assured that my personal data isn't being collected.
- I want the ability to opt-out of analytics completely.
- I want to understand clearly what data is being tracked.
๐ป Technical Implementation: Let's Get Started!
1. Plausible Setup: The First Steps
โ๏ธ Sign up for Plausible
- Head over to https://plausible.io.
- Create an account.
- Add our site:
chastityos.app(or your domain). - Grab the script snippet โ we'll need this later.
โ๏ธ Add Environment Variables
# .env
VITE_PLAUSIBLE_DOMAIN=chastityos.app
VITE_PLAUSIBLE_ENABLED=true
2. Script Integration: Bringing It All Together
๐ Install the Plausible Script
File: index.html
<head>
<!-- Plausible Analytics (Privacy-friendly) -->
<script
defer
data-domain="%VITE_PLAUSIBLE_DOMAIN%"
src="https://plausible.io/js/script.js"
></script>
</head>
Or, you can use the React component for a cleaner approach:
npm install plausible-tracker
File: src/utils/analytics/plausible.ts
import Plausible from 'plausible-tracker';
const { enableAutoPageviews, trackEvent } = Plausible({
domain: import.meta.env.VITE_PLAUSIBLE_DOMAIN,
apiHost: 'https://plausible.io',
});
// Enable automatic page view tracking
export const initPlausible = () => {
if (!import.meta.env.VITE_PLAUSIBLE_ENABLED) return;
enableAutoPageviews();
};
export const trackPlausibleEvent = (
eventName: string,
props?: Record<string, string | number>
) => {
if (!import.meta.env.VITE_PLAUSIBLE_ENABLED) return;
trackEvent(eventName, { props });
};
3. Respecting User Preferences: Putting Users First
๐ฆ Check Settings Before Tracking
File: src/utils/analytics/analyticsManager.ts
import { settingsDBService } from '@/services/database';
import { trackPlausibleEvent } from './plausible';
export class AnalyticsManager {
private static userOptedIn: boolean = false;
static async init(userId: string): Promise<void> {
const settings = await settingsDBService.getUserSettings(userId);
this.userOptedIn = settings?.dataCollection ?? false;
if (this.userOptedIn) {
initPlausible();
}
}
static trackEvent(
eventName: string,
props?: Record<string, string | number>
): void {
if (!this.userOptedIn) return;
trackPlausibleEvent(eventName, props);
}
static setOptIn(optIn: boolean): void {
this.userOptedIn = optIn;
if (optIn) {
initPlausible();
}
}
}
4. Initialize in App: Connecting the Pieces
File: src/App.tsx
import { AnalyticsManager } from './utils/analytics/analyticsManager';
function App() {
const { user } = useAuthState();
useEffect(() => {
if (user?.uid) {
AnalyticsManager.init(user.uid);
}
}, [user?.uid]);
// ... rest of app
}
5. Tracking Custom Events: Digging Deeper
๐ Define Event Types: Setting Up the Framework
File: src/utils/analytics/events.ts
export const AnalyticsEvents = {
// Sessions
SESSION_STARTED: 'Session Started',
SESSION_ENDED: 'Session Ended',
SESSION_PAUSED: 'Session Paused',
SESSION_RESUMED: 'Session Resumed',
EMERGENCY_UNLOCK: 'Emergency Unlock',
// Tasks
TASK_CREATED: 'Task Created',
TASK_SUBMITTED: 'Task Submitted',
TASK_APPROVED: 'Task Approved',
TASK_REJECTED: 'Task Rejected',
// Events
EVENT_LOGGED: 'Event Logged',
// Goals
GOAL_CREATED: 'Goal Created',
GOAL_COMPLETED: 'Goal Completed',
// Achievements
ACHIEVEMENT_UNLOCKED: 'Achievement Unlocked',
// Relationships
RELATIONSHIP_REQUESTED: 'Relationship Requested',
RELATIONSHIP_ACCEPTED: 'Relationship Accepted',
// Settings
SETTINGS_UPDATED: 'Settings Updated',
TIMEZONE_CHANGED: 'Timezone Changed',
// Auth
SIGNED_IN: 'Signed In',
SIGNED_OUT: 'Signed Out',
ACCOUNT_LINKED: 'Account Linked',
} as const;
๐ ๏ธ Add Tracking to Services: Implementing the Events
File: src/services/database/SessionDBService.ts
import { AnalyticsManager } from '@/utils/analytics/analyticsManager';
import { AnalyticsEvents } from '@/utils/analytics/events';
async startSession(...) {
// ... existing code ...
// Track analytics (respects user opt-in)
AnalyticsManager.trackEvent(AnalyticsEvents.SESSION_STARTED, {
hardcoreMode: session.isHardcoreMode,
hasDuration: !!session.goalDuration,
});
}
Repeat this process for:
- TaskDBService
- EventDBService
- GoalDBService
- AchievementDBService
- RelationshipService
- SettingsDBService
6. Settings UI Integration: User Control at Its Finest
File: src/pages/SettingsPage.tsx (PrivacySection)
const PrivacySection: React.FC = () => {
const [dataCollection, setDataCollection] = useState(false);
const handleDataCollectionChange = async (enabled: boolean) => {
setDataCollection(enabled);
// Update settings
await updateSettings.mutateAsync({
section: 'privacy',
data: { dataCollection: enabled },
});
// Update analytics manager
AnalyticsManager.setOptIn(enabled);
if (enabled) {
showToast('Anonymous analytics enabled', 'info');
} else {
showToast('Analytics disabled', 'info');
}
};
return (
<ToggleSwitch
label="Anonymous Analytics"
description="Help improve ChastityOS by sharing anonymous usage data. No personal information is collected."
checked={dataCollection}
onChange={handleDataCollectionChange}
/>
);
};
7. Privacy Policy Update: Transparency is Key
File: docs/PRIVACY.md
Add a section about analytics to your privacy policy:
## Analytics
ChastityOS uses Plausible Analytics, a privacy-first analytics service that:
- Does not use cookies
- Does not collect personal data
- Does not track users across websites
- Is GDPR, CCPA, and PECR compliant
Analytics is **opt-out by default**. You can enable anonymous analytics in Settings > Privacy.
When enabled, we collect:
- Page views
- Feature usage (which features you use)
- Session events (sessions started/ended, not session content)
- Error occurrences (not error details)
We never collect:
- Your session data or events
- Task content
- Personal information
- IP addresses
- Device fingerprints
๐ฆ What We'll Track: The Details
โก๏ธ Page Views (Automatic):
- Dashboard
- Tracker
- Log Event
- Full Report
- Tasks
- Rewards
- Settings
- Achievements
๐ฃ๏ธ Custom Events:
Session Events:
- Session Started (hardcoreMode: boolean, hasDuration: boolean)
- Session Ended (duration: number, reason: string)
- Session Paused
- Session Resumed
- Emergency Unlock (reason: string)
Task Events:
- Task Created (assignedBy: "keyholder"|"self")
- Task Submitted
- Task Approved
- Task Rejected
Event Logging:
- Event Logged (type: string)
Goals:
- Goal Created (type: "personal"|"keyholder")
- Goal Completed
Achievements:
- Achievement Unlocked (category: string)
Relationships:
- Relationship Requested
- Relationship Accepted
Settings:
- Settings Updated (section: string)
- Timezone Changed
Auth:
- Signed In (method: "google"|"anonymous")
- Signed Out
- Account Linked
โ Error Tracking:
Track errors without exposing sensitive details:
AnalyticsManager.trackEvent('Error Occurred', {
page: window.location.pathname,
errorType: 'network' | 'validation' | 'unknown',
});
๐ Implementation Plan: Putting It All Together
Phase 1: Setup (1 hour)
- Sign up for Plausible
- Add environment variables
- Install script/package
Phase 2: Core Integration (2 hours)
- Create analytics utilities
- Create AnalyticsManager
- Initialize in App
- Test basic page views
Phase 3: Custom Events (3 hours)
- Define event types
- Add tracking to all services
- Test event tracking
Phase 4: Settings Integration (1 hour)
- Hook up opt-in toggle
- Test opt-in/opt-out flow
- Verify tracking respects preference
Phase 5: Documentation (1 hour)
- Update privacy policy
- Add analytics docs
- Create tracking guide for developers
Phase 6: Testing (1 hour)
- Test with analytics enabled
- Test with analytics disabled
- Verify no PII is sent
- Check Plausible dashboard
โ Acceptance Criteria: Making Sure We're Successful
- [ ] Plausible script only loads when the user opts in.
- [ ] Page views are tracked automatically.
- [ ] Custom events are tracked for key features.
- [ ] Analytics respects the user's opt-in preference.
- [ ] Opt-out works immediately (no more tracking).
- [ ] No personal data is ever sent to Plausible.
- [ ] Privacy policy is updated.
- [ ] The Plausible dashboard shows real-time data.
- [ ] Events include useful properties for analysis.
- [ ] Error tracking works without exposing sensitive data.
- [ ] Developer documentation explains how to add new events.
๐ก๏ธ Privacy Checklist: Ensuring Data Protection
- [ ] No IP addresses are collected.
- [ ] No user IDs are sent.
- [ ] No session content is tracked.
- [ ] No task content is tracked.
- [ ] No event details are tracked.
- [ ] No relationship details are tracked.
- [ ] Only anonymous, aggregate data is used.
- [ ] Users can opt-out at any time.
- [ ] Opt-out is immediate.
- [ ] The privacy policy is clear and transparent.
๐งช Testing: Rigorous Checks
- [ ] Test with data collection enabled.
- [ ] Test with data collection disabled.
- [ ] Verify events appear in the Plausible dashboard.
- [ ] Verify no events are sent when opted out.
- [ ] Test the toggle on/off multiple times.
- [ ] Verify no PII is in the Plausible dashboard.
- [ ] Test all custom events fire correctly.
๐ Dependencies and Resources
- Plausible account
plausible-trackerpackage- Settings backend integration (issue #470)
โฑ๏ธ Estimated Effort
6-8 hours
๐ฐ Cost
- Free tier: Up to 10,000 page views per month.
- Paid plans start at $9/month for unlimited page views.
๐ก Alternative: Self-Hosting
We could self-host Plausible if we wanted:
- Full control over all our data.
- No third-party involvement.
- Requires server maintenance.
- Docker-based deployment is recommended.
๐งฉ Related Issues:
- Depends on issue #470 (settings backend).
- Enhances product development with usage data.
- Maintains user privacy and trust.
This should give you a great start to integrating Plausible Analytics and collecting valuable user data while staying privacy-focused!
For more detailed information, you can check out the official Plausible documentation. Plausible Analytics Documentation