← Back to Blog

Flutter Context-Aware Localization: Best Practices

flutterlocalizationcontexttranslation-qualityi18n

Flutter Context-Aware Localization: Best Practices

Context matters in translation. The word "bank" means something different in "river bank" versus "financial bank". This guide shows you how to implement context-aware localization in Flutter to deliver accurate, natural translations.

The Context Problem

Consider these English words and their multiple meanings:

  • Book: "Book a flight" vs "Read a book"
  • Order: "Place an order" vs "In order"
  • Close: "Close the door" vs "Close to home"

Without context, AI translation and human translators can choose the wrong meaning, leading to confusing or even offensive mistakes.

Adding Context in Flutter

Flutter's .arb files support context through the @ metadata. Here's how to do it properly:

Basic Context Example

{
  "bookVerb": "Book",
  "@bookVerb": {
    "description": "Action button to book/reserve something (e.g. book a hotel, book a flight)"
  },
  "bookNoun": "Book",
  "@bookNoun": {
    "description": "Physical or digital book for reading"
  }
}

French Translation

{
  "bookVerb": "Réserver",
  "bookNoun": "Livre"
}

Real-World Examples

E-commerce Context

{
  "orderActionButton": "Order",
  "@orderActionButton": {
    "description": "Button text to place a purchase order"
  },
  "orderStatusSequence": "Order",
  "@orderStatusSequence": {
    "description": "Sequence or arrangement, as in 'in order'"
  },
  "orderHistoryTitle": "Orders",
  "@orderHistoryTitle": {
    "description": "List of previous purchase orders"
  }
}

Financial App Context

{
  "bankInstitution": "Bank",
  "@bankInstitution": {
    "description": "Financial institution where money is kept"
  },
  "riverBank": "Bank",
  "@riverBank": {
    "description": "Edge of a river or lake"
  }
}

Context for Buttons and Actions

Button text needs extra context because it's action-oriented:

{
  "saveDraft": "Save",
  "@saveDraft": {
    "description": "Button to save a draft of an email/document without sending"
  },
  "saveToFavorites": "Save",
  "@saveToFavorites": {
    "description": "Button to bookmark/save an item to favorites list"
  },
  "saveChanges": "Save",
  "@saveChanges": {
    "description": "Button to persist changes to database"
  }
}

German translations show why this matters:

{
  "saveDraft": "Entwurf speichern",
  "saveToFavorites": "Als Favorit speichern",
  "saveChanges": "Änderungen speichern"
}

Screen Location Context

Provide context about where text appears:

{
  "welcomeHomeScreen": "Welcome back!",
  "@welcomeHomeScreen": {
    "description": "Greeting shown on home screen for returning users"
  },
  "welcomeOnboarding": "Welcome!",
  "@welcomeOnboarding": {
    "description": "Greeting shown during first-time onboarding flow"
  },
  "welcomeEmailSubject": "Welcome to our app",
  "@welcomeEmailSubject": {
    "description": "Email subject line for welcome email"
  }
}

Formality Levels

Some languages have formal and informal forms. Provide context about the relationship:

{
  "youCustomerSupport": "you",
  "@youCustomerSupport": {
    "description": "Addressing customer in support context - should be polite/formal"
  },
  "youFriendlyChat": "you",
  "@youFriendlyChat": {
    "description": "Casual conversation between friends - can be informal"
  }
}

German translations:

{
  "youCustomerSupport": "Sie",  // Formal
  "youFriendlyChat": "du"        // Informal
}

Gender and Plurals with Context

Combine context with gender and plural forms:

{
  "friendRequestMessage": "{gender, select, male{He sent} female{She sent} other{They sent}} you a friend request",
  "@friendRequestMessage": {
    "description": "Notification message when someone sends a friend request",
    "placeholders": {
      "gender": {
        "type": "String"
      }
    }
  }
}

Context for Abbreviations

{
  "drTitle": "Dr.",
  "@drTitle": {
    "description": "Doctor title abbreviation (medical professional)"
  },
  "drStreetAbbrev": "Dr.",
  "@drStreetAbbrev": {
    "description": "Drive abbreviation in street addresses"
  }
}

Using Context in Your Code

class ProfilePage extends StatelessWidget {
  final String userRole;

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;

    // Use context-specific strings
    String greeting = userRole == 'customer'
        ? l10n.welcomeCustomer
        : l10n.welcomeAdmin;

    return Scaffold(
      appBar: AppBar(title: Text(greeting)),
      body: // ...
    );
  }
}

FlutterLocalisation Context Features

FlutterLocalisation makes context management easier:

  • Visual context editor: Add descriptions directly in the UI
  • AI understands context: Translations consider your descriptions
  • Context validation: Warns when context is missing
  • Search by context: Find all strings used in specific scenarios
  • Context templates: Reuse descriptions across similar strings

Context Checklist

For every translation key, ask:

  • What action does this trigger?
  • Where does it appear in the app?
  • Who is the audience?
  • What's the formality level?
  • Are there multiple meanings?
  • Does it involve gender or plurals?
  • Is it an abbreviation?

Bad vs Good Context

❌ Bad: Vague descriptions

{
  "close": "Close",
  "@close": {
    "description": "Close"
  }
}

✅ Good: Specific descriptions

{
  "closeDialogButton": "Close",
  "@closeDialogButton": {
    "description": "Button to dismiss modal dialog without saving changes"
  }
}

Testing Context

Write widget tests that verify contextual usage:

testWidgets('Save button uses correct context', (tester) async {
  await tester.pumpWidget(DraftEditor());

  // Verify draft context is used, not favorites
  expect(
    find.text(l10n.saveDraft),
    findsOneWidget
  );
});

Conclusion

Context-aware localization prevents translation errors and creates a more natural user experience. The extra effort in documenting context pays dividends in translation quality.

Without context, you're forcing translators to guess. With good context, you're enabling them to make informed decisions that make your app feel native in every language.


Want automated context management? FlutterLocalisation provides visual context editing, AI that understands your descriptions, and validation to ensure no string lacks context.