← Заметки и статьи о Laravel PHP

4 апреля 2016

SPA и SEO — проблема и решение

Для саморазвития интересно писать простенькие проекты с использованием неизученных технологий. Это помогает скоротать вечер с пользой и не зависнуть в прокрастинации. Одним таким вечером я переписал (в очередной раз) этот блог на Vue.js с SPA уклоном. Всё было отлично — подключил vue-router, vue-resource, разбил приложение на компоненты при помощи Vueify. Радости не было предела.

Радость ушла, SEO пришла

Но затем я задумался — как же приложение теперь проиндексируется? Это важно, потому как это блог и львиная доля траффика приходит из поисковиков. Ещё перестали работать кнопки шейринга — возникает та же проблема, что и при индексировании — бот не умеет рендерить страницу.

Поиск решения

Google

С октября прошлого года Google уже умеет просматривать страницы, как живой мальчик браузер. Отличная новость — ничего не придется делать.

Яндекс

Товарищ Яндекс меня такой же новостью не обрадовал — для каждого роута SPA нужно иметь чистую HTML версию. Она должна быть доступна по адресу с приставкой ?_escaped_fragment_=. Причём оригинальная версия роута должна содержать мета тег <meta name="fragment" content="!">. Он помогает Яндексу определить, что это страница с AJAX содержимым и у неё есть чистый отрендеренный HTML аналог по адресу с приставкой ?_escaped_fragment_=.

Шейринг

С шейрингом сложнее. При нажатии кнопки «Поделиться» во Вконтакте (или другой соц. сети) бот сразу пытается зайти на нашу страницу по адресу и забрать описание, картинку, тайтл и нашу душу. Он не смотрит, есть ли у нас мета тег или ещё чего. Нужно каким-то образом отдавать ему HTML, например, перехватывая заголовок User-Agent.

Что нам нужно в итоге сделать?

Первое — для каждого роута приложения нужно отрендерить HTML версию и сделать её доступной по адресу с приставкой ?_escaped_fragment_=. И не забыть поставить мета-тег.

Второе — перехватывать запросы ботов социальных сетей и отдавать им отрендеренную HTML версию страниц.

Prerender.io — решение в 3 шага

Prerender делает всё за нас — заходит на роут SPA приложения, рендерит его как браузер, сохраняет HTML версию страницы у себя.

Использовать сервис можно двумя способами — бесплатно установить себе на сервер (благо он OpenSource и доступен на Github) или воспользоваться сервером Prerender.io для хранения своих страниц. Второй вариант предполагает оплату за кол-во кешируемых страниц более 250. Для моего блога 250 — более, чем достаточно. Да и возиться с установкой на свой сервер лень.

Используем Prerender

В итоге я совершил три действия:

  1. Зарегистрировался на Prerender.io, получил API ключ.
  2. Установил Laravel Prerender — обычный middleware. Он перехватывает заголовки User-Agent от поисковых систем, проверяет наличие GET параметра _escaped_fragment_. Если одно из этих условий выполняется, то отдаёт отрендеренную Prerender.io HTML версию страницы. Список User-Agent задаётся в конфиге, я добавил туда ещё vkshare для бота шейринга Вконтакте. И задал API ключ из первого пункта в переменную окружения.
  3. Добавил на страницу <meta name="fragment" content="!">.

Вот и всё. Теперь, если к нашему роуту обращается глупый бот, то он получает отрендеренную HTML версию.

Важно! Отрендеренная HTML версия не должна содержать <meta name="fragment" content="!">, как пишет Яндекс. Поэтому в нашем шаблоне мы должны скрывать этот тег, когда нашу страницу смотрит и рендерит Prerender. Это можно сделать с помощью проверки заголовка User-Agent на вхождение prerender.

UPD, 23 января 2017: На самом деле гугл соврал и он не всегда корректно индексирует аяксовые сайты. Prerender не является панацеей, так как даже с ним возникают проблемы: скорость рендеринга низкая на слабых серверах (бот может подумать что сайт медленный, прийдётся помучаться с кешем, что несёт дополнительные проблемы), возможны различные неожиданные баги. Поэтому я рекомендую воздержаться от клиентского рендеринга на больших проектах, где крайне важна SEO оптимизация. Вешайте JS плюшки на части сайта, которые не важны для SEO (например в интернет-магазине выдачу лучше сделать с формированием HTML на сервере, а корзину и оформление заказа уже можно на JS).

Плюсануть
Поделиться
Отправить