Skip to content

feat: auto-attach $screen_name to all events#530

Open
turnipdabeets wants to merge 10 commits into
feat/logs-pr3from
feat/screen-name-on-all-events
Open

feat: auto-attach $screen_name to all events#530
turnipdabeets wants to merge 10 commits into
feat/logs-pr3from
feat/screen-name-on-all-events

Conversation

@turnipdabeets
Copy link
Copy Markdown
Contributor

Stacked on #525. Base will auto-update to main when that lands.

💡 Motivation and Context

Closes #119. RN and Flutter already attach $screen_name to every event once screen() has been called; Android did not. Suggested as a follow-up in #525 since that PR introduced the lastScreenName cache on PostHog (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, $exception carries it (locks in the cross-event scope decision), $snapshot does not (verifies the appendSharedProps = false gate).

End-to-end on a Pixel 4 across all five customer-visible scenarios — confirmed in device logcat and by querying the events table on us.posthog.com:

Scenario Event $screen_name
Auto-capture (NormalActivity) test_auto_capture NormalActivity
Manual screen("ManualScreen") test_after_manual ManualScreen
Caller override test_override OverrideValue
After reset() test_after_reset absent
Exception after screen("ExceptionScreen") $exception ExceptionScreen

Behavior change to call out for reviewers: existing customers who have not disabled captureScreenViews will start seeing $screen_name attached to $exception, $feature_view, $identify, etc. — not only $screen events. Opt-out is captureScreenViews = false plus avoiding manual PostHog.screen() calls.

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

turnipdabeets and others added 2 commits May 22, 2026 10:57
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).
@turnipdabeets turnipdabeets requested a review from a team as a code owner May 22, 2026 15:13
turnipdabeets and others added 4 commits May 22, 2026 13:01
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>
}

// Cache for capture-time context snapshot on log records.
if (screenTitle.isBlank()) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to trim before checking, and assign the lastScreenName already trimmed

// override still takes precedence.
if (appendSharedProps) {
val cachedName = lastScreenName
val callerName = (props["\$screen_name"] as? String)?.trim()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val cachedName = lastScreenName
val callerName = (props["\$screen_name"] as? String)?.trim()
if (!cachedName.isNullOrEmpty() && callerName.isNullOrEmpty()) {
props["\$screen_name"] = cachedName
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flutter also captures $screen_name, and uses the android sdk, so its better to check if we are not overwriting the flutter value here

turnipdabeets and others added 2 commits May 23, 2026 15:36
… 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants