© 2018 WebHive

Ember.js и SEO

Как хорошо известно приложения на javascript MVC фреймворках очень плохо индексируются поисковыми машинами. Контент генерируется автоматически на клиенте и для поисковой машины сайт выглядит как пустая страница. Ember.js не исключение и это безусловно один из его огромных недостатков. Попробуем изучить вопрос и разобраться какие есть варианты решения этой проблемы.

Собственно для нормальной индексации надо решить две проблемы:

  • Поисковая машина должна обнаружить ссылки
  • Сервер должен отвечать по найденным ссылкам

Рассмотрим эти моменты подробнее

Как показать ссылки поисковой машине

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

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

Существует два решения этой проблемы:

Обеспечить корректную работу для клиентов не поддерживающих javacsript

Суть этого способа в том, чтобы для каждой страницы предоставить некоторый HTML код, завёрнутый в тег <noscript>. Такой подход использован например в проекте discuss.emberjs.com. Но данный метод не пользуется особой популярностью т. к. нужно делать двойную работу и обеспечивать работу сайта без javascript.

Предоставить sitemap.xml

Второй способ довольно банален. Собственно можно скормить ссылки для поисковой машины через sitemap.xml. Все равно вы скорее всего будете его использовать, поэтому получается решить проблему «малой кровью». В него можно напихать любые ссылки — лишь бы сервер мог на них вернуть корректный контент.

Как заставить сервер отзываться на данные URL-ы

Как правило (а для ember.js именно так!) javascript фреймворки используют т. н. hash навигацию. В этом случае URL выглядит примерно так http://mydomain.com/#/posts/1. Таким образом текущий путь указывается после символа # и соответственно не передаётся на сервер, т. к. изначально предназначен для быстрой навигации внутри страницы.

Таким образом суть проблемы это найти возможность передать этот путь серверу. Опять же рассмотрим два варианта решений этой задачи:

Использование HTML5 History API

HTML5 History API позволяет перезаписывать URL без перезагрузки страницы. В этом случае никакого символа # в URL-е нет и ссылки выглядят как обычно http://mydomain.com/posts/1. Фреймворк манипулирует URL-ами через History API.

Для Ember включается следующим образом:

1
2
3
App.Router.reopen({
location: 'history'
});

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

Ну и очевидным минусом такого подхода является необходимость дублировать для каждого Ember пути соответствующий серверный эквивалент. В случае большого приложения это может стать проблемой.

Так же в данный момент не все браузеры поддерживают HTML5 History API, что безусловно мешает продвижению этой технологии в массы. Хотя судя по caniuse.com все не так уж и плохо — даже IE подтянулся.

API compatibility chart

Использование AJAX Crawling Scheme

В качестве альтернативы можно использовать (AJAX Crawling Scheme) [https://developers.google.com/webmasters/ajax-crawling/docs/getting-started]. Данная технология в настоящий момент поддерживается практически всеми поисковыми машинами (Google, Yahoo, Bing). Даже Яндекс хотя и много критиковался за отсутствие поддержки данной технологии таки добавил ее поддержку.

В этом случае символ # заменяется на #! (это ещё называют термином hashbang) (например http://mydomain.com/#!/posts/1) и поисковая машина обнаружив такой URL сформирует запрос к серверу следующего вида http://mydomain.com?_escaped_fragment_=posts/1.. Нужно лишь, чтоб сервер ответил на этот запрос правильным HTML кодом.

Собственно этот метод немногим лучше варианта с HTML5 History API. Как ни верти нужно делать поддержку на стороне сервера. Но тем не менее это выбор и тут уж каждый решает, чтоб подходит именно ему.

Для Ember.js поддержка hashbang отсутствует и придется брать в руки напильник и делать какое-то своё решение, что как бы не радует.

Итого

Моё предпочтение в случае Ember все-таки на стороне HTML5 History API. Собственно все банально — есть готовая поддержка, браузеры уже поддерживают эту технологию практически поголовно, а на сервере контент генерить придется в любом случае.

Ссылки по теме

Комментарии