# App Store Aso

> Методология ASO для App Store — метаданные, ключевые слова, локали, замеры. Использовать всякий раз, когда работа касается видимости приложения в App Store, даже если слово «ASO» не прозвучало — подбор ключей, сборка или правка Name/Subtitle/Keywords, решение открывать ли локаль, разбор выгрузок App Store Connect или ASO-сервисов (ASO Mobile, AppTweak, AppFollow), диагностика «почему нет показов/загрузок в стране X». Use whenever the user works on App Store search visibility, even without the word "ASO" — keyword research, Name/Subtitle/Keywords fields, App Store Connect impressions/downloads analysis, store locale decisions, autosuggest research, or "why does my app get no impressions in country X". App Store only; Google Play works differently / Только App Store.

- Skill: `muxxik/app-store-aso` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add muxxik/app-store-aso`
- Raw SKILL.md: https://api.skillmd.com/api/skills/muxxik/app-store-aso/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: Muxxik (https://skillmd.com/u/muxxik)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/muxxik/app-store-aso

---


# ASO для App Store

Метод, собранный на реальных замерах. Скрипты в `scripts/` работают без платных сервисов.

## Главное правило

**Диагноз до решений.** Прежде чем менять слова, ответь на три вопроса по данным, а не по интуиции:

1. Есть ли в этой стране спрос? — индекс Search Ads + показы из ASC с разбивкой по источнику
2. Видят ли нас? — позиции по ключам с подтверждённым спросом
3. Выбирают ли нас, когда видят? — конверсия показ→загрузка против других стран

Провал на каждом уровне лечится по-разному, и лечить второй, когда сломан первый, бесполезно.

## Модель индексации

- **Фраза собирается только из токенов ОДНОЙ локали.** Name + Subtitle + Keywords одной локали комбинируются между собой; токены разных локалей — никогда. Если фраза «счетчик отношений» нужна целиком, оба слова должны лежать в одной локали.
- **На страну индексируется несколько локалей.** Каждая дополнительная — это ещё 100 символов ключей и своя пара Name/Subtitle. Карта в `references/locales.md`.
- **Вес Name и Subtitle заметно выше keywords.** Проверено: приложение с фразой в имени обошло лидера рынка, у которого её в имени не было. Отсюда правило — в имя ставится фраза с наибольшим трафиком, а не самая красивая.
- **Слитная и раздельная формы — разные токены.** `breakup` не матчит «break up», `getover` не матчит «get over». Разносить на токены; при необходимости держать обе формы (одну в имени, другую в ключах).
- **Диакритика — НЕ разные токены: Apple её нормализует.** «corazon» в keywords матчит запрос «corazón roto» — проверено тройно (идентичная выдача по обеим формам, автосаджест канонизирует префикс без акцента в форму с акцентом, одинаковые позиции в ASO Mobile). В keywords достаточно одной формы — акцентированную не дублировать. Внимание: ASO-сервисы считают формы разными ключами — в трекинге не плодить строки-дубли.
- **Региональные варианты написания — тоже разные токены.** `defence` не матчит «defense»: в американском сторе с британским написанием в сабтайтле ранжируешься по «tower defence» и невидим по «tower defense», которым там ищут. Правило: американская форма — в en-US, британская — в en-GB (он индексируется в Европе, где печатают по-британски).
- **Дубли внутри одной страны сжигают слот.** Слово, уже индексируемое через другую локаль этой же страны, повторять бессмысленно — кроме намеренного повтора ради точной фразы в Name.
- **Пунктуация в Name не влияет на токены.** «No Contact Tracker: Break Up» и «No Contact Tracker — Break Up» дают одинаковый набор токенов — Apple игнорирует знаки при разбиении. Практическое следствие: ASC отклоняет имя, совпадающее с существующим приложением (коллизия имён), — меняй пунктуацию, индексация не пострадает.
- Метаданные применяются **только с новой версией**, а версия требует нового билда. Значит все правки копятся в одну отправку, иначе лишний круг ревью.

## Метрики: как их не переврать

Подробно в `references/metrics.md`. Кратко:

- **Индекс популярности Search Ads (5–100)** — метрика Apple, самый честный сигнал спроса. 5 — это пол. **Нельзя сравнивать между сторами одним порогом:** он относительный к объёму стора, и в небольшой стране настоящий спрос выглядит как 5–8. Сравнивай внутри страны с местным эталоном (например, с самым общим словом ниши).
- **Прочерк ≠ ноль.** Означает «данных нет». Свежедобавленные ключи заполняются не сразу; и сервис может вовсе не знать термина — если приложение, названное словом X, не показывает X среди своих ключей, термина просто нет в корпусе.
- **Всегда чисти брендовые коллизии.** В любой выгрузке верх списка займут чужие приложения, зацепившиеся за общий токен. Это шум, не рынок.
- **Показы из ASC — единственная твёрдая опора, но только с разбивкой по источнику.** Показы из подборок маскируются под спрос. Нужен фильтр «Поиск в App Store».
- **Платформенные события дают ступеньку во всех сторах разом.** Тест: если показы скакнули в один день в нескольких несвязанных странах, а загрузки не выросли пропорционально — это не твой результат. Проверь дату релиза iOS. Такую ступеньку нужно исключить из сравнения до/после.
- **Эффект метаданных меряется только на чистом периоде** — от даты релиза до первого внешнего события.

## Порядок работы

У каждого шага указана его ловушка — шаг без неё не закрыт.

1. **Базлайн до изменений.** Позиции по ключам + показы/загрузки из ASC по странам и источникам. Без него измерить эффект нечем.
   *Ловушка:* в периоде может сидеть платформенное событие — сразу прогони `scripts/analyze.py event <показы_по_странам> <загрузки_по_странам>`; найденную ступеньку исключи из базлайна и запиши дату.
2. **Сбор ключей у конкурентов.** Настоящие ключи берутся из выдачи тех, кто уже ранжируется, а не угадываются. Инструмент типа App Keywords / Spy Explorer в ASO-сервисе; бесплатный заменитель — автосаджест плюс разбор названий конкурентов (`store-query.sh apps`, затем `lookup` по ID).
   *Ловушка:* верх любой выгрузки — чужие приложения на общем токене; чисти брендовые коллизии до анализа.
3. **Автосаджест по стору** (`scripts/store-query.sh suggest <страна> "<префикс>"`) — Apple подсказывает то, что люди реально печатают. Локализованные гибриды в подсказках («no contact gratis», «no contact kostenlos») — прямое доказательство, что в стране ищут смесь английского и местного.
   *Ловушки:* пауза 15–20 с между запросами; на непроверенном ID стора пустой ответ неотличим от лимита — сначала контрольный запрос заведомо популярного префикса `what`.
4. **Сборка полей** с подсчётом символов, без дублей внутри страны. Keywords добивать до ~100 символов в каждой локали: незанятые символы — подаренная индексация. Пакет — в файл формата `[локаль] / name: / subtitle: / keywords:` и обязательно через `scripts/validate-fields.py`: лимиты, недобор, синтаксис keywords, дубли внутри локали и между локалями одной страны руками не ловятся.
   *Ловушка:* валидатор находит дубли и в собранном «начисто» пакете — прогон не формальность.
5. **Отправка одной версией.** Метаданные применяются только с новым билдом — копи все правки в одну отправку.
   *Ловушка:* через 2–3 дня после релиза прогони `store-query.sh live` по каждой стране — поля могут молча не сохраниться. Реальный случай: в пяти новых локалях в стор уехали keywords, description и скриншоты, а Name/Subtitle остались на фолбэке основного языка, и ASC этого никак не показал. Если такое случилось — окно до фикса читай как «вклад одних кейвордов без вклада имени», это непрошеный, но полезный замер веса полей.
   Тем же заходом сними срез позиций по новым фразам — измеришь скорость индексации, а не только факт доставки полей (замерено пока только «≤7 дней»: через неделю фразы из новых Name стояли в топ-10, раньше не проверяли).
6. **Замер через 3–4 недели.** Индексация занимает дни, эффект копится недели.
   *Ловушка:* перед сравнением до/после — снова `analyze.py event` на свежей выгрузке: событие могло случиться уже после релиза и надуть «твой» рост.

## Решение об открытии локали

Критерий — **есть ли у ниши собственный термин со своей экосистемой приложений**. Проверяется за десять минут: автосаджест по стору плюс поиск конкурентов (`scripts/store-query.sh apps`). Если в выдаче несколько приложений с местным термином в названии — термин живой.

Примеры из практики: во французском это «silence radio», в испанском «contacto cero», в португальском «contato zero», в немецком «Kontaktsperre» — вокруг каждого своя группа приложений. Там, где местного термина нет и в подсказках только английский, локаль даст меньше.

**Находки не переносятся между рынками — даже родственными.** Каждую страну исследуй с нуля, перенос по аналогии проваливается систематически. Реальные замеры одной ниши: испанское слово-жила (индекс 72–74 в Испании и Мексике) не имеет аналога ни в Бразилии, ни в Германии, ни в Италии; соотношение английского термина к лучшему местному — Франция ~1:1, Германия 16:1, Италия 103:1 — три разных стратегии Name в одной языковой семье. Испания и Мексика — разные локали с разными живыми словами (duelo живо в MX и мертво в ES), хотя конкуренты льют туда один набор.

**Локаль работает на две вещи сразу, и вторая часто важнее:**

- индексация — дополнительные 100 символов и местные запросы;
- **конверсия** — пользователь, видящий в своём сторе приложение с названием на своём языке рядом с англоязычным, склоняется к первому. Поэтому переводим, а не оставляем англоязычную витрину «потому что ключи английские».

**Паттерн гибридного имени:** английский якорь + локальный термин, например `No Contact : Silence Radio`. Английская часть ловит запросы на английском (их в Европе много), локальная — местные и продаёт тап.

**Английские токены дублируй в основную локаль стора**, даже если они уже приходят через en-GB. Секондари-локаль индексируется, но вес основной предположительно выше — см. открытые гипотезы ниже.

## Открытые гипотезы — проверять, а не принимать на веру

Это не установленные факты. Помечай их как гипотезы в рабочих файлах и ставь критерий проверки заранее, иначе через месяц забудешь, что именно проверял.

**Гипотеза 1. Вес основной локали выше, чем вторичной.** Если слово индексируется в стране только через вторичную локаль, приложение ранжируется по нему хуже, чем если бы то же слово лежало в основной. Наблюдение, породившее гипотезу: страна, где ядро ниши было только во вторичной локали, стояла вне топ-100, а соседняя, где то же ядро в основной, — в топ-10.
*Как проверять:* залить ядро в основную локаль и сравнить позиции до/после. Оговорка: слово, уже индексируемое через вторичную локаль, добавлением в основную **не меняет совпадение** — проверяется именно перевзвешивание.

**Гипотеза 2. Локальное название важнее для конверсии, чем английский якорь в Name.** Пользователь в своём сторе выбирает приложение с названием на своём языке; поэтому Name и Subtitle отдаются местным словам, а английские термины уходят в keywords.
*За:* полностью локализованный рынок конвертил почти вдвое лучше англоязычных. *Против:* английский термин может быть генерической подсказкой в этом сторе, и лидеры рынка часто держат его именно в Name.
*Как проверять:* через 3–4 недели после релиза посмотреть позиции по английскому термину в этом сторе. Не выросли — переносить якорь в Name следующей итерацией, жертвуя частью местных слов.

**Правило для обеих:** одна итерация — одна проверяемая гипотеза на локаль. Если поменять и Name, и keywords, и локаль сразу, причину результата установить будет нельзя.

**Предупреждение о рассинхроне:** если витрина переведена, а интерфейс приложения нет, пользователь получает не то, что ожидал. Либо локализуй интерфейс, либо осознанно принимай просадку удержания.

**Не путай невидимость с отсутствием спроса.** Ноль показов в стране, где у тебя нет ни одного местного слова, не доказывает, что спроса нет — доказывает, что тебя не по чему найти. Различить можно только индексом Search Ads по местным терминам.

## Скрипты

- `scripts/store-query.sh suggest <страна|storefrontId> "<префикс>"` — автосаджест App Store (принимает код страны: us, de, jp…)
- `scripts/store-query.sh apps <country> "<запрос>"` — приложения в выдаче стора с ID и названиями
- `scripts/store-query.sh live <appId> <country...>` — что реально живёт в сторе, включая сабтайтл из HTML витрины (проверка, что метаданные доехали; если вместо сабтайтла жанр — локаль в стране не заполнена, стор подставил своё)
- `scripts/analyze.py asc <csv...>` — разбор выгрузок ASC: агрегация по периодам, конверсии, рейтинг стран
- `scripts/analyze.py event <показы_по_странам.csv> [загрузки.csv]` — поиск платформенных событий: ступенька показов сразу в нескольких странах без роста загрузок. Запускать ДО любого сравнения до/после
- `scripts/validate-fields.py <файл-полей>` — проверка пакета метаданных перед отправкой: лимиты, синтаксис keywords, пустой Subtitle, дубли внутри локали и между локалями одной страны (формат файла — в докстринге скрипта)
- `scripts/analyze.py xlsx <file>` — чтение xlsx без внешних библиотек

⚠️ У автосаджеста жёсткие лимиты: **пауза 15–20 секунд между запросами**, иначе Apple молча отдаёт пустой ответ, который легко принять за «ничего не находится».

## Антипаттерны

- **Оптимизировать имя под фразу с нулевым трафиком.** Проверяй индекс до того, как отдать ей 30 символов, а не после.
- **Читать «мало показов» как «нет спроса»** там, где нет местных слов.
- **Принимать поведение конкурентов за доказательство.** То, что лидеры не пришли в страну, может быть их упущением, а не приговором рынку — у них другой масштаб и другие приоритеты.
- **Слитные ключи**, не совпадающие с раздельными запросами.
- **Токены одной фразы в разных локалях** — фраза не соберётся.
- **Пустой Subtitle.** Стор подставит вместо него жанр, а 30 символов индексации сгорят. Проверяй, что поле реально сохранилось.
- **Сравнивать индекс Search Ads между странами** по одному порогу.
- **Мерить эффект на периоде, куда попало внешнее событие.**
- **Брать слово по индексу, не проверив интент.** Высокий индекс может целиком принадлежать чужому смыслу: separazione — юридический развод, superar в Бразилии — курсы от страха летать, Herz* в немецком сторе — пульсометры, saudade — радиостанции, relationship tracker — приложения для пар. Проверка за минуту: выдача стора по слову (`store-query.sh apps`) — если топ занят чужим интентом, конверсии не будет, какой бы ни был индекс.

