SuperAPI AI Directory

maui-localization

General & other

View repository

Updated 10-16 05:05

About this skill

.NET MAUI Localization

Common gotchas

Issue Fix
ResourceManager returns null for default culture Set <NeutralLanguage>en-US</NeutralLanguage> in .csproj
iOS ignores culture overrides CFBundleLocalizations missing from Info.plist
Windows doesn't show correct language <Resource Language="..." /> missing from Package.appxmanifest
x:Static bindings don't update on language switch x:Static is one-time — use binding approach with INotifyPropertyChanged
.Designer.cs not regenerating in VS Code Add <CoreCompileDependsOn>PrepareResources;$(CoreCompileDependsOn)</CoreCompileDependsOn> and run dotnet build

⚠️ NeutralLanguage is mandatory

<!-- ✅ Always set in .csproj -->
<PropertyGroup>
  <NeutralLanguage>en-US</NeutralLanguage>
</PropertyGroup>

## Platform declarations — don't forget these

### iOS / Mac Catalyst

⚠️ Without this, iOS won't offer your app's languages in system Settings:

```xml
<!-- Platforms/iOS/Info.plist AND Platforms/MacCatalyst/Info.plist -->
<key>CFBundleLocalizations</key>
<array>
  <string>en</string>
  <string>es</string>
  <string>fr</string>
</array>

Windows

<!-- Platforms/Windows/Package.appxmanifest -->
<Resources>
  <Resource Language="en-US" />
  <Resource Language="es" />
  <Resource Language="fr-FR" />
</Resources>

Android

Android picks up .resx-based localization automatically. No additional manifest entries required. ✅

Runtime language switching — x:Static trap

<!-- ❌ Won't update when language changes at runtime -->
<Label Text="{x:Static resx:AppResources.WelcomeMessage}" />

<!-- ✅ Updates dynamically via INotifyPropertyChanged -->
<Label Text="{Binding [WelcomeMessage], Source={x:Static local:LocalizationResourceManager.Instance}}" />

When switching culture, set all three properties or formatting is inconsistent:

// ✅ Complete culture switch
var culture = new CultureInfo("es");
CultureInfo.CurrentUICulture = culture;  // resource lookup
CultureInfo.CurrentCulture = culture;     // dates/numbers
AppResources.Culture = culture;           // ResourceManager

// ❌ Only sets UI culture — dates/numbers stay in old culture
CultureInfo.CurrentUICulture = new CultureInfo("es");

RTL layout — set FlowDirection at page level

<!-- ✅ Page-level — children inherit -->
<ContentPage FlowDirection="RightToLeft">
  <StackLayout FlowDirection="MatchParent" />
</ContentPage>

<!-- ❌ Only on child — parent still LTR, layout breaks -->
<ContentPage>
  <StackLayout FlowDirection="RightToLeft" />
</ContentPage>

VS Code pitfall

⚠️ .Designer.cs may not regenerate on save. Add to .csproj and run dotnet build after .resx changes:

<CoreCompileDependsOn>PrepareResources;$(CoreCompileDependsOn)</CoreCompileDependsOn>

Decision framework

Need Approach
Static multilingual strings .resx files with x:Static bindings
Runtime language switching LocalizationResourceManager with INotifyPropertyChanged bindings
Culture-specific images Name images banner_{culture}.png or store paths in .resx
RTL support Set FlowDirection at page level, detect with TextInfo.IsRightToLeft
Date/number formatting Set CultureInfo.CurrentCulture alongside CurrentUICulture

Quick checklist

  • NeutralLanguage set in .csproj
  • Default AppResources.resx contains all keys
  • Each target language has its own AppResources.{culture}.resx
  • iOS/Mac: CFBundleLocalizations lists all supported languages
  • Windows: Package.appxmanifest declares <Resource Language="..." />
  • RTL cultures set FlowDirection at page/app level
  • Runtime switching sets all three: CurrentUICulture, CurrentCulture, AppResources.Culture
  • dotnet build regenerates .Designer.cs after .resx changes