Apps SDK — Flutter

Translate your Flutter or Dart app's UI into 90 languages with one init call and a TransableText widget. Pure Dart, zero runtime dependencies. Translations are cached on disk for instant offline startup, and no public call ever throws into your app — every failure falls back to the original text.

Experimental preview. This is an early Dart port (0.1.0-preview.1). On the build machine it is dart analyze-clean, passes 58/58 unit tests, and a live check against the real API translated en → ru and served the repeat call from cache. It is not battle-tested inside a shipped Flutter app, has no web support (the transport uses dart:io), and the public API may still change. Not recommended for a shipping app yet — we'd love your feedback.

Install

  1. Download the package: transable-flutter-0.1.0-preview.1.zip
  2. Unzip it next to your app and depend on the local copy in your pubspec.yaml (once the repo is public you can use a git or pub.dev dependency instead — see PUBLISH.md):
dependencies:
  transable_sdk:
    path: ../transable-flutter

Then run flutter pub get (or dart pub get in a pure-Dart CLI project). Supported targets: Flutter mobile/desktop and the Dart CLI — no web. Create an app project in the dashboard and copy your API key.

One-line start

Call Transable.init(...) exactly once at startup. It is idempotent and never throws — a missing or wrong key just leaves the UI in the source language. Pass a real, writable cacheDirectory so the offline cache persists across launches:

import 'package:path_provider/path_provider.dart';
import 'package:transable_sdk/transable_sdk.dart';
import 'package:transable_sdk/transable_widget.dart'; // TransableText

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final support = await getApplicationSupportDirectory();

  Transable.init('tk_live_yourKeyHere', TransableOptions(
    appName: 'my-app',
    cacheDirectory: support.path,
    // defaultLanguage: 'de',   // else the user's OS locale is detected
  ));

  runApp(const MyApp());
}

Translate — the widget, or one call

The idiomatic Flutter path: wrap the strings you want translated. The widget re-renders when the language changes and when the background translation lands. The authored string is both the source text and the fallback shown until the translation arrives:

TransableText('Save changes')

Or call t() directly — synchronous and cache-first (returns the fallback and queues a background batch on a miss), plus an async index-aligned batch:

Text(Transable.t('greeting', 'Welcome back'))

final out = await Transable.translateBatch(['Save', 'Cancel'], language: 'de');
// index-aligned: ['Speichern', 'Abbrechen']

There is no automatic widget-tree scanning — you explicitly wrap what you want translated. That's a privacy boundary: the SDK never picks up text a user typed into a field. Rebuild your UI on Transable.onLanguageChanged / onTranslationsUpdated, and switch language with Transable.setLanguage('de').

Safe mode & offline cache

Safe mode is on by default and runs before any network I/O, so filtered text never leaves the machine: emails, URLs, file paths, GUIDs, version strings, log lines, and code-like identifiers (snake_case, PascalCase) are never sent — while ordinary UI words like "Save" and "Cancel" do translate. The SDK only ever translates strings you explicitly pass to t() / translateBatch() or author on a TransableText.

Every translation is written to disk at {cacheDirectory}/v1/{lang}.jsonl, per language, content-addressed (10 MB per-language cap), so the second launch is translated instantly, even offline. Always pass a real cacheDirectory — in a Flutter app use a path_provider directory.

It never crashes your app

One rule: no public entry point ever throws. Missing key, no network, HTTP 4xx/5xx, quota exhaustion, a malformed response, even a throwing logger — every failure degrades to the source-language text, with at most a message on your logger.

Questions or something broke? Contact us — include your Flutter/Dart version and the package version. Other platforms: Android, iOS / macOS, or any language via the REST API. Full platform list on Apps SDK.