Skip to main content

Komplett guide till Flutter-lokalisering

Från ARB-filer till RTL-stöd: lokalisera din Flutter-app med easy_localization, hantera pluralformer för alla språk och automatisera översättningar med AI.

1

Installera easy_localization

Lägg till paketet easy_localization i din pubspec.yaml. Det är det populäraste Flutter-paketet för i18n och stöder ARB-/JSON-filer, pluralformer och kontexttillägg. Lägg även till flutter_localizations från SDK:n för språkanpassad formatering av datum och tal samt textriktning.

easy_localization tillhandahåller kontexttillägg som context.tr() och 'key'.tr() för smidig åtkomst till översättningar. Det hanterar inläsning och lagring av språkversionen samt hot reload av översättningsfiler under utvecklingen.
pubspec.yaml
dependencies:
  easy_localization: ^3.0.7
  flutter_localizations:
    sdk: flutter
2

Skapa ARB-översättningsfiler

Application Resource Bundle-filer (ARB) är standardformatet för lokalisering i Flutter. Varje fil innehåller nyckel–värde-par med valfria metadata som beskriver platshållare, pluralregler och kontext för översättare. Skapa en fil per språkversion i katalogen assets/translations.

assets/translations/en.arb
{
  "@@locale": "en",
  "appTitle": "My App",
  "@appTitle": {
    "description": "The title of the application"
  },
  "greeting": "Hello, {name}!",
  "@greeting": {
    "description": "Greeting with user name",
    "placeholders": {
      "name": {
        "type": "String",
        "example": "Alice"
      }
    }
  },
  "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
  "@itemCount": {
    "description": "Number of items in the cart",
    "placeholders": {
      "count": {
        "type": "num",
        "format": "compact"
      }
    }
  }
}
Nycklar med prefixet @ (som @greeting) är metadata – de beskriver strängen ovanför. Inkludera platshållartyper och exempel så att översättarna kan skapa korrekta översättningar. Dessa metadatanycklar tas bort vid körning och medför ingen extra belastning.
3

Konfigurera appen

Omslut din app med widgeten EasyLocalization. Den hanterar språkversionsstatus, läser in översättningar från dina resursfiler och tillhandahåller de språkversionsdelegater som MaterialApp behöver. De tre obligatoriska delegategenskaperna är localizationsDelegates, supportedLocales och locale – alla är tillgängliga via kontexttillägg.

lib/main.dart
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: [
        Locale('en'),
        Locale('ar'),
        Locale('ja'),
        Locale('de'),
      ],
      path: 'assets/translations',  // Path to your ARB/JSON files
      fallbackLocale: Locale('en'),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: HomePage(),
    );
  }
}
"Easy Localization not initialized" – det här felet innebär att du har glömt att anropa EasyLocalization.ensureInitialized() före runApp(). Anropet måste inväntas efter WidgetsFlutterBinding.ensureInitialized() och före runApp().
4

Översätt widgetar

Använd tilläggsmetoden .tr() på strängnycklar för att hämta översatt text i valfri widget. Använd .plural() med antalsvärdet för pluralformer. easy_localization tillhandahåller både strängtilläggssyntaxen ('key'.tr()) och kontextmetodsyntaxen (context.tr('key')).

lib/widgets/home_page.dart
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('appTitle'.tr()),   // Simple key
      ),
      body: Column(
        children: [
          // String with variable interpolation
          Text('greeting'.tr(args: ['Alice'])),

          // Named arguments
          Text('greeting'.tr(namedArgs: {'name': 'Alice'})),

          // Plural form
          Text('itemCount'.plural(3)),
        ],
      ),
    );
  }
}
Om råa nycklar returneras i stället för översatt text kontrollerar du följande: 1) Widgeten EasyLocalization omsluter din MaterialApp, inte tvärtom. 2) Dina översättningsfiler anges under assets i pubspec.yaml. 3) Filsökvägen i EasyLocalization motsvarar din faktiska katalogstruktur.
5

Hantera pluralformer och variabler

Flutter använder ICU MessageFormat för pluralformer – samma standard som används av iOS, Android och webben. Definiera pluralformer med syntaxen {count, plural, ...} i dina ARB-filer. Varje språk behöver en egen uppsättning former baserat på CLDR:s pluralregler. Arabiska har 6 former, ryska har 4 och japanska har 1.

Plural forms by language
// English: 3 useful forms (=0, =1, other)
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"

// Arabic: 6 forms (=0, =1, =2, few, many, other)
"itemCount": "{count, plural, =0{لا عناصر} =1{عنصر واحد} =2{عنصران} few{{count} عناصر} many{{count} عنصرًا} other{{count} عنصر}}"

// Japanese: 1 form (other)
"itemCount": "{count, plural, other{{count}個のアイテム}}"

// German: 2 forms (=1, other)
"itemCount": "{count, plural, =1{1 Artikel} other{{count} Artikel}}"

// Russian: 3 forms (one, few, many)
"itemCount": "{count, plural, =0{Нет товаров} one{{count} товар} few{{count} товара} many{{count} товаров} other{{count} товаров}}"
Variables and named arguments
// Simple variable
"welcome": "Welcome, {name}!"

// Multiple variables
"orderStatus": "Order #{orderId} — {status}"

// Variable in plural context
"unreadMessages": "{count, plural, =0{No unread messages} =1{1 unread message from {sender}} other{{count} unread messages}}"

// In widgets:
Text('welcome'.tr(namedArgs: {'name': userName}));
Text('orderStatus'.tr(namedArgs: {'orderId': '1234', 'status': 'Shipped'}));
Text('unreadMessages'.plural(count, namedArgs: {'sender': senderName}));
Hårdkoda aldrig logik för singular och plural med if (count == 1). Språk som franska behandlar 0 som singular. Ryska, polska och arabiska har pluralformer som helt saknas i engelskan. Använd alltid ICU:s pluralsyntax och låt ramverket välja rätt form.
6

Stöd RTL-språk

Flutter spegelvänder automatiskt hela layouten när språkversionen använder ett höger-till-vänster-språk, exempelvis arabiska, hebreiska, persiska eller urdu. Koden måste dock använda riktningsmedvetna widgetar och egenskaper för att spegelvändningen ska fungera korrekt. Ersätt hårdkodad vänster/höger med motsvarande start/slut.

lib/widgets/adaptive_layout.dart
import 'package:flutter/material.dart';

class AdaptiveLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final isRtl = Directionality.of(context) == TextDirection.rtl;

    return Scaffold(
      body: Row(
        children: [
          // Use start/end instead of left/right
          Expanded(
            child: Padding(
              padding: EdgeInsetsDirectional.only(
                start: 16.0,  // Leading edge (left in LTR, right in RTL)
                end: 8.0,     // Trailing edge
              ),
              child: Text('content'.tr()),
            ),
          ),
          // Flip icons for RTL
          Icon(
            isRtl ? Icons.arrow_back : Icons.arrow_forward,
          ),
        ],
      ),
    );
  }
}
RTL-aware widget patterns
// Use Directional widgets for RTL-aware layouts
EdgeInsetsDirectional.only(start: 16, end: 8)   // Not EdgeInsets.only(left: 16, right: 8)
AlignmentDirectional.centerStart                  // Not Alignment.centerLeft
BorderRadiusDirectional.only(topStart: Radius.circular(8))

// Automatically mirrors when locale changes to Arabic, Hebrew, etc.
// No conditional logic needed — Flutter handles text direction from locale
Testa RTL genom att tillfälligt ange arabiska som appens språkversion (Locale('ar')). Flutter spegelvänder hela användargränssnittet – navigeringspaneler öppnas från höger, bakåtpilar vänds och text högerjusteras. Använd EdgeInsetsDirectional, AlignmentDirectional och BorderRadiusDirectional för att se till att dina anpassade layouter spegelvänds korrekt.
7

Smarta reservkedjor för språkversioner

När en pt-BR-översättning saknas går Flutter som standard direkt över till engelska och hoppar över fullt användbara pt-PT-översättningar. Paketet locale_chain löser detta med konfigurerbara reservkedjor. Det krävs bara en konfigurationsrad och ingen migrering – dina befintliga .tr()-anrop fortsätter att fungera.

lib/main.dart with LocaleChain
import 'package:locale_chain/locale_chain.dart';
import 'package:locale_chain/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();
  LocaleChain.configure();  // Enable smart fallback chains

  runApp(
    EasyLocalization(
      supportedLocales: [
        Locale('en'),
        Locale('pt', 'BR'),
        Locale('pt', 'PT'),
        Locale('es'),
        Locale('es', 'MX'),
      ],
      path: 'assets/translations',
      assetLoader: LocaleChainAssetLoader(  // Swap in the chain loader
        baseLoader: RootBundleAssetLoader(),
      ),
      fallbackLocale: Locale('en'),
      child: MyApp(),
    ),
  );
}

// Result: pt-BR user sees pt-PT translations when pt-BR keys are missing,
// instead of falling back directly to English.
Custom fallback configuration
// Override specific chains while keeping built-in defaults
LocaleChain.configure(
  fallbacks: {
    'pt-BR': ['pt-PT', 'pt'],      // pt-BR → pt-PT → pt → en
    'es-MX': ['es-419', 'es'],     // es-MX → es-419 → es → en
    'fr-CA': ['fr'],               // fr-CA → fr → en
  },
);

// Or replace all defaults with your own chains
LocaleChain.configure(
  fallbacks: {
    'zh-Hant-HK': ['zh-Hant-TW', 'zh-Hans'],
    'pt-BR': ['pt-PT', 'pt'],
  },
  mergeDefaults: false,  // Only your chains, no built-in defaults
);
locale_chain innehåller inbyggda reservkedjor för regionala varianter av portugisiska, spanska, franska, tyska, italienska, nederländska, norska och malajiska. En pt-BR-användare ser innehåll på pt-PT före engelska. En es-MX-användare ser es-419 och sedan es före standardspråkversionen.
8

Automatisera översättningar

När lokaliseringskonfigurationen är klar kan du översätta dina ARB-filer med AI. Be din AI-assistent i utvecklingsmiljön att översätta ARB-källfilen eller använd i18n Agent CLI i din CI/CD-pipeline. ARB-metadata (platshållare och beskrivningar) ger kontext som förbättrar översättningskvaliteten.

Terminal
# In your IDE, ask your AI assistant:
> Translate assets/translations/en.arb to Arabic, Japanese, and German

✓ ar.arb created (1.4s)
✓ ja.arb created (1.2s)
✓ de.arb created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate assets/translations/en.arb --lang ar,ja,de
Översätt stegvis – när du lägger till nya nycklar i ARB-källfilen översätter du bara skillnaden i stället för att generera om alla filer. Då bevaras översättningar som har granskats av människor och dina ARB-metadata förblir intakta.

Automatisera kontrollen av översättningskvalitet

Upptäck saknade nycklar och trasiga platshållare före lansering med i18n-validate. Testa användargränssnittet med pseudoöversättningar via i18n-pseudo innan de riktiga översättningarna är klara.

Vanliga fallgropar

Översättningsfiler hittas inte vid körning

Dina ARB-/JSON-filer måste anges i avsnittet assets i pubspec.yaml. Om detta steg saknas kan Flutter inte hitta filerna vid körning trots att de finns på disken. Lägg till: assets: - assets/translations/

Ogiltig syntax i ARB-filen

ARB-filer är strikt JSON – inga avslutande kommatecken, enkla citattecken eller kommentarer tillåts. Ett enda syntaxfel kan tyst hindra hela filen från att läsas in. Validera dina ARB-filer med en JSON-linter innan du felsöker översättningsproblem.

Översättningsändringar visas inte efter hot reload

easy_localization cachelagrar översättningar i minnet. När du lägger till nya nycklar eller ändrar befintliga översättningar kan en fullständig hot restart krävas (inte hot reload) för att ändringarna ska börja gälla. Använd hot restart (Shift+R) efter att du har redigerat översättningsfiler under utvecklingen.

Hårdkodad vänster/höger förstör RTL-layouten

Om du använder EdgeInsets.only(left: 16) i stället för EdgeInsetsDirectional.only(start: 16) kan Flutter inte spegelvända layouten för RTL-språk. Sök igenom kodbasen efter EdgeInsets, Alignment och BorderRadius utan suffixet Directional.

Rekommenderad filstruktur

Project Structure
my_flutter_app/
├── assets/
│   └── translations/
│       ├── en.arb          # Source language (English)
│       ├── ar.arb          # Arabic (with 6 plural forms)
│       ├── de.arb          # German
│       ├── ja.arb          # Japanese
│       ├── pt-BR.arb       # Brazilian Portuguese
│       └── pt-PT.arb       # European Portuguese
├── lib/
│   ├── main.dart           # App entry with EasyLocalization
│   ├── app.dart            # MaterialApp with locale delegates
│   └── widgets/
│       └── language_switcher.dart
├── pubspec.yaml            # Dependencies
└── analysis_options.yaml

Prova i18n Agent nu

Släpp din översättningsfil här

JSON, YAML, PO, XML, CSV, Markdown, Properties

eller klicka för att välja en fil

Målspråk

Ingen registrering krävsPrisuppskattning direkt

Reservspråk med locale_chain

När en översättningsnyckel saknas i en regional språkversion som pt-BR går Flutter direkt till mallspråket i stället för att först kontrollera den överordnade språkversionen pt.

Terminal
flutter pub add locale_chain
Configuration
import 'package:locale_chain/locale_chain.dart';

LocaleChain.configure(fallbacks: {
  'pt-BR': ['pt', 'en'],
  'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
});

LocaleChainAssetLoader(baseLoader: RootBundleAssetLoader());

Se vår guide om reservspråk för en fullständig lista över ramverk som stöds och 75 inbyggda kedjor. Learn more →

Vanliga frågor