Developer Hub · Protocol v1

Ship localized content without blocking app startup.

Publish an immutable environment release, create a public read-only SDK credential, initialize from cache and bundled translations, then refresh OTA in the background.

1. PublishCreate a release from Published translations.
2. ConnectUse a project and environment-scoped gl_sdk_ token.
3. Resolve offlineLookup is synchronous: cache, bundle, fallback, then key.

Supported SDKs

JavaScript@golocalise/javascript-sdkModern browsers or runtimes with fetch and Web Crypto

Public npm distribution is not configured yet.

iOSGoLocalise Swift packageiOS 15+ or macOS 12+

A public Swift Package URL is not configured yet.

AndroidGoLocalise Kotlin libraryAndroid API 26+

Public Maven coordinates are not configured yet.

Choose a project

Open a project and select Developer to see its live release, languages, credential status, OTA endpoint, and copy-ready SDK configuration.

Server-to-server export uses a different private credential model. See the Developer API v1 guide; never ship an organization API secret in a client app.

Try the read-only GoLocalise Demo client to switch languages, inspect keys, and exercise OTA refresh.

Run the demo clients

All demos use the same public, read-only gl_sdk_ credential. In your project, publish a release and open Developer to copy the project ID, environment, token, and OTA base URL. Never put an organization API secret in a demo app.

Web demoIncluded at /demo

Set the five NEXT_PUBLIC_DEMO_* values in .env, run pnpm dev, then open the demo.

iOS demoSwiftUI · iOS 15+

Add sdks/ios as a local Swift package, add the example source to an iOS app target, and provide its five GOLOCALISE_* Info.plist values.

Android demoCompose sample

Supply the five GOLOCALISE_* Gradle properties or environment variables and run :sample:assembleDebug.

# Web (.env)
NEXT_PUBLIC_DEMO_OTA_BASE_URL=http://localhost:3001
NEXT_PUBLIC_DEMO_SDK_TOKEN=gl_sdk_...
NEXT_PUBLIC_DEMO_PROJECT_ID=...
NEXT_PUBLIC_DEMO_ENVIRONMENT=production
NEXT_PUBLIC_DEMO_LOCALE=ar-LB

pnpm dev
# Open http://localhost:3000/demo

The repository's docs/demo-clients.md guide includes the complete Xcode, Gradle, and manual golden-path instructions.

Locales and regional Arabic

GoLocalise accepts BCP 47 locale tags. Use ar-LB for Arabic (Lebanon), ar-IQ for Arabic (Iraq), en-US, fr-CA, and other valid tags. Inputs such as ar_lb are accepted for convenience and stored as ar-LB, so every locale has one stable OTA/cache identity.

Add each regional locale under the project's Languages settings, translate it, and publish a release for the chosen environment. The SDK's supportedLocales() returns only locales present in that environment's current release; use one of those values with setLocale(...).

Placeholders and plurals

Translators use visual tokens and plural forms; GoLocalise handles the platform syntax. A string placeholder is modeled once and rendered as%@ for iOS, %1$s for Android, or a canonical token for Web. Escaped percent signs, positional arguments, and malformed values are validated safely.

Plurals use the locale's real categories—for example one/other in English and zero, one, two, few, many, and other in Arabic. iOS uses .stringsdict, Android uses plurals.xml, and OTA preserves canonical plural metadata for cache and bundled-fallback parity.

Important: count selects the plural category; it is not one of the positional arguments. Set the editor's Count Variable (usually count) and place {count} where the number belongs. Pass a numeric count to the SDK. Use arguments only for extra placeholders such as {0}. For Arabic, the active locale must be Arabic and a new OTA release must be published after changing forms.

Placeholder formatting is available in the current JavaScript, iOS, and Android SDK sources. The translation workspace also provides a locale-aware plural editor with an always-required other form.

// Web — canonical tokens: "Welcome, {0}"
client.t("welcome", { arguments: ["Maya"] })

// iOS — canonical {0} or Apple %@ / %1$@
client.translation(for: "welcome", arguments: ["Maya"])

// Android — canonical {0} or %s / %1$s
client.translation("welcome", arguments = listOf("Maya"))

// Web plural: count selects the form; arguments fill {0}
client.t("cart.items", { count: 1, arguments: ["Maya"] })

// iOS plural (Arabic 1 selects the one form)
client.translation(for: "cart.items", count: 1, arguments: ["Maya"])

// Android plural
client.translation("cart.items", count = 1.0, arguments = listOf("Maya"))