---
title: "Translation sub-agents go brrrrrrrr"
description: "Taking your app to the world by localization"
url: "https://cuteios.dev/2026/08/17/localizations-translations/"
source: "https://cuteios.dev/2026/08/17/localizations-translations.md"
date: "2026-08-17"
author: "Amy"
site: "Amy is a cute iOS Developer"
language: "en"
license: "CC BY 4.0 (prose), MIT (code samples)"
---

# Translation sub-agents go brrrrrrrr

The world is global, diverse, amazing and filled with many many people who speak languages that aren't your native one. For me, my native language is English and it's what I think in. What I write in. What I assume the world operates in.

But that's not reality. English isn't the dominant language. It's what I use, the world doesn't. So how do I take my apps from english to other languages. There are some key components.

- Extensions on `LocalizedStringResource`
- Strings catalogue per view
- Detailed comments in strings catalogue
- Xcode 27 translation skill

### LocalizedStringResource

If you're using `defaultLocalization: "en"` then you get this for free. I rather code this in by hand so that it's a guide of what keys I need adding to the strings catalogue.

So the first thing to remember is if you're doing it by hand is remove the defaultLocalization line from the SPMs Package.swift file. If you want auto generation then just leave it in.

The structure of the extension should be similar to:
```swift
extension LocalizedStringResource {
  enum ActivitySummary {
	static let move = LocalizedStringResource(
	  "activitySummary.move",
	  table: "ActivitySummary",
	  bundle: #bundle
	)
	static let exercise = LocalizedStringResource(
	  "activitySummary.exercise",
	  table: "ActivitySummary",
	  bundle: #bundle
	)
	static let stand = LocalizedStringResource(
	  "activitySummary.stand",
	  table: "ActivitySummary",
	  bundle: #bundle
	)
	static let unknown = LocalizedStringResource(
	  "activitySummary.unknown",
	  table: "ActivitySummary",
	  bundle: #bundle
	)

	static func progress(current: String, goal: String) -> LocalizedStringResource {
	  LocalizedStringResource(
		"activitySummary.progress",
		defaultValue: "\(current) / \(goal)",
		table: "ActivitySummary",
		bundle: #bundle
	  )
	}
  }
}
```

The advantage of going for writing the `LocalizedStringResource` extensions yourself is that it gives a lot more control up front about how to structure the properties. You also give a solid example to the LLM to make sure that conventions are followed. Going for the generated option will save time but you loose the structured example for the LLM to follow.

### Strings catalogue per view

Just as your `LocalizedStringResource` has extensions and a structure that matches the view, so should your strings catalogue. This breaks apart what could be a very large and complex strings catalogue into something that is human parsable and has a low cognitive overhead.

The advantages there are also for the LLMs in that it provides a solid structure for it to follow. It will spend less tokens trying to determine what is going on.

### Detailed comments in strings catalogue

Again, this helps with providing context to the readers and LLMs so they are able to determine an exact translation rather than trying to guess.

Using a coding agent in Xcode makes generating the comments straight forward. Just write a prompt and have the coding agent exicute it.

### Xcode 27 translation skill

Xcode 27 introduced some amazing skills that developers can make use of. This includes a translation skill that knows how to use sub-agents to get the values it requires.

Go and watch this excelent video from WWDC 2026 about [Translate your app using agents in Xcode](https://developer.apple.com/videos/play/wwdc2026/213).

### Verifying the Output

Making use of a SwiftUI preview is the easiest way to see just how a language is responding to the app code.

All up, this is fun and a great challenge to think through wording, meaning, value, et cetera as you do.

The output speaks for itself. This is an updated onboarding screen from [RideJournal](https://ridejournal.app)

![RideJournal onboarding screen localized into Japanese](https://cuteios.dev/assets/images/localizations-translations/japanese.png)
