Working with String Catalogs in iOS projects
Practical tips, limitations, and best practices for localization with .xcstrings files.
16 Mar 2026 · 6 min read
Localization is an essential part of many iOS apps. Prior to String Catalogs, developers managed localized strings using Localizable.strings and Localizable.stringsdict files. While this approach works well, it requires manual maintenance and can easily lead to missing or outdated localization keys.
String Catalogs simplify this workflow by integrating localization management directly into Xcode. In this article, we'll look at how String Catalogs work in practice. Let's jump right in.

What is a String Catalog?
A String Catalog is a file with the extension .xcstrings, typically named Localizable.xcstrings.
Contrary to Localizable.strings and Localizable.stringdict files, a String Catalog manages all translations in a single structured file. Inside Xcode, the catalog provides a dedicated editor where we can view and manage all localized strings across supported languages.
Internally, a String Catalog is stored as JSON. A simplified example might look like this:
{"sourceLanguage": "en","strings": {"loginButton.title": {"localizations": {"de": {"stringUnit": {"state": "translated","value": "Einloggen"}},"en": {"stringUnit": {"state": "translated","value": "Login"}}}}},"version": "1.0"}
Automatic detection of localizable strings
One of the most convenient features of String Catalogs is Xcode's automatic detection of localized strings.
Whenever the project is built, Xcode scans the codebase for known localization APIs and automatically adds detected keys to the String Catalog.
For example, when using SwiftUI's Text view with Text("loginButton.title"), Xcode automatically creates a new entry for us.
Once the entry is created, translations can be added directly in the catalog editor.
For cases where localized strings need to be passed around in code, the LocalizedStringResource type can be used to maintain automatic detection.
Manual management of localized strings
In some cases, Xcode cannot detect keys, for example when they are constructed dynamically:
Text("loginButton." + state)
Since Xcode cannot determine the final key during compilation, these strings will not appear automatically in the String Catalog. In such cases, entries must be added manually.
When we switch an entry to manual management, Xcode will no longer modify or remove it automatically.
Manual management can be useful when:
- localization keys are generated dynamically
- strings are shared across multiple modules
- keys are intentionally kept even if not currently referenced in code
Understanding String Catalog states
String Catalog entries can appear in different states depending on how they are used in the project. For example:
- new - the string was detected but has not yet been translated.
- needs_review - indicates that a translation should be checked again.
- stale - the string is no longer referenced in the code.
- translated - all required translations are available.
When Xcode marks an entry as stale, it means the key is no longer detected in the codebase.
At this point, the entry can either be removed or switched to manual management.
The needs_review state can be set manually to indicate that a translation should be checked again, for example when the source text changes:
Practical tip: renaming localization keys
When working with localization keys, it's common that naming conventions evolve over time. For example, we might decide to rename a key like loginButton.title to something more structured such as login.button.title.
A straightforward approach would be to simply update the key in the codebase:
Text("login.button.title")
However, when doing this, Xcode treats the new key as a completely new entry. The old key will be marked as stale, while the new key appears as new.
This means all translations associated with the old key would need to be copied manually to the new one.
A more practical approach is to rename the key directly in the String Catalog editor in Xcode. When renaming a key from within the catalog, Xcode updates the references in the codebase automatically while keeping the existing translations intact:
This allows us to refactor localization keys without losing translations or creating duplicate entries.



Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips



