The Business Reality4 min read

The App Spoke 14 Languages and the Store Spoke One. Another App Was the Reverse

I sat down to improve the store listings on 14 Android apps and realised there was a prior question: how many languages does each app actually speak? Putting the app's locale list next to the store's showed the gap runs both ways, and only one direction is cheap to fix.

#i18n#aso#android#audit
Two columns: what the app speaks on the left, what the store speaks on the right. The top row is an app with 14 locales against a store with one. The bottom row is the reverse, an app with two against a store with 17. A double-headed arrow sits between them.
One app had already paid for translation and never registered it. Another advertises in languages it cannot speak.

Have you ever written the number of languages your app supports next to the number of languages your store page exists in?

I hadn't. I sat down to improve listing copy and realised those two numbers had to be written first. Two of 14 apps were mismatched — in opposite directions.

A two-line comparison

The app's language count comes from counting resource folders. The store's comes from the listing API.

app_locales   = count(res/values-*) + 1     # values is the default language
store_locales = len(listing_api.locales())

One caveat: Android resource qualifiers are not standard language codes. Indonesian is in (not id); Chinese is zh-rCN / zh-rTW. Compare them directly against store codes and you invent mismatches that don't exist.

And if the build pins a language list (resConfigs), adding a folder does nothing. Check that before you compare anything.

The gap ran both ways

Twelve of 14 apps matched. The other two were opposites.

One app had all 14 languages in resources and exactly one store listing. Users in 13 markets were seeing an English-only store page for an app that already speaks their language.

That's a pure loss. The translation was already paid for; only the registration was missing. The fix costs approximately nothing.

The other app had two languages in resources and 17 store listings. It advertises in 15 markets in their language, and when you install it an English app opens.

That direction is worse. Installs go up while ratings and retention go down. And deleting listings is not the fix — translating the app is. Delete them and traffic drops immediately; translating is separate work.

Which one would you do first?

The two directions have completely different cost structures.

Direction Loss Cost to fix
App 14 / store 1 No discovery path Three strings × 13 locales
App 2 / store 17 Ratings and retention Translating the app into 15 languages

One helpful fact: the Android store needs no new build and no screenshots to add a listing language. Title, short description and full description are enough; graphics fall back to the default language.

Apple is the opposite. Create a new locale and the screenshot set appears empty, which blocks submission outright. That's the family the empty Japanese screenshots belonged to — the assets existed, the pipeline just never asked for that locale.

One API trap

The listing update API is a full replace.

# Dangerous — unspecified fields get erased
update_listing(locale="de-DE", full_description=new_body)
 
# Safe — read, change what you meant to, write the whole thing back
current = get_listing(locale="de-DE")
current["fullDescription"] = new_body
update_listing(locale="de-DE", **current)

A new locale requires all three fields, and if any one is empty the language is created blank. That leaves you with a page that's worse than no page.

The same property is what nearly made my deploy script overwrite live listings with stale repo values. Full-replace APIs revert things silently.

Three-line self-check

  1. Can you state, right now, how many languages your app speaks and how many your store speaks? If not, one of the two is probably wrong.
  2. Have you separated the direction of the mismatch? One direction is free to fix and the other needs a translation budget. Bundling both as "inconsistent" produces no plan.
  3. Are you comparing resource qualifiers to store locale codes directly? in/id and zh-rCN/zh-Hans generate phantom mismatches.

The honest part

Whether the app that gained 13 listings gained installs, I don't know yet. Store search takes time to reflect changes, and that app has low install volume to begin with, so a signal above noise needs several weeks.

The other direction (app 2 / store 17) I did not fix. Cutting listings drops traffic immediately, and translating the app is separate work. Which side to take is a decision that needs more numbers, so I left it. In other words, this post has one item deliberately left unresolved.

And the resource folder count means "a translation exists," not "the translation is complete." A single key creates the folder. This comparison never looked inside — an app with folders present and half its strings still English passes this check.

If you ship several apps, write ls res/values-* | wc -l next to your store's listing locale count today. If the numbers differ, start by asking which direction.

Related