Skip to content

feat(v3): add cross-platform SystemLocale() API (BCP-47 language tag) - #5894

Open
mortenolsrud wants to merge 1 commit into
wailsapp:masterfrom
mortenolsrud:feat/system-locale-api
Open

feat(v3): add cross-platform SystemLocale() API (BCP-47 language tag)#5894
mortenolsrud wants to merge 1 commit into
wailsapp:masterfrom
mortenolsrud:feat/system-locale-api

Conversation

@mortenolsrud

@mortenolsrud mortenolsrud commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

There is no way to get the system/device locale from Go code in a Wails app. On Android, the LANG/LC_ALL env vars are not set in the app sandbox; on iOS, the locale is only accessible via Foundation; on desktop platforms, the approach differs per OS.

This adds a unified application.SystemLocale() function that returns the BCP-47 language tag (e.g. "nb-NO", "en-US") on all platforms:

locale := application.SystemLocale() // works on all platforms

Also adds SystemLocale() to the MobileManager interface for mobile access via application.Mobile.SystemLocale().

Per-platform implementations:

Platform Method Source
Android Locale.getDefault().toLanguageTag() WailsBridge (new getLocale() method)
iOS NSLocale.currentLocale.localeIdentifier ObjC bridge (new ios_system_locale())
macOS NSLocale.currentLocale Foundation framework via CGO
Windows GetUserDefaultLocaleName() kernel32.dll syscall
Linux $LC_ALL / $LC_MESSAGES / $LANG Env vars, parsed to BCP-47
Server Same as Linux Env vars

All implementations normalize to BCP-47 (hyphen-separated) and fall back to "en" if detection fails.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Linux (GTK3) build — compiles, SystemLocale() returns the host's $LANG value.

  • Android cross-compile (android/arm64 via NDK) — compiles.

  • Windows cross-compile (GOOS=windows CGO_ENABLED=0) — compiles.

  • Host-side command tests — pass.

  • iOS: ios_system_locale() follows the same mfDup() pattern as ios_network_json() etc.

  • Windows

  • macOS

  • Linux

Test Configuration

  • Wails CLI: v3.0.0-beta.3
  • Go: go1.26.5
  • Ubuntu 24.04.4, Android NDK 26.3.11579264

Checklist:

  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Note: The Linux implementation can be unit-tested on the host (reads env vars). A quick follow-up could add a test for parsePosixLocale. The mobile/macOS/Windows implementations require their respective platforms.

Summary by CodeRabbit

  • New Features
    • Added system locale detection across Android, iOS, Windows, macOS, Linux, and server environments.
    • Locale values are returned in standardized BCP-47 format, such as en-US.
    • Added fallback handling for unavailable or unspecified locales.
    • Mobile application management now exposes the device's current locale.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ab999850-8291-41dd-bd7d-376231ffb7ec

📥 Commits

Reviewing files that changed from the base of the PR and between bcc9d55 and 0218d2f.

📒 Files selected for processing (13)
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_darwin.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/locale_server.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/mobile_features_ios.h
  • v3/pkg/application/mobile_features_ios.m
  • v3/pkg/application/mobile_stub.go
🚧 Files skipped from review as they are similar to previous changes (13)
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_features_ios.h
  • v3/pkg/application/mobile.go
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/mobile_features_ios.m
  • v3/pkg/application/locale_darwin.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/mobile_stub.go
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_server.go

Walkthrough

The application package now exposes SystemLocale() for desktop, server, Android, and iOS targets. Mobile managers expose the same method. Implementations return BCP-47-style locale tags and use "en" as a fallback.

Changes

System Locale Support

Layer / File(s) Summary
Native locale bridges
v3/internal/commands/build_assets/android/.../WailsBridge.java, v3/pkg/application/mobile_features_ios.*
Added Android and iOS native methods that return system locale tags.
Platform locale providers
v3/pkg/application/locale_*.go
Added platform-specific locale detection, environment-variable precedence, normalization, native API calls, and "en" fallbacks.
Mobile locale contract and delegation
v3/pkg/application/mobile.go, v3/pkg/application/mobile_stub.go, v3/pkg/application/mobile_features_*
Added SystemLocale() to MobileManager and implemented Android, iOS, and stub manager methods.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MobileManager
  participant AndroidWailsBridge
  participant IOSNativeLocale
  MobileManager->>AndroidWailsBridge: getLocale()
  AndroidWailsBridge-->>MobileManager: BCP-47 locale
  MobileManager->>IOSNativeLocale: ios_system_locale()
  IOSNativeLocale-->>MobileManager: BCP-47 locale
Loading

Poem

A rabbit gathers locale tags,
From Linux hosts and mobile bags.
Hyphens mark the language trail,
Native bridges carry the detail.
“en” waits when other tags fail.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the cross-platform SystemLocale API and its BCP-47 language-tag behavior.
Description check ✅ Passed The description explains the feature, platform implementations, testing, configuration, and checklist status; issue linkage and added tests are not provided.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@v3/pkg/application/locale_android.go`:
- Around line 8-10: The Android locale bridge methods must return the documented
"en" fallback when the bridge errors or returns an empty string. Update
SystemLocale in v3/pkg/application/locale_android.go (lines 8-10) and the
corresponding method in v3/pkg/application/mobile_features_android.go (lines
145-147) to retain the bridge error and return "en" when err is non-nil or s is
empty; otherwise preserve the returned locale.

In `@v3/pkg/application/locale_ios.go`:
- Around line 5-8: Update SystemLocale in locale_ios.go by adding a cgo preamble
declaring ios_system_locale(void) and importing the C pseudo-package before the
package declaration, so the existing C.ios_system_locale() call resolves during
the iOS build.

In `@v3/pkg/application/locale_linux.go`:
- Line 1: Update the build constraint for the Linux provider in locale_linux.go
to require !server in addition to linux && !android, preventing it from
compiling alongside the server-specific SystemLocale implementation.

In `@v3/pkg/application/locale_server.go`:
- Around line 13-20: Update the locale normalization logic in the shown function
to remove any suffix beginning with “@” before replacing underscores and
returning the tag, matching parsePosixLocale’s handling. Preserve the existing
dot truncation, fallback to “en” for empty/C/POSIX values, and normalized locale
return behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ea299d1-88b4-4765-afd0-c461d71ddb22

📥 Commits

Reviewing files that changed from the base of the PR and between 2014eb6 and 964ee0d.

📒 Files selected for processing (12)
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_darwin.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/locale_server.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/mobile_features_ios.m
  • v3/pkg/application/mobile_stub.go

Comment thread v3/pkg/application/locale_android.go
Comment thread v3/pkg/application/locale_ios.go Outdated
Comment thread v3/pkg/application/locale_linux.go Outdated
Comment thread v3/pkg/application/locale_server.go Outdated
@mortenolsrud
mortenolsrud force-pushed the feat/system-locale-api branch 2 times, most recently from 4523141 to 8789385 Compare August 4, 2026 09:53
@mortenolsrud

Copy link
Copy Markdown
Contributor Author

Addressed in the force-push:

  1. Android "en" fallback — Fixed. Both locale_android.go and the androidManager.SystemLocale() method now return "en" if the bridge returns an empty string.

2-4. iOS symbol / Linux build tag / Server modifier — These were already fixed in the previous force-push (before CodeRabbit's review ran). The review was against the pre-fix commit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@v3/pkg/application/locale_darwin.go`:
- Around line 18-22: Update the legacy locale fallback in the locale retrieval
implementation to preserve script and variant subtags, rather than constructing
the tag solely from languageCode and countryCode. Use a canonical or explicit
locale identifier API compatible with macOS versions below 13, ensuring values
such as zh-Hant_TW retain all available components.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 00a95efa-b787-4c16-9f3d-2f7641db83ac

📥 Commits

Reviewing files that changed from the base of the PR and between 964ee0d and 4523141.

📒 Files selected for processing (13)
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_darwin.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/locale_server.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/mobile_features_ios.h
  • v3/pkg/application/mobile_features_ios.m
  • v3/pkg/application/mobile_stub.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_stub.go
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/locale_linux.go
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java

Comment thread v3/pkg/application/locale_darwin.go Outdated
@mortenolsrud
mortenolsrud force-pushed the feat/system-locale-api branch from 8789385 to bcc9d55 Compare August 4, 2026 10:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@v3/pkg/application/mobile_features_ios.m`:
- Around line 717-718: Remove the duplicate file-scope `return mfDup(tag);`
statement and its accompanying closing brace immediately after
`ios_system_locale`; retain the valid return and function closure already
present in that function.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fb5ae7f7-eeda-4b73-97c0-3d13736d25a3

📥 Commits

Reviewing files that changed from the base of the PR and between 8789385 and bcc9d55.

📒 Files selected for processing (13)
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_darwin.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/locale_server.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/mobile_features_ios.h
  • v3/pkg/application/mobile_features_ios.m
  • v3/pkg/application/mobile_stub.go
🚧 Files skipped from review as they are similar to previous changes (12)
  • v3/pkg/application/mobile_features_ios.go
  • v3/pkg/application/locale_ios.go
  • v3/pkg/application/locale_windows.go
  • v3/pkg/application/mobile_features_ios.h
  • v3/internal/commands/build_assets/android/app/src/main/java/com/wails/app/WailsBridge.java
  • v3/pkg/application/locale_server.go
  • v3/pkg/application/mobile_stub.go
  • v3/pkg/application/locale_android.go
  • v3/pkg/application/locale_linux.go
  • v3/pkg/application/mobile.go
  • v3/pkg/application/mobile_features_android.go
  • v3/pkg/application/locale_darwin.go

Comment thread v3/pkg/application/mobile_features_ios.m Outdated
Add application.SystemLocale() returning the device/system locale as a
BCP-47 language tag (e.g. "nb-NO", "en-US") on all platforms:

  Android: Locale.getDefault().toLanguageTag() via WailsBridge
  iOS:     NSLocale.currentLocale.localeIdentifier (underscore→hyphen)
  macOS:   NSLocale.currentLocale (Foundation framework)
  Windows: GetUserDefaultLocaleName (kernel32.dll)
  Linux:   $LC_ALL / $LC_MESSAGES / $LANG parsed to BCP-47

Also adds SystemLocale() to the MobileManager interface, so it is
accessible via application.Mobile.SystemLocale() on mobile platforms
(delegates to the platform-specific implementation).

Usage:
  locale := application.SystemLocale() // works everywhere
  // or on mobile:
  locale := application.Mobile.SystemLocale()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants