VK Mini Apps — это платформа для создания мини-приложений, работающих внутри ВКонтакте. На ней можно создать продукт любого масштаба — от лендинга до сложного сервиса с множеством функций. А ещё вы можете портировать на площадку ваше веб-приложение, чтобы получить доступ к огромной аудитории VK Mini Apps и новым возможностям монетизации. В этой статье поделюсь пошаговой инструкцией, как превратить в сервис любое веб-приложение — на примере планировщика задач.

Всем хабропривет. Я Леонид Шевчук, старший разработчик. Четыре года создаю мини-приложения. Руковожу командой фронтенд-разработки VK Знакомств. Наш сервис разработан как мини-приложение ВКонтакте. Это яркий пример того, что на платформе VK Mini Apps можно делать продукты с очень развитой функциональностью.

Эта статья пригодится тем, кто ещё не работал с нашей платформой, поэтому я буду рассказывать очевидные для опытных разработчиков вещи. Сначала мы освежим в памяти, на каких технологиях делаются современные веб-приложения. Затем научимся портировать в VK Mini Apps — на примере приложения для планирования дел, написанного на React. И сделаем это так, чтобы оно выглядело органично для платформы. А для чего это всё нужно? Сейчас объясню.

У VK Mini Apps огромная аудитория, унаследованная от ВКонтакте. И вы можете бесплатно (или дёшево) получать трафик для своих приложений, когда пройдёте модерацию и попадёте в каталог платформы. Более того, если ваше мини-приложение будет достаточно крутым, оно может получить бесплатный фичеринг — попадёт в тематическую подборку на платформе. Это настоящий буст трафика. Например, «Печенька с предсказаниями» — мини-апп с DAU 350 000, а его сделали три джуна и один мидл.

Перед тем как начать

Мини-приложения представляют собой одностраничные веб-приложения, которые встраиваются в платформу с помощью iFrame или WebView. Здесь нет конструктора наподобие Tilda, никакого zerocode — вам нужно владеть привычными для любого веб-разработчика технологиями: JavaScript, HTML и CSS. Однако порог вхождения гораздо ниже, чем в нативной разработке под Android или iOS.

Ещё нужно владеть каким-нибудь UI-фреймворком. Рекомендую React JS (документация, руководство для новичков): он значительно упрощает разработку веб-приложения. На нём написана и наша библиотека с готовыми компонентами VKUI, в других фреймворках этими компонентами пользоваться не получится. Но при этом React JS — не обязательная технология для мини-приложений. Просто с другими фреймворками придётся самостоятельно решать, какие библиотеки компонентов использовать или изобретать собственные компоненты. И, скорее всего, они будут несовместимы с ВКонтакте.

Начало

Я не буду рассказывать, как писать приложения на React, статья несколько о другом. Поэтому сразу перескочим на шаг вперёд: мы приготовили для вас приложение-планировщик (TODO List), можете ознакомиться с его репозиторием. Он умеет:

  • добавлять и удалять задачи;

  • помечать задачи выполненными;

  • подсчитывать количество выполненных задач.

Теперь оформим его как мини-приложение в VK Mini Apps. 

? Если вам будет сложно выполнить какой-то шаг, можете ввести команду, которая приведена в конце соответствующей главы, и посмотреть результат этого шага.

Сначала клонируйте репозиторий с готовым планировщиком и установите зависимости:

git clone git@github.com:shevchux/vkma-todo-list.git
cd vkma-todo-list
git checkout tags/step-1
npm install

Структура демонстрационного приложения простая: 

├── App
│   ├── App.jsx
│   ├── defaultData.json
│   ├── index.js
│   └── styles.css
├── TodoForm
│   ├── TodoForm.jsx
│   ├── index.js
│   └── styles.css
├── TodoItem
│   ├── TodoItem.jsx
│   ├── index.js
│   └── styles.css
└── index.jsx

Главный компонент страницы (App.jsx):

  • хранит состояние (todos) списка задач;

  • описывает экшены по работе со списком задач:

    • addTask и removeTask для добавления и удаления задач;

    • handleToggle для переключения статуса задачи между отмеченной и неотмеченной;

    • рендерит основное содержимое страницы и дочерние компоненты.

Компонент TodoForm содержит форму создания новой задачи. Через обратный вызов сообщает о намерении добавить её в список.

Компонент TodoItem содержит отрисовку сущности одного элемента списка. Каждый такой элемент умеет через обратный вызов сообщать о намерениях:

  • поменять статус выполненности на противоположный;

  • удалить элемент из списка.

Интерфейс приложения выглядит так:

На этом скриншоте — ваш план действий. После их выполнения вы получите полноценное мини-приложение на платформе VK Mini Apps.

А теперь можно начинать.

1. VK Bridge

? VK Bridge — библиотека для взаимодействия со средой ВКонтакте. Она позволяет выполнять запросы к API ВКонтакте, получать информацию о пользователе, устройстве и многом другом.

Библиотека служит для отправки и получения событий. VK Bridge — это буквально мост между приложениями, работающими на стороне пользователя, и клиентской частью ВКонтакте (мобильным приложением, мобильной и десктопной версией сайта). Именно они обмениваются данными с серверами соцсети, а библиотека работает как посредник на стороне пользователя.

Для использования этой библиотеки необходимо установить npm-пакет:

npm install /vk-bridge

2. VKWebAppInit и инициализация

В начале кода необходимо вызвать событие инициализации (VKWebAppInit). Если вы этого не сделаете, мини-приложение работать не будет.

Теперь импортируйте модуль VK Bridge и инициализируйте мини-приложение:

Подробнее о начале работы с VK Bridge можете почитать в документации.

? Введите команду, чтобы посмотреть результат этого шага:

git checkout tags/step-2

3. Проверка запуска мини-приложения

Чтобы запустить мини-приложение, выполните команду npm run start. Оно будет доступно по адресу https://localhost:3000. Укажите этот адрес для iFrame мини-приложения и проверьте, что оно работает.

В портале для разработчиков зайдите в настройки созданного приложения. Там укажите https://localhost:3000 в качестве адреса для всех трёх версий:

? Важно: наше локальное приложение запускается по протоколу HTTPS. Его использует сайт ВКонтакте, поэтому браузерные политики требуют HTTPS и для домена iFrame-приложения.

Теперь можете открыть мини-приложение в десктопной и мобильной версии: vk.com/appXXX и m.vk.com/appXXX, где XXX — ID вашего мини-приложения. Он указан в настройках:

Обязательно проверяйте мобильную версию, потому что основная доля аудитории мини-приложений открывает их со смартфонов.

Пока не пробуйте открыть мини-приложение именно с мобильного устройства (ни в клиенте, ни по адресу m.vk.com/appXXX), наверняка оно находится в другой сети. Но даже если в той же самой, могут возникнуть проблемы из-за брандмауэра. Ниже я покажу, как настроить просмотр локального мини-приложения с удалённого устройства с помощью туннелирования. 

Идём дальше.

4. Методы VK Bridge и запоминание состояния приложения

Вернёмся к разработке проекта. 

Заметим, что любые изменения, внесённые в мини-приложение, теряются при повторном заходе в него. Решить эту проблему можно по-разному. Например, поднять свой бэкенд и подготовить методы для CRUD-операций с TODO-списком. Но в случае с мини-приложениями ВКонтакте можно обойтись клиентской разработкой. Для этого рассмотрим несколько методов VK Bridge из секции Storage

? Вы можете экспериментировать с любыми методами VK Bridge в песочнице.

Метод VKWebAppStorageSet позволяет закрепить за пользователем некую информацию в рамках конкретного мини-приложения, а метод VKWebAppStorageGet — получить её. У других пользователей не будет к ней доступа. Этого вполне достаточно, чтобы сделать механизм сохранения состояния списка задач. 

Определите ключ STORAGE_KEY, по которому в VK Storage будет храниться JSON с актуальным состоянием. При монтировании корневого компонента запросите данные по этому ключу и актуализируйте состояние todos. Обратите внимание, что VK Storage умеет хранить только строковые данные, поэтому при записи состояние нужно сериализовать (JSON.stringify), а при чтении — десериализовать (JSON.parse). 

У новых пользователей может выскочить ошибка парсинга, потому что значение в VK Storage — по умолчанию пустая строка. Чтобы этого не происходило, отлавливайте ошибку с помощью try-catch и показывайте пользователю приложение по умолчанию.

В качестве самостоятельного задания с помощью флага loaded отрисуйте особое состояние при загрузке списка задач.

Теперь разберёмся, как записывать данные в VK Storage. Для примера, не углубляясь в безопасную архитектуру, воспользуемся useEffect из React для изменения состояния todos. Только будьте осторожнее с генерацией сетевых запросов в useEffect в рабочих проектах: можно сгенерировать много избыточных параллельных запросов, наткнуться на flood control или поймать баги из-за гонки асинхронных операций. Предлагаю вам самостоятельно придумать более безопасный механизм отправки запросов. Например, воспользоваться троттлингом

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

? Введите команду, чтобы посмотреть финальный результат этого шага:

git checkout tags/step-3

? Обратите внимание, что теперь веб-приложение не будет корректно работать в отдельной вкладке по адресу localhost:3000. Дело в том, что VK Bridge работает только внутри iFrame или WebView. 

5. VKUI 

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

Кому-то это может показаться не таким уж и важным, но однородность вашего мини-приложения с экосистемой ВКонтакте — это не только очень важно, но и просто. Даже если вы намерены использовать необычный или уникальный дизайн, помните: пользователь будет интуитивно искать нужные ему кнопки именно там, где они расположены ВКонтакте — это дело привычки. А аудиторию лучше не путать, она любит, когда всё просто и понятно.  

Чтобы поддерживать однородность стиля интерфейсов, ВКонтакте предлагает открытую библиотеку компонентов (VKUI) и иконок (VK Icons). С ними быстрее разрабатывать, нужно меньше кода.

? VKUI — это набор React-компонентов, которые адаптированы под мобильную (Android и iOS) и десктопную среду. Библиотека основана на дизайн-системе ВКонтакте и содержит готовые компоненты, которые будут нативно выглядеть на любом устройстве.

Чем полезна VKUI:

  • Удобно: многие типовые компоненты уже готовы, осталось только встроить их в структуру вашей страницы.

  • Компоненты соответствуют стилю ВКонтакте: пользователю будет привычнее и удобнее работать с теми элементами управления и интерактивом, к которым он уже привык в социальной сети.

  • Не нужно следовать жёсткой архитектуре построения фронтенда: берите только то, что нужно, и можете модифицировать компоненты. Например, добавьте во view-компонент свой класс или обработчик событий, сделайте вложенные компоненты любой глубины и так далее.

  • Адаптивность: библиотека подстраивается под экраны разного размера, делая интерфейс доступным на смартфонах, планшетах и компьютерах.

  • Мультиплатформенность: интерфейсы на VKUI практически неотличимы от дизайна платформ. Библиотека умеет мимикрировать под iOS- и Android-клиенты ВКонтакте, под дизайн vk.com и m.vk.com.

  • Разные цветовые схемы: тёмная тема — один из самых важных факторов доступности.

6. Подключение

Ознакомьтесь с разделом «Быстрый старт» из документации VKUI и выполните описанные шаги.

Сначала установите зависимости:

npm install @vkontakte/vkui @vkontakte/icons

Добавьте тег viewport для корректного отображения интерфейса на безрамочных смартфонах:

<meta
  name="viewport"
  content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>

Соберите базовый app shell для VKUI:

Отдельно расскажу про компоненты View и Panel. View должен содержать в себе набор всех Panel. У каждой Panel должен быть уникальный id. Параметр activePanel у View регулирует отрисовку нужной панели в конкретный момент времени.

Наше тренировочное мини-приложение содержит всего один экран, но обычно их несколько — компоненты View и Panel помогут разобраться с навигацией между разными экранами.

7. Переход на VKUI

Теперь заменим старые компоненты нашего приложения на компоненты VKUI. Для этого в файле App.tsx:

  • шапку «Список задач» оформите с помощью PanelHeader по примеру из документации;

  • индикатор загрузки замените на PanelSpinner (пример);

  • сноску о количестве задач замените на Footer;

  • удалите файл стилей styles.css.

В результате получится очень семантичный код, не нагруженный особенностями реализации вёрстки:

Продолжим рефакторинг в файлах TodoForm и TodoItem. Удалите из них прошлые стили и перейдите на компоненты VKUI. Предлагаю использовать Input, Button и Cell. У вас получится код, похожий на этот:

Теперь у приложения есть современный интерфейс, который использует ВКонтакте. И для этого вам не пришлось написать ни строки на CSS. Более того, новые компоненты умеют адаптироваться под тёмную тему и слегка изменять внешний вид под особенности iOS и Android. 

Слева направо: Android — светлая и тёмная тема, iOS — тёмная тема.

? Введите команду, чтобы посмотреть финальный результат этого шага:

git checkout tags/step-4

8. VK Tunnel

Мобильные ОС могут диктовать условия, которые не всегда заметны при разработке на компьютере. Например, VKUI отрисовывает некоторые компоненты на разных ОС по-разному. Поэтому рекомендую проверить работу своего приложения на мобильном устройстве на этапе локальной разработки, до сборки и публикации проекта. Сделать это можно с помощью VK Tunnel. Это утилита для VK Mini Apps, которая позволяет сделать сервер на вашем локальном компьютере публичным. Вы сможете отладить своё локальное мини-приложение на мобильном устройстве в любой сети и показать коллегам и друзьям промежуточные результаты.

Сначала установите пакет VK Tunnel:

npm install @vkontakte/vk-tunnel -g

Затем в файл package.json добавьте такой скрипт:

"tunnel": "vk-tunnel --insecure=1 --http-protocol=https --ws-protocol=wss --host=0.0.0.0 --port=3000"

Создайте файл vk-tunnel-config.json, он будет отвечать за автоматическую подстановку туннель-адреса в URL для разработчика в настройках мини-приложения (вместо 123456 нужно поставить ID вашего мини-приложения):

{
  "app_id": 123456,
  "endpoints": ["mobile"]
}

Более подробная инструкция есть в документации.

Теперь убедитесь, что у вас запущен локальный сервер: npm run start. И после этого проверьте работу туннеля: npm run tunnel. В первый раз потребуется авторизоваться — следуйте инструкциям, которые появятся в консоли. После этого можно убедиться, что локальная версия мини-приложения запускается в официальном клиенте ВКонтакте на мобильном устройстве.

? Введите команду, чтобы посмотреть финальный результат этого шага: 

git checkout tags/step-5

9. Eruda

Обратите внимание, что в настройках мини-приложения есть возможность включить консоль Eruda. Это может быть полезно для отладки кода, например когда вы проверяете работу вашего мини-приложения не с компьютера, где есть доступ к инструментам разработчика, а с мобильного устройства.

Подробнее об инструментах отладки читайте на портале для разработчиков

10. VK Mini Apps Deploy 

К этому моменту вы уже отладили своё мини-приложение. Пора опубликовать его. Вы можете выбрать для этого любой хостинг и любой домен, как и для обычного веб-приложения. Главное, укажите правильный URL в настройках мини-приложения. Отметим, что не все начинающие разработчики умеют настраивать хостинг для статики. К тому же не всегда это можно сделать бесплатно, получив при этом высокую скорость доставки файлов. Поэтому ВКонтакте предоставляет инструмент, который берёт решение этих вопросов на себя — VK Mini Apps Deploy. Он позволяет опубликовать статику вашего фронтенд-приложения буквально одной командой. Это легко, бесплатно и быстро. ВКонтакте использует кеширование, сжатие и технологию CDN, чтобы доставлять статику до пользователей за максимально короткое время.

Установите пакет VK Mini Apps Deploy:

npm install @vkontakte/vk-miniapps-deploy --include=dev

В файл package.json добавьте скрипты:

"predeploy": "npm run build",
"deploy": "vk-miniapps-deploy"

Создайте файл vk-hosting-config.json, он будет отвечать за автоматическую подстановку адреса вашей статики в URL для пользователей в настройках мини-приложения (вместо 123456 нужно поставить ID вашего мини-приложения):

{
  "static_path": "build",
  "app_id": 123456,
  "endpoints": {
    "mobile": "index.html",
    "mvk": "index.html",
    "web": "index.html"
  }
}

Документация и инструкции по использованию VK Mini Apps Deploy лежат здесь.

Теперь можно развернуть ваше мини-приложение: npm run deploy. Система попросит подтвердить публикацию собранной статики для пользователей мини-приложения. Также в первый раз может потребоваться авторизация. Следуйте инструкциям, которые появляются в консоли. 

После этого проверьте в настройках мини-приложения, что оно всем доступно для просмотра. И убедитесь, что TODO List запускается на всех платформах не только у разработчиков, но и у внешних пользователей.

? Введите команду, чтобы посмотреть финальный результат этого шага:

git checkout tags/step-6

Заключение

Поздравляю, вы портировали своё стороннее веб-приложение на платформу VK Mini Apps! 

Кроме описанных в начале статьи преимуществ у VK Mini Apps есть и другие, часто неочевидные.

  • Монетизация проекта. Например, игра «Ёлочка» приносит авторам выручку более 7 млн рублей в месяц.

  • Вы можете прокачиваться в коммерческой разработке, повышая свою ценность на рынке. Компаниям нужны сервисы, и они всё чаще заказывают разработку спецам и командам, которые умеют работать на VK Mini Apps.

  • Сразу создавая мини-приложения на платформе, вы можете быстро прототипировать разные идеи, экспериментировать и оттачивать владение технологиями. 

  • Вы можете делать классные пет-проекты для портфолио. Как говорится, не GitHub’ом единым.

И напомню ещё раз про каталог — эта фича платформы способна кратно повысить доходность мини-приложений. Как в него попасть, мы расскажем в одной из новых статей.

Полезные материалы

P.S. Опытные разработчики, уже создававшие мини-приложения для VK Mini Apps, расскажите, что вам больше всего помогало на первых порах?