docs: review all

This commit is contained in:
2026-10-04 07:18:50 +05:00
parent 8cb3f1a8f0
commit 1d337f065b
21 changed files with 696 additions and 495 deletions
+58 -37
View File
@@ -24,8 +24,9 @@
> схему сайта они не меняют.
>
> **Слаги в этом документе:** `jpg-to-png`, `crop-jpeg` и подобное — интенты и
> URL конкурента, а не id наших инструментов. Наши id — в `docs/tools-map.md`; в
> тексте ниже реальные id инструментов приводятся в бэктиках.
> URL конкурента, а не наши страницы. Наши страницы — в `docs/tools-map.md`
> (карта перечисляет `slug`, не `id`); в тексте ниже названия инструментов
> приводятся по этим слагам, потому что для SEO важны адреса.
## 0. Решения
@@ -72,9 +73,14 @@
`registry/pages/`. Схему не менять без отдельного SEO-плана: после индексации
переименование URL означает 301 и потерю позиций. Разделение инструмента и
страницы (решение выше) адресов не меняет.
- **Без GA и рекламных скриптов:** аналитика — self-hosted Plausible/Umami или
Cloudflare Web Analytics. «No tracking» — часть позиционирования, её нельзя
подрывать собственными скриптами.
- **Аналитика — GA4, в режиме «только агрегаты».** GA4 уже стоит в проде
(`web/src/app.html`, prerender-оболочка, значит на каждой странице). Решение —
не выпиливать, а ограничить: cookieless-конфигурация, без рекламных audiences,
signals и ремаркетинга. Граница приватности проходит по данным изображения: GA
не видит ни файла, ни его содержимого, ни результата инструмента — только факт
открытия страницы. **Рекламу и ремаркетинг не ставим** — они противоречат
позиционированию, в отличие от счётчика посещений. Формулировку «без трекинга»
на публичных страницах не использовать: она теперь неточна, см. §1 и S4b.
- **Честные методы.** Никакого клонированного текста, дорвеев, PBN. Контент — по
каждому инструменту, с ручной вычиткой.
@@ -105,10 +111,10 @@
| `rel=canonical` | нет | S1 |
| OG/Twitter-теги, OG-картинки | нет | S1 |
| Канонический домен в абсолютных URL | нет, деплой на GitHub Pages с базой | S1 |
| Контент страницы (H1-текст, how-to, FAQ, related) | только title/description | S2 |
| Контент страницы (how-to, FAQ, related) | title, robots и отрендеренный H1 | S2 |
| JSON-LD (SoftwareApplication, FAQPage, Breadcrumb) | нет | S3 |
| `llms.txt`, хабы категорий с текстом | нет | S3 |
| GSC + приватная аналитика | нет | S4 |
| GSC + доводка GA до cookieless-конфигурации | GA4 стоит, GSC не подключён | S4 |
Строка `noindex` — первая не потому, что её сложнее всего, а потому, что она
блокирует всё остальное: пока тег стоит, остальные строки таблицы не дают
@@ -150,7 +156,7 @@
ссылок на инструменты. Но это этап S3e и только после того, как написано ядро
S2: транзакционная страница приносит конверсию, информационная — только
трафик. Тонкие FAQ-страницы «про всё» не заводить — несколько сильных
материалов с ссылками на 3–5 инструментов каждый.
материалов с ссылками на несколько связанных инструментов.
6. **Дистрибуция.** GitHub-репо (звёзды/форки = сигналы), alternative.to,
Product Hunt, Reddit по интенту — реальный путь набрать первые бэклинки без
бюджетов.
@@ -175,16 +181,20 @@
- [ ] **[S1e]** OG-картинки per-tool: генерация PNG-карточек скриптом на
существующем ядре (мы сами умеем рисовать PNG) — имя инструмента + бренд,
файл `static/og/[slug].png`, ссылка из `Seo.svelte`. Относительные пути
(`/og/crop-png.png`) работают без домена; при деплое на собственном домене
файл `static/og/[slug].png`, ссылка из `Seo.svelte`. Путь к картинке
строить через `resolve()` из `$app/paths` (как favicon в
`+layout.svelte`), а не литералом `/og/…`: под `BASE_PATH` корневой путь
ломается. Домен для этого не нужен; при деплое на собственном домене
OG-картинки будут абсолютными и корректными.
- [ ] **[S1f]** Download-кнопка с селектором формата PNG/JPG/WebP/BMP (+quality
для lossy) для всех инструментов — механика `Tool.output` уже есть
(`docs/backlog.md`, «Идеи» №6, UX-райз «Download»). Продуктовая основа
«image tools»-позиционирования: без неё сайт остаётся PNG-сайтом. Вести
параллельно с текущими quality-задачами. Побочно снимает `quality` из схем
страниц — после этого 14 convert-страниц сводятся на один инструмент
(`docs/backlog.md`).
**конвертеров** — после этого convert-страницы сводятся на один инструмент
(`docs/backlog.md`). Не из всех схем: у `jpeg-artifacts` `quality` —
функциональное поле (сила артефактов), а `output` у инструмента нет, так
что селектор формата его не покрывает.
- [ ] **[S1g]** Поведение конвертеров после S1f: не предлагать в меню форматов
формат исходника (disable) — чтобы `convert-png-to-jpg` не мог сохранить в
png. Существующие страницы не трогать: `convert-png-to-jpg`,
@@ -198,10 +208,12 @@
`https://<юзер>/<repo>/…` на корневые URL (301). Делается одновременно с
S1d (canonical), чтобы Google проиндексировал сразу с правильным доменом.
- [ ] **[S1b]** Скрипт `web/scripts/gen-sitemap.mjs`: генерирует `sitemap.xml` в
`build/` из `TOOLS` реестра (`web/src/lib/registry`) + статических
страниц. Вызов из `pnpm build` после `vite build` (adapter-static пишет в
`build/`, дописываем файл там же). Origin — из env (`PUBLIC_SITE_ORIGIN`),
учёт опционального `BASE_PATH`.
`build/` из `PAGES` реестра (`web/src/lib/registry`) + статических
страниц. Взять адреса у страниц, а не у инструментов: страниц может быть
несколько на один инструмент, у инструмента адреса нет. Вызов из
`pnpm build` после `vite build` (adapter-static пишет в `build/`,
дописываем файл там же). Origin — из env (`PUBLIC_SITE_ORIGIN`), учёт
опционального `BASE_PATH`.
- [ ] **[S1c]** `robots.txt`: `Sitemap:` + закрыть служебный `/kit`; после
cleanup — вернуть минимальный allow-all.
- [ ] **[S1d]** Компонент `Seo.svelte` (kit): canonical (абсолютный URL по
@@ -211,9 +223,9 @@
> **Порядок S1:** S1e/S1f/S1g → покупка домена → S1a+S1b+S1c+S1d → **S1h**
> (снятие `noindex`) → S2-контент. Гейты: `pnpm --dir web build` зелёный; в
> `build/` лежит корректный `sitemap.xml` со всеми инструментами; canonical/OG
> присутствуют на всех страницах; `noindex` отсутствует в собранном HTML
> (`pnpm --dir web build` и проверка `build/tools/*/index.html`);
> `build/` лежит корректный `sitemap.xml` со всеми страницами инструментов;
> canonical/OG присутствуют на всех страницах; `noindex` отсутствует в собранном
> HTML (`pnpm --dir web build` и проверка `build/tools/*/index.html`);
> `pnpm --dir web test:e2e` — по правилам `docs/quality-gates.md`, в CI job
> `e2e` non-blocking, поэтому его статус читается по отдельному job
> (`docs/decisions.md`, раздел 10).
@@ -229,9 +241,9 @@
(`ol`), описание параметров (из схемы), FAQ, related tools (перелинковка
внутри категории + 2–3 «соседних» интента).
- [ ] **[S2c]** Хлебные крошки (Каталог → Категория → Инструмент) в UI.
- [ ] **[S2d]** Первая волна контента — топ-30 инструментов ядра (приоритет по
вордстату: transparent png, jpg→png, compress, resize, crop, rotate,
circle crop, add text, pixelate, grayscale…).
- [ ] **[S2d]** Первая волна контента — топ приоритетных инструментов ядра
(приоритет по вордстату: transparent png, jpg→png, compress, resize, crop,
rotate, circle crop, add text, pixelate, grayscale…); отбор — §5.
- Гейты: на каждой странице инструмента — уникальный текст ≥ 300 слов, H1
совпадает с интентом, FAQ ≥ 3, related ≥ 3; текст в статике (prerender), не в
рантайме.
@@ -266,8 +278,11 @@
- [ ] **[S4a]** Google Search Console: собственность на домен, отправка sitemap,
мониторинг индексации и запросов. Бесплатно и обязательно.
- [ ] **[S4b]** Аналитика без трекинга: self-hosted Plausible/Umami либо
Cloudflare Web Analytics. GA/ЯМ не ставим (позиционирование).
- [ ] **[S4b]** Довести GA4 до решения §0: cookieless-конфигурация, отключённые
рекламные audiences и signals, `anonymize_ip`, запрет на передачу
параметров с данными картинки. Плюс отсечь мусорные попадания:
prerender-оболочка грузит тег и на локальных сборках, их нужно отсекать
флагом окружения. GA/ЯМ как замена счётчику не рассматриваем.
- [ ] **[S4c]** Дистрибуция: закрепить GitHub-репо (README со скриншотами),
подача на alternative.to (страница против конкурента), Product Hunt,
тематические Reddit/HN-треды. Бэклинки — главный дефицит для конкуренции.
@@ -279,19 +294,23 @@
## 5. Приоритизация инструментов (первая волна контента)
Источник — `docs/tools-map.md` (наш состав и замер по конкуренту — §2). Ids ниже
— **фактические id реестра**; первая волна — топ-интенты, где конкуренты
ранжируются, а у нас уже есть инструмент и он не хуже:
Источник — `docs/tools-map.md` (наш состав и замер по конкуренту — §2). Слаги
ниже — **фактические `slug` страниц** из `docs/tools-map.md` §1; первая волна —
топ-интенты, где конкуренты ранжируются, а у нас уже есть инструмент и он не
хуже:
- прозрачность/фон: create-empty-png, remove-background-png, change-png-opacity,
set-alpha-channel-png
set-alpha-channel-png, round-corners-png
- конвертация: convert-png-to-jpg, convert-png-to-webp, png-to-bmp, svg-to-png,
png-to-base64
- геометрия: crop-png, resize-png, rotate-png, round-corners-png, flip-png,
change-aspect-ratio-png
- цвет/фильтры: grayscale-png, invert-colors-png, pixelate-png, add-text-png,
watermark-tile-png
- генерация: linear-gradient-png, create-empty-png
- геометрия: crop-png, resize-png, rotate-png, flip-png, change-aspect-ratio-png
- цвет/фильтры: grayscale-png, invert-colors-png, pixelate-png
- текст: add-text-png, watermark-tile-png
- генерация: linear-gradient-png
> Группы здесь — по категории страницы в реестре (`registry/pages/`), а не по
> смыслу: `round-corners-png` лежит в `alpha`, `add-text-png` и
> `watermark-tile-png` — в `text`.
> **Открытый вопрос по интентам «из формата в PNG».** У конкурента есть
> `jpg-to-png`, `webp-to-png`, `gif-to-png` как отдельные страницы; у нас таких
@@ -380,9 +399,10 @@ with PNG, JPG, WebP» в тексте + селектор формата в Downl
- [ ] **[R1]** Механический переезд бренда на новое имя. Список файлов и строк с
хардкодом — в локальном плане (раздел «Где живёт бренд в коде»); здесь
только SEO-ограничения. **НЕ трогать:** адреса страниц инструментов
(`/tools/crop-png`), ключи localStorage (`easy-png-tools:*` — или
мигрировать отдельной мелочью), историю `docs/archive`. Бренд должен стать
i18n-константой, а не тремя независимыми хардкодами.
(`/tools/crop-png`) и localStorage-ключи — `theme` и `locale` лежат без
префикса бренда, поэтому переименование с ними не столкнётся (проверено в
`theme.svelte.ts` и `i18n/locale.svelte.ts`); историю `docs/archive`.
Бренд должен стать i18n-константой, а не тремя независимыми хардкодами.
- [ ] **[R2]** Купить выбранный домен (кандидаты и пробы — в локальном плане) и
перевести прод на него без `BASE_PATH` (§0). Домен нужен до S1-domain:
canonical и sitemap генерятся от `PUBLIC_SITE_ORIGIN`.
@@ -396,7 +416,8 @@ with PNG, JPG, WebP» в тексте + селектор формата в Downl
- Клонирование всего каталога конкурента (низкокачественные дубли + нет ресурсов
на контент) — вместо этого ядро + обоснованные хвосты.
- RU-локаль в индексе до решения о структуре `/ru/` + hreflang.
- GA/реклама/трекинг — противоречит позиционированию.
- Реклама, ремаркетинг, pixels сторонних сетей — противоречит позиционированию.
Счётчик посещений GA4 — не противоречит, условия ограничений — §0 и S4b.
- Дорвеи, программные зеркала, покупные ссылки.
- Массово-сгенерированные форматные клоны (`crop-jpeg`/`crop-webp` как копии
`crop-png` с подстановкой формата в шаблонный текст) — doorway-паттерн, риск