Skip to content

Localisation

As of 2026-10-19 (vulture-ios 3176c4cc4, vulture-android 85fd9cc6, vulture-web 61d304e).

The iOS String Catalogs are the single source of the app’s text. Android generates its strings from them, so nothing is translated twice. For voice, tone, form of address and the locked glossary, see the Localization style guide (apps) and Tone of voice (website).

Vulture ships 8 languages. Every catalogue is complete in all of them.

CodeLanguageiOSAndroid (values-…)Browser extensions (_locales)vulture.aero (locales/)
enEnglish (US, source)Yesvalues/YesYes
nlDutchYesYesYesYes
deGermanYesYesYesYes
frFrenchYesYesYesYes
esSpanishYesYesYesYes
csCzechYesYesYesYes
itItalianYesYesYesYes
plPolishYesYesYesYes

Slovenian is not shipped. localization-style.md plans it: Slovenian is in its translation phase list and its form-of-address table, and the plural rules mention its dual form. No String Catalog has a sl localisation, and no Android values-sl, extension _locales/sl or site locale exists (all checked on 2026-10-19). That guide’s phase list also leaves out French, which ships. Treat the code inventory above as the truth.

All catalogues are .xcstrings, with source language en.

CatalogueKeysUsed by
vulture-ios/Packages/DesignSystem/Sources/DesignSystem/Resources/Localizable.xcstrings1006All the screen packages resolve through it
vulture-ios/Modules/App/Resources/Localizable.xcstrings513The app target
vulture-ios/Modules/App/Resources/AppShortcuts.xcstrings12App Shortcuts phrases
vulture-ios/Modules/App/Resources/InfoPlist.xcstrings19Permission texts and other Info.plist strings
vulture-ios/Modules/Watch/Resources/Localizable.xcstrings, InfoPlist.xcstrings134, 7Watch app
vulture-ios/Modules/MetarWidget/Resources/Localizable.xcstrings46Widgets
vulture-ios/Modules/QuickLook/Resources/Localizable.xcstrings18Quick Look preview
vulture-ios/Modules/Clip/Resources/Localizable.xcstrings4App Clip
vulture-ios/Packages/Preferences/.../Localizable.xcstrings39Units and preferences
vulture-ios/Packages/Formatting/.../Localizable.xcstrings24Formatters
vulture-ios/Packages/LiveActivity/.../Localizable.xcstrings6Live Activity
vulture-ios/Packages/Waypoints/.../Localizable.xcstrings1Waypoints
  • Most keys are dotted semantic keys, in the form <area>.<kind>.<name>. Examples: common.button.ok, settings.labels.unit.kph, inflight.button.centerglider, file.label.import.success.title, skysight.layers.section.labels.thermals.
  • App Intents, App Shortcuts and widget strings use the English source text as the key. This is the system default for those APIs.
  • Plurals use the catalogue’s “vary by plural”. Never write “item(s)” by hand.
  • Unit abbreviations and aviation terms (METAR, TAF, QNH, AGL, FL) stay untranslated (style guide, “Do not translate”).

The tooling is vulture-android/scripts/convert_strings.py, documented in vulture-android/docs/strings.md.

Terminal window
python3 scripts/convert_strings.py --ios ../vulture-ios # regenerate
python3 scripts/convert_strings.py --verify # completeness check only (CI)

The script reads five catalogues: DesignSystem, App, Formatting, Preferences and Waypoints (the CATALOGS list). It writes vulture-android/core/designsystem/src/main/res/values*/strings_ios.xml. As of this date that file holds 1,526 strings and 22 plurals in English. The files start with a GENERATED comment. Never edit them. Change the iOS catalogue and regenerate, so both apps stay in sync.

iOSAndroid
key flight.detail.titleR.string.flight_detail_title: lower-cased, non-[a-z0-9_] characters become _, repeated _ collapse, a leading digit gets an s_ prefix, reserved words get a trailing _ (resource_name())
%@%s
%lld, %ld, %u, %i%d
two or more placeholdersPositional: %1$s, %2$d
plural variation<plurals>, read with pluralStringResource(R.plurals.x, count, count)
device variationThe iPhone variant
stale keys, empty keys, keys that are only placeholders (%@ · %@)Skipped

R is be.fousa.vulture.core.designsystem.R, because all generated strings live in :core:designsystem.

Since build 563, iOS writes menu commands and bar buttons in Apple HIG style: Title Case, with an ellipsis on a command that opens something to fill in (“Edit Flight…”). Material asks for sentence case and no ellipsis. The owner’s rule (2026-10-17, decision §17 in vulture-android/docs/decisions.md) is that the iOS HIG changes do not apply on Android.

ANDROID_WORDING in convert_strings.py maps resource names to their Android English text ("Edit flight"). It has 113 entries as of this date.

  • Only the English values/strings_ios.xml is changed. The seven translations were already sentence case in the catalogue.
  • The script fails when an entry names a key the catalogue no longer has, so the table cannot go stale.
  • Add an entry when a regeneration brings in a new Title Case button or menu string. Leave proper nouns (“Soaring Spot”, “Engine RPM”) alone.
  • Put them in the using module’s res/values/strings.xml. Settings uses strings_<area>.xml. Add all 8 locales (values-cs/ … values-pl/).
  • Strings that must not be translated get translatable="false".
  • A module with no Android-only strings has no strings.xml at all, not even an empty one (decision RA-18).
  • About 20 modules have their own strings files as of this date.
  • iOS substitutions (several plurals in one string) are converted without the plural logic. The script warns about each one. There are none today.
  • Android uses the zero plural form only in languages that have it grammatically. iOS uses it for 0 in every language. Check count == 0 in code where the zero text matters.
  • Two iOS keys can map to the same Android name (flight.not.found and Flight not found.). The script keeps the first and warns.
ChangeDo
Text in both appsEdit the iOS catalogue (all 8 languages), commit in vulture-ios, then regenerate in vulture-android
A new iOS menu or button in Title CaseAlso add an ANDROID_WORDING entry with its sentence-case English
Android-only textThe module’s strings.xml in all 8 locales
Website textvulture-web/locales/<lang>.yml, following Tone of voice
Browser extension textvulture-ios/Chrome/_locales/ and vulture-ios/Modules/Safari/Resources/_locales/