Для удобства отражения сайта на мобильных устройствах зачастую нужно внедрить в проект страницу Accelerated Mobile Pages (AMP). Делимся примером, как можно выполнить эту задачу, если вы работаете с приложением на React.
Начнем с того, что AMP — технология ускоренных мобильных страниц от Google с открытым исходным кодом. Этот способ позволяет оперативно загрузить веб-страницу при низкой скорости подключения к сети.
Подробнее с технологией можно познакомиться в различных источниках, например, здесь, здесь или здесь.
Именно такая задача появилась в одном из наших проектов, где стек технологий включал в себя Next.js, React, Styled components и Effector, при этом не было доступа к стору на стороне клиента. Большинство инструкций и гайдов по внедрению AMP, в свою очередь, были ориентированы на обычные html-страницы.

Примечание: для подобных задач можно использовать такие инструменты, как react-snap или prerender.io, если в вашем проекте нет Next.js и иных способов рендеринга на сервере.
В первую очередь установите расширение Amp validator от Google, которое поможет в реализации задачи. Если вы работаете с Next, то для включения режима amp на определ��нной страницы достаточно добавить следующую строчку:
export const config = { amp: true }
После этого Next добавляет необходимые теги в разметку. Amp validator поможет вам определить, что нужно сделать, чтобы выполнить требования к amp-страницам. Рассмотрим несколько примеров:
Требования к разметке. Next добавляет необходимые теги в разметку, поэтому достаточно убрать дублирование тегов, добавленных вручную в head. Для поискового продвижения также важно добавить тег
<link rel=”canonical” href=”{SOME_URL}” />.CSS должен быть глобальным, т.е. внутри HTML в теге <head>, и минимального размера. Размер авторской таблицы стилей или совокупный размер встроенных стилей не должен превышать 75 000 байт, иначе произойдет ошибка валидации. Здесь полезна библиотека styled-components, так как на странице будет использоваться только тот css, который необходим. Кроме того, библиотека по умолчанию добавляет стили в тег <head> HTML, а валидатор от Google проверяет
!importantв стилях.Проверьте все компоненты, используемые на странице. Используйте тег
<amp-img />вместо img или компонента Image, который предоставляет Next. Обратите внимание, что на Typescript на сегодняшний день нет поддержки таких тегов, какamp-img. Однако, в корне проекта можно создать файлamp.d.tsи в нем прописать следующее:
declare namespace JSX {
interface IntrinsicElements {
'amp-img': any;
} }Next предоставляет кастомный хук useAmp(), который возвращает true, если это страница AMP, и false, если нет. Мы не создавали новые компоненты и использовали этот хук внутри тех компонентов, которые рендерятся на странице.
Здесь можно было пойти другим путем и создать новый компонент типа AppImage, который будет возвращать нужный элемент в зависимости от хука. Однако, уровнем выше нам все равно нужно было выполнять проверку, так как изображения в целях оптимизации должны иметь строго определенные размеры width и height.
Еще одна проблема может быть связана с использованием формы. В теге
formобязательно должен быть атрибутtarget, который может принимать значение_blankили_topТег
scriptзапрещен, если параметрtypeне имеет значениеapplication/ld+json,application/jsonилиtext/plain. Другие неисполняемые значения могут быть добавлены по мере необходимости. Исключения — обязательный тегscript, используемый для загрузки среды выполнения AMP, а также тегиscriptдля загрузки расширенных компонентов.
Если в проекте нужна интерактивность, есть два способа реализации.
В AMP HTML запрещены имена атрибутов, начинающиеся с on (например,
onclickилиonmouseover). Атрибут с буквальным именем on (без суффикса) является допустимым. Что это дает? Возможность указать действия по событию, например, добавить к кнопке строчкуon=”tap:menu.toggleVisibility”.По клику на кнопку (tap) происходит поиск элемента, у которого id равен menu. Если он виден, то будет скрыт. Для того чтобы добавить несколько действий на один элемент, их можно перечислить через запятую, например:
on=”tap:menu.toggleVisibility,elem.show”. Также можно прослушивать несколько событий на одном элементе, для этого их нужно перечислить через точку с запятой:on="submit-success:lightbox1;submit-error:lightbox2"Вместо этого вы можете использовать существующий amp-компонент. Например, если вам нужна amp-carousel и отдельные слайды готовы, останется только обернуть их в этот компонент и стилизовать кнопки.
Также вы можете использовать тег
<amp-script>и обернуть им любую часть своего HTML. Amp-script копирует своих потомков в виртуальный дом, и вы сможете обратиться к ним черезdocument.body
<amp-script src="http://example.com/my-script.js" width="300" height="100">
<p>A single line of text</p>
</amp-script>Заключение
Как вы видите, в создании AMP-страниц для React в принципе нет ничего сложного. При этом зачастую нужно переключиться с того стиля кода, который характе��ен для современных React-приложений, и реализовать задачу так, как вы бы это сделали до создания React.
Спасибо за внимание! Надеемся, что этот пример был вам полезен.
