How to Localize Your iOS App: A Complete .xcstrings Guide
Localization is one of the most effective ways to grow your iOS app's user base. Apps available in multiple languages see significantly higher downloads in non-English markets. Yet many developers put off localization because the process feels complex and time-consuming.
With Xcode 15+, Apple introduced String Catalogs (.xcstrings files), replacing the older .strings and .stringsdict formats. This modern format makes iOS localization much more manageable. In this guide, we'll walk through everything you need to know.
What is a .xcstrings file?
A .xcstrings file (also called a Xcode String Catalog) is a JSON-based file that Xcode uses to manage all translatable strings in your iOS app. It replaces the older Localizable.strings and Localizable.stringsdict files with a single, unified format.
Key advantages of .xcstrings over legacy formats:
- Single file for all languages instead of separate files per language
- Built-in plural support without needing
.stringsdict - Automatic string extraction from SwiftUI and UIKit code
- Translation state tracking (translated, needs review, stale)
- JSON format that's easy to parse and integrate with translation tools
Setting up localization in Xcode
Step 1: Create a String Catalog
In Xcode, go to File > New > File and select String Catalog. Name it Localizable.xcstrings and add it to your target.
Step 2: Add target languages
Open your project settings, go to the Info tab, and click the + button under Localizations to add languages. Common choices include French, German, Spanish, Japanese, and Simplified Chinese.
Step 3: Use localized strings in your code
In SwiftUI, strings are automatically localized:
Text("Welcome back") // Automatically uses Localizable.xcstrings
Text("items_count \(count)") // Supports string interpolation
In UIKit, use NSLocalizedString:
let title = NSLocalizedString("welcome_title", comment: "Welcome screen title")
Step 4: Build your project
After building, Xcode automatically extracts all localizable strings and adds them to your .xcstrings file. You'll see them in the String Catalog editor.
Handling plurals
One of the biggest improvements in .xcstrings is native plural support. Instead of maintaining a separate .stringsdict file, you can handle plurals directly.
In your Swift code:
Text("^[\(count) item](inflect: true)")
The .xcstrings file stores plural variants for each language automatically. Different languages have different plural rules — English has two forms (one, other), while Arabic has six (zero, one, two, few, many, other).
Translation workflow
Once your strings are extracted, you need to translate them. Here are the common approaches:
Manual translation in Xcode
You can translate strings directly in Xcode's String Catalog editor. This works for small projects but doesn't scale well.
Export/Import with XLIFF
Xcode supports exporting to XLIFF format for professional translation services. Go to Product > Export Localizations.
Using a localization tool
For the fastest workflow, use a dedicated iOS localization tool like Localizable. The process is simple:
- Upload your
.xcstringsfile - Select target languages
- Translate instantly with AI
- Review translations with your team
- Download the translated
.xcstringsfile - Replace it in your Xcode project
This approach preserves all placeholders (%@, %d), plural rules, and metadata — so you get a production-ready file without manual work.
Best practices for iOS localization
1. Use meaningful keys
Prefer descriptive keys over using the source text as the key:
// Good
NSLocalizedString("onboarding.welcome.title", comment: "")
// Less ideal (harder to manage at scale)
NSLocalizedString("Welcome to our app!", comment: "")
2. Provide context with comments
Translation context helps translators make accurate choices:
NSLocalizedString("book", comment: "Verb - as in 'book a reservation'")
NSLocalizedString("book", comment: "Noun - as in 'a library book'")
3. Don't concatenate strings
String concatenation breaks in many languages because word order varies:
// Bad - word order differs across languages
let msg = greeting + " " + name
// Good - use a single string with placeholder
String(format: NSLocalizedString("greeting_name %@", comment: ""), name)
4. Test with pseudolocalization
Before sending strings for translation, test your UI with longer strings. German text is typically 30% longer than English, and some languages are even longer. Make sure your layouts handle text expansion.
5. Handle right-to-left languages
If you support Arabic or Hebrew, test your entire UI for RTL layout. SwiftUI handles most RTL adjustments automatically, but custom layouts may need attention.
Quality assurance
After translating, always check for:
- Placeholder mismatches — every
%@or%din the source must appear in the translation - Length issues — translations that are too long may break your UI
- Missing translations — untranslated strings fall back to the development language
- Consistency — the same term should be translated the same way throughout the app
Tools like Localizable run these QA checks automatically, flagging issues before they reach production.
Conclusion
Localizing your iOS app with .xcstrings is more straightforward than ever. The String Catalog format simplifies the process, and with the right tools, you can go from a single-language app to a fully localized one in minutes instead of days.
Ready to localize your iOS app? Get started with Localizable — upload your .xcstrings file and translate instantly.