How to Localize a SwiftUI App with String Catalogs (.xcstrings)

By The strings.dev team · Last updated

Frequently asked questions

Do I need to wrap SwiftUI Text() strings in NSLocalizedString?

No. In SwiftUI, a string literal passed to Text, Button, and similar views is treated as a LocalizedStringKey automatically, so it's extracted into your String Catalog on build with no wrapper. Use String(localized:) only for strings outside a view — model code, notifications, anything that isn't a SwiftUI control — so those get extracted too.

How do strings get into the .xcstrings file?

Automatically, on build. When you build the project, Xcode scans your code for every Text, Button, and String(localized:) call and adds a row per unique string to Localizable.xcstrings, keyed by the source text. Add a new string and build to see it appear; remove one and Xcode marks the old entry stale so you can prune it. You never hand-maintain the key list.

How do I handle plurals in a String Catalog?

Interpolate the count normally in code — Text("\(itemCount) items") — then right-click the row in the String Catalog editor and choose Vary by Plural. Xcode expands the row into Unicode CLDR categories (one, other, and more where a language needs them) and the OS selects the right variation at runtime. Note that a target language may need few/many forms English never defines.

Should I use String Catalogs or the older .strings and .stringsdict files?

For new apps in Xcode 15 and later, start with String Catalogs (.xcstrings). They combine what used to require separate .strings and .stringsdict files into one visual, JSON-backed file with per-string state tracking and built-in plural and device variations. Xcode can also migrate existing .strings files into a catalog from the editor.

How do I translate all my languages at once instead of typing each cell?

Export native Xcode Localization Catalogs with Editor → Export Localizations (or xcodebuild -exportLocalizations), upload the .xcloc bundles to strings.dev, and pick your target locales — up to 52, including regional variants. It fills every empty cell and plural category in one pass and returns the same native format, which you import back via Editor → Import Localizations. The free Indie tier covers 1 language; unlimited languages is Indie Plus at $20/mo, or $10/mo billed annually.

Does this localize my App Store listing too?

No. This flow localizes in-app strings in your String Catalog only. Your App Store Connect metadata — app description, keywords, and screenshots — is translated separately in App Store Connect, not in the .xcstrings file. Keep the two tasks distinct.

Related

Localize your first language free