Перейти к содержимому

SEO для Flutter: 5 потерь сайта на canvas

SEO для Flutter: 5 потерь сайта на canvas

Команда выкладывает Flutter-приложение в веб, по привычке открывает view-source и видит <canvas> и тег скрипта. В браузере продукт выглядит правильно. Google получает пустую оболочку, и то же самое получает каждое превью ссылки в мессенджере. SEO для Flutter решается в этот момент, задолго до того, как кто-то напишет title.

Код: HydraLine, лицензия MIT.

HydraLine кладёт настоящий семантический HTML в первый HTTP-ответ и поднимает поверх острова интерактивности. Он работает с существующим приложением Flutter Web, по одному маршруту за раз, без замены main() и роутера.

Почему SEO для Flutter не работает по умолчанию

Flutter рисует приложение в canvas. В DOM остаются один элемент и загрузчик. Робот, который не исполняет фреймворк, видит страницу без заголовка, текста и ссылок.

Исполнение скриптов тоже не спасает. Даже робот с JavaScript получает canvas, а текст внутри canvas нельзя выделить, процитировать и проиндексировать как текст. Проблема структурная, и метатегом её не починить.

Что может нести первый ответ

В режиме документа в ответе есть заголовки, абзацы, списки и ссылки, а также canonical, hreflang, Open Graph и Twitter Card с размерами картинки, девять типов JSON-LD. Генератор карты сайта делит её на 50 000 адресов, и этот порог большой каталог переходит раньше, чем кто-то это заметит.

То же дерево документа уходит потоком с сервера на Dart или собирается в статический каталог dist/, поэтому маркетинговый сайт бывает статическим, а приложение обслуживается сервером из одной модели. Два пути отрисовки из одного источника это и есть то, что не даёт им разъехаться.

Потеря 1: трафик, у которого не было шанса

Страница, которая не ранжируется ни по чему, ничего и не приносит. Для продукта, который растёт из поиска, сайт на canvas значит, что весь контент невидим, а команда продолжает покупать трафик, который конкурент получает бесплатно.

Потеря 2: превью ссылки с пустой карточкой

Каждая ссылка в Slack, Telegram, LinkedIn и WhatsApp читает теги Open Graph. Без них превью это серый прямоугольник с голым адресом, и запуск продукта выглядит сломанным в том канале, где о нём объявляют.

Потеря 3: платный трафик на невидимую страницу

Рекламе нужен не SEO, а лендинг, который быстро грузится и конвертирует. Страница на canvas, которая рисует первый кадр несколько секунд, теряет оплаченный клик, и отчёт кампании потом винит аудиторию, а не страницу.

Потеря 4: переписывание, которого не было в бюджете

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

HydraLine работает добавлением: маршрут переезжает в режим document, виджеты Flutter остаются на месте, а остальное приложение продолжает работать. Режим hybrid ставит семантический HTML вокруг островов, которые по-прежнему на Flutter, поэтому карточке товара с конфигуратором не нужны две команды.

Потеря 5: клоакинг как короткий путь

Самый дешёвый взлом это отдавать роботу одну страницу, а человеку другую, определяя робота по User-Agent. Это работает до первого сравнения двух ответов, а потом это санкция на весь домен, а не на страницу.

Здесь сборщик не получает User-Agent вовсе, поэтому робот и человек получают побайтно одинаковое тело. Тест в CI сравнивает оба ответа, и это единственная версия такого обещания, которая выживает после рефакторинга.

Что получает посетитель, пока грузится движок

Интерактивность идёт тремя уровнями. L0 это статический HTML без JavaScript: элементы details и summary, ссылки :target, ленивые картинки. L1 добавляет обычный JavaScript и острова на HTMX около 8–14 КБ, чего хватает для вкладок, форм и поиска. L2 грузит движок Flutter и только тогда, когда острову он действительно нужен.

Большинство контентных страниц до L2 не доходят. Статья, страница документации и лендинг остаются на L0 или L1, движок не грузится. Сдвиг вёрстки держится около нуля, потому что каждый остров резервирует точный размер через Declarative Shadow DOM.

Сколько стоит внедрение

Вечер на маршрут для страниц, которые важны, и ноль работы для остальных. 486 модульных и виджет-тестов, 26 сквозных проверок в живом Chrome, фаззинг XSS на миллионе входов и CLI аудита идут вместе с пакетом, и это та часть, за которую клиент платит один раз и держит.

Рядом: мобильная разработка о том, как считается объём на Flutter, и SEO-аудит контента о проверке текста, которая начинается, когда страница уже индексируется.