Localize Your App in Minutes with Localizable.xcstrings

Localize Your App in Minutes with Localizable.xcstrings

A beginner-friendly guide

Today I want to take you on a small journey into localization in Swift — using Localizable.xcstrings.

Localization is one of those topics that often feels more complicated than it actually is. With the introduction of String Catalogs, Xcode made the process much more approachable, especially for beginners.

To keep things concrete and easy to follow, we’ll work with a simple Garden app 🌱 as an example. The app itself is small, but it gives us real strings to localize and real scenarios you’re likely to encounter in your own projects.

In this post, you’ll learn how to:

  1. Add Localizable.xcstrings and a new language to an app target
  2. Localize strings in the app target
  3. Localize strings inside a Swift Package and fix missing translations using bundle: .module
  4. Work with format strings and pluralization
  5. (Bonus) Translate strings faster using ChatGPT
  6. Debug common localization issues

1. Localizable.xcstrings

First things first: to get started, we need to add a Localizable.xcstrings file to the project.
This file is Xcode’s modern way of managing localized strings and translations in one place.


How to add the file

To add a String Catalog to your app target:

1. Right click the folder where you want the file to live
(the folder doesn’t really matter, as long as the file ends up in the main app target)

2. Select New File from Template

3. Choose String Catalog and press Next

4. Choose where to save the file and make sure the app target checkbox is enabled.

Xcode will create a Localizable.xcstrings file and add it to the main bundle.


How to add a new language

Next, let’s add support for another language.

  1. Open your project settings and go to the Info tab
  2. Under Localizations, you’ll see the list of supported languages
  3. Click the + button at the bottom of the list

4. Select the language you want to add (in this example, Romanian)

Now the app supports the new language.
After building the project and opening Localizable.xcstrings, you’ll see the new language appear in the catalog — even if no strings are translated yet.

You’ll also notice that strings already used in SwiftUI start appearing automatically.
This happens when you use LocalizedStringResource, for example via Text.

You can also use it directly in your own APIs:

Text(_ resource: LocalizedStringResource)

2. Localize App target

Now that Localizable.xcstrings is set up, let’s actually translate the app.

This section covers the simplest and most common case:
localizing strings that live directly in the app target.


How to add a translation

Open Localizable.xcstrings and select the language you added.

Click on the placeholder text for a string and enter the translation.
Once you press Enter, the state changes to a checkmark.

You can also right-click on an entry to access additional options.
For example, you can mark the empty string as Don’t Translate.


How to mark a localizable string in code

Most SwiftUI components have initializers that accept a LocalizedStringResource, which makes localization effortless.

If you need to define a string manually, you can do so using:

String(localized: "Text")

This marks the string as localizable for the compiler.

Another option is the older API:

NSLocalizedString("Text", comment: "")

Result

English:

Romanian:


3. Localize strings inside a Swift Package

Everything looks good so far — until we try to plant a tree.

You’ll notice that the navigation title isn’t translated.
That’s because this screen lives inside a Swift Package, not the main app target.

Let’s fix that.


How to add Localizable.xcstrings to a Swift Package

The process is very similar to the app target, with one extra step.
1. Right click the Swift Package folder
2. Choose New File from Template, then select String Catalog

3. Add a .resources parameter to the package target so the file is copied into the module bundle


4. Build the project — the package’s Localizable.xcstrings should now include strings from SwiftUI usage


Translations don’t show up in the app only identifiers, or in our case english string.

This happens because the package’sLocalizable.xcstrings file is not part of the main bundle.

To fix this, you must explicitly specify the package bundle:

String(localized: "Text", bundle: .module)

For example:

// Before
.navigationTitle("Thank You")
// After
.navigationTitle(String(localized: "Thank You", bundle: .module))

And just like that — it works.


4. Work with format strings and pluralization

Now let’s look at formatted strings and pluralization.

We’ll change Seed Bank into a more informative string:

"Bank with \(seeds.count) seeds"

After doing this, open Localizable.xcstrings.
You’ll see a warning and a new entry appear.

  1. Right-click the entry and choose Vary by Plural.

Xcode will generate multiple plural variants.
In Romanian, for example, you’ll see one, few, and other.

You can safely remove the old warning entry.


Result

English

Singular:

Plural:

Romanian

Singular:

Plural:

And just like that, we localized the app in under an hour.


5. (Bonus) Translate strings fast with ChatGPT

You might have noticed that Localizable.xcstrings is essentially JSON.

You can confirm this by right-clicking the file, selecting Open As → Source Code, and viewing the raw structure.

What I usually do is copy this content and paste it into ChatGPT with the following prompt:

You are translating an Apple Localizable.xcstrings file.
Rules:
- Do NOT change keys.
- Do NOT change the file structure.
- Translate ONLY string values.
- Preserve placeholders exactly (%@, %d, %1$@, ${value}, etc.).
- Keep translations short and UI-friendly.
- Use natural, casual language.
- Return valid JSON only.
Task:
Translate all English strings into the following languages:
- ro
- es
If a string is empty, add translations for the new languages.
Here is the file:
<PASTE Localizable.xcstrings JSON HERE>

This returns valid JSON with translations filled in.
You can translate into multiple languages in a single request.


Lesson: One file vs one file per package

I once tried keeping all strings in a single “Localized” swift package.
That approach didn’t scale well — the file grew too large, and ChatGPT struggled once multiple languages were involved.

Lesson learned.

In my newer projects (like Viatza), each screen lives in its own Swift Package, with its own Localizable.xcstrings.
Smaller files are easier to review, cheaper to translate, and faster to maintain — especially for indie developers.


6. Debug common localization issues

How to debug a specific language?

Open the app scheme, go to Options, and set App Language.


Translations don’t appear in the app

Double-check that you’re using the correct bundle:

String(localized: "Text", bundle: .module)

Localizable.xcstrings stopped updating

Common causes:
• There is no Localizable.xcstrings file in the main app target
(keep an empty one if all strings live in packages)
• Localization is disabled in Build Settings

Check your app target’s Build Settings and make sure localization-related options are enabled.

Conclusion

Localizing a pet project has never been easier.
With Localizable.xcstrings, you can add new languages without introducing extra tools or complex workflows.

Once the basics are in place, localization becomes just another small, manageable part of development — even when working with Swift Packages.

If you’re planning to localize a project next, I’d love to hear about it.
And if you have any questions or run into issues, feel free to leave a comment — I’m happy to help.


Links

2 thoughts on “Localize Your App in Minutes with Localizable.xcstrings

Leave a Reply