Skip to main content

Metadata Localization

Generate localized ASO text metadata — name, subtitle, keywords, description for iOS and title, short_description, full_description for Android — directly into Fastlane-compatible locale folders.

This is a skill-driven workflow: it runs through the Claude Code skill (kappmaker:kappmaker), not as a kappmaker shell command. Claude reads your en-US source files, applies the ASO strategy you pick, and writes the localized output files directly. No API key is required — all generation happens in the model conversation.

Two modes

You pick the mode explicitly; the workflow never mixes them. See ASO Guidelines for the strategy trade-off.

ModeOutput languageLocalesUse case
keyword-expansionEnglish in all 9 foldersFixed set of 9 US-indexed localesMaximize unique keyword surface in the US App Store
market-localizationNative per localeWhatever locales you listAdapt copy for users in each target market

Triggers

Invoke from any Claude Code session by mentioning the skill in your message. Examples:

Using kappmaker, localize metadata mode=keyword-expansion keywords="drift coach, lap timer, ai car tuner, ghost lap, apex finder, suspension setup, track day app, racing line, telemetry analyzer, sector times"

Using kappmaker, localize metadata mode=market-localization base=en-US locales="de-DE, fr-FR, ja, es-ES"

Using kappmaker, localize metadata mode=market-localization

The skill router also picks up shorter phrasings like "localize aso", "localize metadata", and "aso keyword expansion".

Output layout

PlatformPath
iOSMobileApp/distribution/ios/appstore_metadata/texts/<iosLocale>/{name,subtitle,keywords,description}.txt
AndroidMobileApp/distribution/android/playstore_metadata/<playLocale>/{title,short_description,full_description}.txt

The iOS layout uses a literal texts/ subfolder. This is intentional — it's KAppMaker's chosen convention and is NOT standard Fastlane deliver layout (Fastlane expects <locale>/ directly under appstore_metadata/). Bridge to Fastlane with a small sync step in your release pipeline, or upload the text files via the App Store Connect API directly.

en-US (or your chosen base locale) is never overwritten once it exists.

Mode 1 — Keyword Expansion

Using kappmaker, localize metadata mode=keyword-expansion keywords="<10–15 target keywords, comma-separated>"

Locale set (fixed)

The 9 US-indexed locales. You don't choose these — they're the locales the US App Store indexes alongside en-US.

iOS folderPlay folder
ar-SAar
fr-FRfr-FR
koko-KR
pt-BRpt-BR
ruru-RU
vivi
zh-Hanszh-CN
zh-Hantzh-TW
es-MXes-MX

Behavior

  • Reads en-US as the source of truth (app voice, value prop, tone). If en-US doesn't exist, the workflow prompts for a 1–2 sentence app description and bootstraps en-US first — see Bootstrap behavior below. Never fails because the base is missing.
  • Distributes your target keywords across the 9 locales by semantic cluster (e.g. "design" keywords to one locale, "AI" keywords to another) so each locale stays coherent and searchable.
  • Generates fresh English content in each locale's 4 iOS files and 3 Android files (63 files total).
  • The iOS description.txt per locale is freshly written to naturally embed that locale's assigned keywords — it's not translated and not copy-pasted from en-US.
  • Always overwrites the 9 locales without prompting (only en-US is protected).

Uniqueness rules

  • Within a locale (hard): zero word overlap across name, subtitle, and keywords. Apple does not re-index a word from name/subtitle when it also appears in keywords — it's wasted space.
  • Across the 9 locales (preferred): every keyword appears in exactly one locale, so each one indexes a different surface. When the strong-keyword pool is exhausted, high-value keywords may repeat across locales rather than padding with weak filler.

Summary table

After the run completes, the workflow prints a table:

| Locale (iOS / Play) | name | sub | kw | desc | title | short | full |
|---------------------|-----:|----:|---:|-----:|------:|------:|-----:|
| ar-SA / ar | 28 | 27 | 96 | 712 | 29 | 78 | 1840 |
| fr-FR / fr-FR | 27 | 29 | 99 | 685 | 28 | 80 | 1925 |
| ...

Any cell at ≥ 95% of its cap is flagged.

Mode 2 — Market Localization

Using kappmaker, localize metadata mode=market-localization base=en-US locales="de-DE, fr-FR, ja, es-ES"

Required arguments

  • mode=market-localization
  • locales= — comma- or space-separated list of locale codes, OR a named preset (see below). No silent autodetect.
  • base= — optional, defaults to en-US. The base locale is the source of truth for app voice and value prop.

Locale presets

Instead of typing locale codes, you can use named presets and the workflow expands them:

Preset (any phrase containing these words)Locales
top 10 / tier 1 / essential / essentialsde-DE, fr-FR, es-ES, es-MX, ja, ko, zh-Hans, pt-BR, ru, it
top 15 / tier 2Tier 1 + nl-NL, tr-TR, ar-SA, pl, zh-Hant
top 20 / tier 3Tier 2 + hi, id, vi, th, fr-CA
all / every locale / all supported localesAll 30 entries from the supported codes table below
European / EU marketsde-DE, fr-FR, es-ES, it, nl-NL, pt-BR, pl, ru, tr-TR, sv, da, no, fi, el, cs, hu, ro, uk
East Asiaja, ko, zh-Hans, zh-Hant
Southeast Asia / SEAid, ms, th, vi
Spanishes-ES, es-MX
Chinesezh-Hans, zh-Hant
MENA / Arabicar-SA

Combiners are recognized too — e.g. top 10 plus hi and id, tier 1 markets but skip ru and zh-Hans. The workflow shows you the expanded list and asks for confirmation before generating, so you can sanity-check it.

Which preset? top 10 is the right default for paid utilities and B2C SaaS — those markets concentrate App Store / Play Store revenue. top 15 adds the next EU + MENA + Eastern Europe layer. top 20 is the better default if you're Android-heavy and target South / Southeast Asia. all is rarely the right call unless you're a free game with very broad appeal — localizing well costs effort even when the workflow handles the typing.

Behavior

  • Reads the base locale and adapts each target locale's copy to local search behavior, locally trending keywords, and the cultural framing of the value proposition.
  • The output is NOT a literal translation. Word order, idioms, and the lead value claim may differ entirely between locales when local search intent differs.
  • Front-loads the primary keyword in name / title (left = stronger ranking weight).
  • iOS keywords.txt per locale never repeats words from that locale's name or subtitle.

Existing-files protection

If any target locale already has any of the expected files on disk, the workflow prompts ONCE:

Found existing metadata in N locale(s): de-DE, fr-FR.
Overwrite ALL existing metadata? [y/N]
  • N (or Enter) → skips those locales, continues with the rest (or exits with "No locales to generate, exiting." if the list becomes empty).
  • y → regenerates all targeted locales.

Supported locale codes

Pass any of these in locales=. The workflow accepts either the iOS or Play form and writes to both stores using the canonical folder names below.

iOS folderPlay folderLanguage
ar-SAarArabic
cscs-CZCzech
dada-DKDanish
de-DEde-DEGerman
elel-GRGreek
es-ESes-ESSpanish (Spain)
es-MXes-MXSpanish (Mexico)
fifi-FIFinnish
fr-CA(none)French (Canada, iOS only)
fr-FRfr-FRFrench
hihi-INHindi
huhu-HUHungarian
ididIndonesian
itit-ITItalian
jaja-JPJapanese
koko-KRKorean
msmsMalay
nl-NLnl-NLDutch
nono-NONorwegian
plpl-PLPolish
pt-BRpt-BRPortuguese (Brazil)
roroRomanian
ruru-RURussian
svsv-SESwedish
ththThai
trtr-TRTurkish
ukukUkrainian
viviVietnamese
zh-Hanszh-CNChinese (Simplified)
zh-Hantzh-TWChinese (Traditional)

A code not in this table is rejected upfront — the workflow aborts with the full list printed before creating any folders. If you need a locale that's not here, ask in the skill conversation and Claude can add it.

Bootstrap behavior

If the base locale (en-US by default) doesn't have its 4 iOS files and 3 Android files filled in, the workflow does not fail. It enters bootstrap mode:

  1. Asks you to describe the app in 1–2 sentences.
  2. For Mode 1, uses that description plus your keywords= list to compose the base locale files.
  3. For Mode 2, uses just the description.
  4. Writes the missing base files first, holding them to the same field rules as the localized output (char limits, no spaces after commas, front-loaded primary keyword, etc.).
  5. Continues into the regular mode procedure with the freshly-written base as the source.

This makes the workflow usable on a fresh project where no en-US content exists yet.

What gets enforced

Every file written passes the ASO Guidelines checks:

  • All character limits (iOS: 30/30/100/4000, Android: 30/80/4000)
  • No spaces after commas in iOS keywords.txt
  • No word overlap across iOS name/subtitle/keywords within a locale
  • No brand name or filler words in iOS keywords.txt
  • Native-feel test in Mode 2 (no machine-translated phrasing)

If any output would exceed a limit, the workflow shortens it (preferring synonyms or cutting filler) and surfaces it in the summary table. The workflow never writes over-limit content.

See also

  • ASO Guidelines — character limits, keyword field rules, and the strategy trade-off explained.
  • Screenshot Translation — the image-side ASO tool. Pair the two for end-to-end localized listings.
  • Claude Code Skill — how the kappmaker:kappmaker skill is installed and invoked.