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-аудит контенту про перевірку тексту, яка починається, коли сторінка вже індексується.
