---
title: "Lokalise"
description: "Use Lokalise for MainSDK translations - project and API token, main.yaml, locales, missing strings caught by the check, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/lokalise"
updated: "2026-10-28"
---

# Lokalise

> Use Lokalise for MainSDK translations - project and API token, main.yaml, locales, missing strings caught by the check, testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/lokalise · Updated: 2026-10-28

Lokalise is a translation management platform for product and engineering teams. Behind [`i18n`](https://mainsdk.dev/docs/interfaces/i18n), it holds your translations while your code keeps calling `t()`. Pick it when your team already manages strings in Lokalise.

> **Note:** `i18n` has no spec yet. The options on this page are provisional and may change when the spec lands.

## Interfaces it serves

### Languages and formats (`i18n`)

- Status: Preview · ships as a beta API
- Driver: `lokalise` (Lokalise)
- Docs: https://mainsdk.dev/docs/interfaces/i18n.md

```yaml
i18n:
  driver: lokalise
```

Swap to another provider: `files`, `tolgee`, `crowdin`, `ai-draft`.

## Before you start

1. Create a Lokalise project with the languages you ship, and note its project ID.
2. Create an API token with access to the project.
3. Store the token in your secrets manager.

## Configure

```yaml title="main.yaml"
i18n:
  driver: lokalise
  locales: [en-IN, hi-IN, ta-IN]
  # [TBD] project ID, and the API token as secret:LOKALISE_API_TOKEN
```

## Use it

```ts title="app/orders/heading.ts"
import { t } from "mainsdk";

export function heading(orders: unknown[]) {
  return t("orders.count", { count: orders.length });
}
```

## Local development and testing

Build with the default `files` driver and switch to `lokalise` when translators join. In tests, `createTestApp()` from `@mainsdk/testing` runs `i18n` without a network, and `chaos.on("i18n", { outage: true })` simulates Lokalise being unreachable.

## What MainSDK adds on top

- A missing translation fails the check, not the user.
- Pseudo-localization in the check catches layout breaks before a translator sees them.

See [Languages and formats](https://mainsdk.dev/docs/interfaces/i18n).

## Limits and notes

- Planned driver from the product requirements; `i18n` has no spec yet.
- How strings sync between your repo and Lokalise is not defined yet [TBD].

## Swap to or from it

```yaml title="main.yaml"
i18n:
  driver: lokalise   # was files
```

> **Warning:** Translations live in Lokalise. Export them before you switch to another driver; how strings move between drivers is not decided yet [TBD].

## FAQ

**Which file formats move in and out?** MainSDK imports and exports XLIFF, iOS `.xcstrings`, Android strings and ICU JSON (`byo-content`).

## Next

- [Languages and formats](https://mainsdk.dev/docs/interfaces/i18n) and [Translate your app](https://mainsdk.dev/docs/guides/i18n)
- [Crowdin](https://mainsdk.dev/docs/integrations/crowdin) and [Tolgee](https://mainsdk.dev/docs/integrations/tolgee)
