feat: auto-attach $screen_name to all events#530
Open
turnipdabeets wants to merge 10 commits into
Open
Conversation
Cache the last screen title on PostHog.screen() and inject it as $screen_name into every event built through buildProperties (excluding $snapshot). Cleared by reset() and close(). Caller-supplied $screen_name in properties still wins. Closes #119. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds two tests: confirms $exception events carry the cached screen name (locks in the cross-event scope decision), and confirms $snapshot events do not (verifies the appendSharedProps gate).
…name-on-all-events
…name-on-all-events
5 tasks
Spell out the primary behavior (auto-captures $screen events via ActivityLifecycleCallbacks) alongside the new $screen_name stamping, so the "also" reads correctly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Put recording the screen view first; the cross-event caching is a secondary effect. Adds explicit @param entries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port the iOS-side defensive check: passing $screen_name as an empty or whitespace-only string on a capture() call now falls back to the cached value rather than shipping the empty/whitespace literal. A meaningful caller-supplied value still wins. Also expand the changeset to mirror the iOS clarity — explicit opt-out instructions, enumerated cross-event stamping list, and a 'what did not change' section so customers don't conflate the iOS-side SwiftUI/ crash-replay work with the Android release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match iOS: PostHog.screen("") and whitespace-only titles no longer
emit a $screen event and leave the cache untouched, so the last
useful name survives. The activity-lifecycle integration already
gated on !isNullOrEmpty(), so this only affects manual calls and
the (unlikely) case where an Activity label is whitespace-only.
Also tighten the changeset: drop the 'What did NOT change' section
and add the screen("") drop note in line with the rest.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
marandaneto
reviewed
May 23, 2026
| } | ||
|
|
||
| // Cache for capture-time context snapshot on log records. | ||
| if (screenTitle.isBlank()) { |
Member
There was a problem hiding this comment.
better to trim before checking, and assign the lastScreenName already trimmed
marandaneto
reviewed
May 23, 2026
| // override still takes precedence. | ||
| if (appendSharedProps) { | ||
| val cachedName = lastScreenName | ||
| val callerName = (props["\$screen_name"] as? String)?.trim() |
Member
There was a problem hiding this comment.
marandaneto
reviewed
May 23, 2026
| val cachedName = lastScreenName | ||
| val callerName = (props["\$screen_name"] as? String)?.trim() | ||
| if (!cachedName.isNullOrEmpty() && callerName.isNullOrEmpty()) { | ||
| props["\$screen_name"] = cachedName |
Member
There was a problem hiding this comment.
flutter also captures $screen_name, and uses the android sdk, so its better to check if we are not overwriting the flutter value here
… stamp Trim screenTitle in screen() before the blank check and store the trimmed value so both lastScreenName and the $screen event payload carry the cleaned name. The post-putAll conditional stamp in buildProperties already preserves caller-supplied $screen_name (including the value posthog-flutter sets from its capture wrapper), but the comment didn't say that. Make the Flutter passthrough explicit so it's visible to a reader. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-applied wrap on a long line that tripped spotlessKotlinCheck in CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Closes #119. RN and Flutter already attach
$screen_nameto every event oncescreen()has been called; Android did not. Suggested as a follow-up in #525 since that PR introduced thelastScreenNamecache onPostHog(originally for log records).💚 How did you test it?
Six unit tests in
PostHogScreenNameTest: before-screen baseline, after-screen attaches, caller override wins,reset()clears,$exceptioncarries it (locks in the cross-event scope decision),$snapshotdoes not (verifies theappendSharedProps = falsegate).End-to-end on a Pixel 4 across all five customer-visible scenarios — confirmed in device logcat and by querying the
eventstable onus.posthog.com:$screen_nametest_auto_captureNormalActivityscreen("ManualScreen")test_after_manualManualScreentest_overrideOverrideValuereset()test_after_resetscreen("ExceptionScreen")$exceptionExceptionScreenBehavior change to call out for reviewers: existing customers who have not disabled
captureScreenViewswill start seeing$screen_nameattached to$exception,$feature_view,$identify, etc. — not only$screenevents. Opt-out iscaptureScreenViews = falseplus avoiding manualPostHog.screen()calls.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file