Add RudderStack event tracking alongside Amplitude#196
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Updates to Preview Branch (feat/rudderstack-integration) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
PR Review: Add RudderStack event tracking alongside AmplitudeOverall this is a clean, well-tested implementation. Good job on graceful degradation (safe no-ops when env vars are not set) and thorough test coverage. A few issues worth addressing before merging. Bug: try/catch does not cover async errors in main.tsxThe initialization code wraps a dynamic try {
import('@rudderstack/analytics-js').then(({ RudderAnalytics }) => {
const rudderAnalytics = new RudderAnalytics();
rudderAnalytics.load(rudderWriteKey, rudderDataPlaneUrl); // errors here are unhandled
(window as any).rudderanalytics = rudderAnalytics;
});
} catch (error) {
console.warn('Failed to initialize RudderStack:', error); // never reached for async errors
}
import('@rudderstack/analytics-js')
.then(({ RudderAnalytics }) => {
const rudderAnalytics = new RudderAnalytics();
rudderAnalytics.load(rudderWriteKey, rudderDataPlaneUrl);
(window as any).rudderanalytics = rudderAnalytics;
})
.catch((error) => {
console.warn('Failed to initialize RudderStack:', error);
});Race condition: early events are silently droppedThe SDK loads asynchronously. Any event fired between page load and SDK initialization (e.g., an OAuth redirect completing immediately) will hit Architectural concern: check for duplicate events in AmplitudeThe typical RudderStack CDP pattern routes events through RudderStack to downstream destinations (including Amplitude), not in parallel. With the dual-call approach here: If RudderStack is configured to forward to Amplitude, every event will appear twice in Amplitude. Worth verifying the RudderStack destination config before going live, as this would inflate all metrics. The dual-call pattern also means every future event must be added in two places. A long-term simplification would be to route everything through RudderStack and remove direct Amplitude SDK calls. Type coupling: importing prop types from amplitude.ts// src/lib/rudderstack.ts
import type {
PracticeTestStartedProps,
PracticeTestCompletedProps,
// ...
} from './amplitude';This creates a dependency from Minor: inconsistent indentation in App.tsxThe What is done well
The 🤖 Generated with Claude Code |
Summary
@rudderstack/analytics-jsv3) as a secondary event tracking layer alongside the existing direct Amplitude integrationRudderStackProviderfor user identity sync and dynamic SDK initialization for minimal bundle impactDetails
src/lib/rudderstack.ts(event tracking),src/hooks/useRudderStack.tsx(identity provider), plus tests for bothVITE_RUDDERSTACK_WRITE_KEY,VITE_RUDDERSTACK_DATA_PLANE_URL) — gracefully disabled when not setTest plan
npx vitest run)npm run build)🤖 Generated with Claude Code