Skip to content

feat: add PostHog.setAppLanguage() and send $locale as BCP 47 on JVM - #115

Merged
turnipdabeets merged 6 commits into
chore/adopt-native-4.0from
feat/kmp-set-app-language
Nov 9, 2026
Merged

turnipdabeets merged 6 commits into
chore/adopt-native-4.0from
feat/kmp-set-app-language

Conversation

@turnipdabeets

@turnipdabeets turnipdabeets commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

💡 Motivation and Context

posthog-android 4.0 and posthog-ios 4.0 add $app_language, the language the app displays, detected from the languages the app declares. Compose Multiplatform resources declare neither localeConfig nor bundle localizations, so KMP apps get a wrong or missing value. This adds PostHog.setAppLanguage() so apps can set it on Android, iOS, macOS and JVM, and aligns the JVM $locale with posthog-android.

Decisions:

  • iOS and Android native detection stays on. It's correct for apps that declare their languages (localeConfig, CFBundleLocalizations), and turning it off would take a working value from them. setAppLanguage() overrides it, and a registered $app_language super property still wins. MIGRATION.md explains the Compose Multiplatform gap: iOS and macOS report the development language, Android sends nothing, and the fix is to list the languages or call setAppLanguage().
  • JS and Wasm don't send $app_language yet, because posthog-js doesn't support it, so setAppLanguage() does nothing there. A before_send hook in the wrapper would have to reimplement the filtering posthog-js applies before before_send (property_denylist, minimal $feature_flag_called events), so this waits for posthog-js. Apps can register() it themselves meanwhile. The KDoc, MIGRATION.md and the changeset say so.
  • JVM $locale is now Locale.toLanguageTag() without extensions, matching posthog-android. It keeps the script (zh-Hant-TW), gives en instead of en- when there's no region, and is omitted for an undetermined locale. This is a breaking change for filters on the old format, and MIGRATION.md and the changeset list it.

💚 How did you test it?

Unit tests on every target, all passing: jvmTest 73, testAndroidHostTest 55, jsNodeTest 65, wasmJsBrowserTest 51, iosSimulatorArm64Test 45, macosArm64Test 45. The new tests cover $app_language on every event on those platforms, surviving reset(), beforeSend seeing it, and the override and register precedence.

posthog-ios 4.0.0 isn't tagged yet, so the iOS and macOS tests ran against a local checkout of posthog-ios chore/v4-remove-deprecated (7b4580c). This PR keeps the pinned swiftPackage and .swiftpm-locks. No manual testing on a device.

📝 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 change to generate a change intent file (updated the existing adopt-native-4-0 intent)

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Written with Claude Code. Native detection was kept rather than disabled, and JS and Wasm wait for posthog-js instead of injecting the value in before_send (see the decisions above).

🤖 Generated with Claude Code

@sampo-s-bot

sampo-s-bot Bot commented Nov 6, 2026

Copy link
Copy Markdown

⚠️ No changeset detected

No new .sampo/changesets/*.md files were detected in this PR. To add one:

  • run sampo add
  • follow the prompts to pick the affected packages and describe the change
  • commit the generated file to this pull request, and it will be detected automatically

If this PR isn't supposed to introduce any changes (e.g., documentation updates), you can ignore this message.

@posthog posthog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PostHog Review · Standard · reviewed f3d8f16: 1 Consider.

See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.

Set $app_language on every platform: forwarded to the native SDKs on
Android, JVM, iOS and macOS, and added in before_send on JS and Wasm,
where posthog-js has no such property. Document the Compose Multiplatform
resources gap in MIGRATION.md.
@turnipdabeets
turnipdabeets force-pushed the feat/kmp-set-app-language branch from f3d8f16 to faabe09 Compare November 6, 2026 20:16
…linkable (#116)

* fix(jvm): keep PostHogConfig copy and default-argument constructor linkable

Adding evaluationContexts changed the data class copy and the
synthetic default-argument constructor, so JVM code compiled against
0.10 that calls copy(...) or PostHogConfig(..., capturePush...= ...)
hit NoSuchMethodError. Add a hidden 20-parameter copy and give the
retained 20-parameter constructor its defaults back.

Also drop the duplicated evaluationContexts assignment on Android and
JVM.

* test(config): use assertNull for the null evaluation contexts check

* chore: re-run CI after retitling to chore
@turnipdabeets
turnipdabeets merged commit 0769afd into chore/adopt-native-4.0 Nov 9, 2026
10 checks passed
@turnipdabeets
turnipdabeets deleted the feat/kmp-set-app-language branch November 9, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants