Use stable PostHog identity for newsletter signups#6588
Conversation
Greptile SummaryThis PR stops using email addresses as PostHog distinct IDs for demo/intro/newsletter form tracking, instead routing PII into
Confidence Score: 5/5The change is narrowly scoped to PostHog analytics; no core signup logic, auth, or data-storage paths are altered. The refactoring correctly strips PII from event payloads, the new JS helper handles all edge-case deletions and the identify guard, and the public API change is backward-compatible. No regressions are expected in the signup or form-submission flows. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "Merge origin/main into fix-posthog-newsl..." | Re-trigger Greptile |
| yield track_newsletter_posthog_subscription(email) | ||
| yield IndexState.send_contact_to_webhook(email) | ||
| yield IndexState.add_contact_to_loops(email) |
There was a problem hiding this comment.
PostHog fires a
newsletter_subscribed event even when email is None. If the user submits the form without an email address, email_to_validate is falsy and the if block is skipped entirely — so email stays None and tracking fires with an empty props object. The resulting event has no identity and no person properties, creating noise in PostHog analytics.
| yield track_newsletter_posthog_subscription(email) | |
| yield IndexState.send_contact_to_webhook(email) | |
| yield IndexState.add_contact_to_loops(email) | |
| if email: | |
| yield track_newsletter_posthog_subscription(email) | |
| yield IndexState.send_contact_to_webhook(email) | |
| yield IndexState.add_contact_to_loops(email) |
| if (Object.keys(personProps).length > 0) {{ | ||
| eventProps.$set = personProps; | ||
| }} | ||
| if (canonicalDistinctId && canonicalDistinctId !== props.email) {{ | ||
| posthog.identify(String(canonicalDistinctId), personProps); | ||
| }} |
There was a problem hiding this comment.
Double person-property write when canonical ID is present
When canonicalDistinctId is truthy, posthog.identify(canonicalDistinctId, personProps) is called and then posthog.capture(event_name, {..., $set: personProps}) is called immediately after with the same personProps in $set. PostHog merges both writes, so this is harmless in practice, but the $set payload on the capture event is redundant when identify already carries the same data. Removing the $set attachment when canonicalDistinctId is present would eliminate the duplicate write, though this is a minor analytics hygiene concern.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
@copilot resolve the merge conflicts in this pull request |
Resolved the merge conflicts in 84e6a63. The two conflicting areas were:
|
Summary
$setperson propertiesposthog.identifywhen a canonical non-email ID is providedtrack_newsletter_posthog_subscription(email, contact_uuid)as the new preferred API for newsletter trackingtrack_newsletter_posthog_submission(form_data)for backwards compatibility (now uses the improved_capture_posthog_person_eventunder the hood)cc @Alek99
Testing
uv run ruff format packages/reflex-components-internal/src/reflex_components_internal/blocks/telemetry/posthog.py packages/reflex-components-internal/src/reflex_components_internal/blocks/telemetry/__init__.py packages/reflex-site-shared/src/reflex_site_shared/backend/signup.pyuv run ruff check packages/reflex-components-internal/src/reflex_components_internal/blocks/telemetry/posthog.py packages/reflex-components-internal/src/reflex_components_internal/blocks/telemetry/__init__.py packages/reflex-site-shared/src/reflex_site_shared/backend/signup.pyuv run --package reflex-site-shared python - <<'PY' ...script assertions for newsletter PostHog payload