Ма­ни­фест? А? Что? За­чем?

Перевод «Manifest? Eh? What? Why?»

Альфред Маерс

Перевод Анна Кухарева

Редактура Вадим Макеев

Многие из нас, кто работает над вебом, активно стараются уменьшить разрыв между нативными и веб-приложениями.

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

Сегодня разрыв между нативными и веб-приложениями не столько технологический — дело в удобстве пользователей: они предпочитают устанавливать приложения, которые уютно живут на домашнем экране (или даже на рабочем столе, если речь про десктопные браузеры).

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

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

Мы в веб-сообществе, как правило, называем это «прогрессивными веб-приложениями».

Что такое «установка»?#

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

Спецификация манифеста предлагает вам стандартный способ сделать это с помощью файла JSON. Просто сошлитесь на файл манифеста в HTML-странице следующим образом:

<link rel="manifest" href="/manifest-a7db44c6d3.json">

Но что находится в этом загадочном файле манифеста? Хорошо, что вы спросили!

Очень простой манифест#

Самый простой манифест может состоять всего-то из имени и одной или нескольких иконок.

{
    "name": "Супергонщик 3000",
    "icons": [{
        "src": "icon/lowres.png",
        "sizes": "64x64"
    }]
}

Типичный манифест#

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

{
    "lang": "ru",
    "dir": "ltr",
    "name": "Супергонщик 3000",
    "description": "Потрясающая футуристичная гоночная игра из будущего!",
    "short_name": "Гонщик3K",
    "icons": [{
        "src": "icon/lowres.webp",
        "sizes": "64x64",
        "type": "image/webp"
    },{
        "src": "icon/lowres.png",
        "sizes": "64x64"
    }, {
        "src": "icon/hd_hi",
        "sizes": "128x128"
    }],
    "scope": "/racer/",
    "start_url": "/racer/start.html",
    "display": "fullscreen",
    "orientation": "landscape",
    "theme_color": "aliceblue",
    "background_color": "red",
    "screenshots": [{
        "src": "screenshots/in-game-1x.jpg",
        "sizes": "640x480",
        "type": "image/jpeg"
    },{
        "src": "screenshots/in-game-2x.jpg",
        "sizes": "1280x920",
        "type": "image/jpeg"
    }]
}

Название приложения#

Приложению нужно настоящее название или набор названий (которые обычно совсем не совпадают с содержимым элемента <title> документа). Для этого используются ключи name и short_name.

{
    "name": "Моё вообще улётное фотоприложение",
    "short_name": "Фотки"
}

Ключ short_name служит названием приложения при отображении в условиях ограниченного пространства (например, под значком на домашнем экране телефона). Ключ name может быть немного длиннее, отображая название приложения полностью. Также он служит дополнительной информацией для пользователя, который ищет ваше приложения на телефоне. Так что, набрав «улётный» или «фото», пользователь сможет найти приложение на своем устройстве.

Если вы опустите название, то браузер может использовать <meta name="application-name"> или элемент <title>.

Но будьте внимательны: некоторые браузеры могут требовать указать название — иначе, ваше приложение может лишиться статуса «прогрессивное веб-приложение».

Иконки#

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

{
    "icons": [{
        "src": "icon/lowres",
        "sizes": "64x64",
        "type": "image/webp"
    }, {
        "src": "icon/hd_small",
        "sizes": "64x64"
    }, {
        "src": "icon/hd_hi",
        "sizes": "128x128",
    }]
}

Если вы не укажете иконки, браузер будет искать запасные варианты: <link rel="icon">, favicon.ico или, если не найдёт их, может даже использовать скриншот вашего сайта.

Назначение иконки#

Нужно написать.

Больше подробностей о назначении иконок можно найти в спецификации Web App Manifest.

Режимы отображения и ориентация#

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

{
    "display": "fullscreen",
    "orientation": "landscape"
}

Доступные значения режимов отображения:

  • Полноэкранный fullscreen занимает весь экран.
  • Автономный standalone открывает приложение со строкой состояния.
  • Минимальный minimal-ui, когда приложение отображается в полноэкранном режиме, как на iOS, но некоторые действия могут вызывать панель навигации и появление кнопок назад и вперед.
  • Браузерный browser открывает приложение со стандартным набором кнопок и панелью инструментов.

Плюс такого указания ориентации в том, что она выступает в качестве «ориентации по умолчанию» для всего приложения. Поэтому, при переходе от одной странице к другой, ваше приложение остается в правильном положении. Вы можете изменить ориентацию по умолчанию с помощью API ориентации экрана.

Также вы можете применить другие стили для приложение в определённом режиме с помощью характеристики display-mode:

@media all and (display-mode: standalone){
    /* … */
}

Используйте метод window.matchMedia(), чтобы проверить это медиавыражение в JavaScript.

if (window.matchMedia('(display-mode: standalone)').matches) {
    // интересные модификации интерфейса
}

Стартовый адрес#

Иногда при запуске приложения вам нужно, чтобы пользователь всегда попадал на определенную страницу. Ключ start_url даёт возможность это указать.

{
    "start_url": "/start_screen.html"
}

«Область» приложения#

Нативные приложения имеют чёткие границы: как пользователь, вы уверены, что когда вы открываете нативное приложение, оно неожиданно не откроет другое незаметно для вас. Чаще всего, вам предельно ясно, что вы переключились с одного нативного приложения на другое. Обычно эти визуальные подсказки предоставляет операционная система (например, вызов диспетчера задач и выбор другого приложения или нажатие Cmd Tab или Alt Tab на компьютере).

С вебом все иначе: это огромная гипертекстовая система, в которой веб-приложение может охватывать несколько доменов: вы можете с легкостью перейти с gmail.com на docs.google.com и пользователь даже этого не заметит. На практике, идея существования границ приложения является абсолютно чуждой для веба. Ведь, в действительности, веб-приложение — это просто серия HTML-документов (представьте «серию труб»… м-м, нет, забудьте!).

В интернете мы знаем, что покидаем область одного приложения и переходим в другое, только благодаря веб-дизайнерам, которые были достаточно добры, чтобы сделать им уникальный различимый дизайн. В случаях, когда это не так, множество пользователей оказываются обмануты сайтами, маскирующимися под другие (старый добрый фишинг).

Формат манифеста решает эту проблему позволяя указывать «область адреса» для вашего приложения. Эта область устанавливает границы для приложения. Это может быть либо домен, либо директория на этом домене.

{
    "scope": "/myapp"
}

Интернационализация: lang и dir#

Нужно написать.

Распространение приложения#

Нужно написать с подробностями и скриншотами.

Цвет темы и цвет фона#

Нужно написать.

Как мне определить, что пользователь «установил» приложение?#

Спецификация позволяет вам определить, когда пользователь устанавливает приложение с помощью регистрации события appinstalled.

function handleInstalled(ev) {
    const date = new Date(ev.timeStamp / 1000);
    console.log(`Ура! Установлено в ${date.toTimeString()}`);
}

// Используем атрибут IDL обработчика события
window.onappinstalled = handleInstalled;

// Используем .addEventListener()
window.addEventListener('appinstalled', handleInstalled);

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

Что не так с тегами <meta>?#

В ходе обсуждения спецификации шли оживленные дискуссии об использовании тегов <meta> в HTML вместо создания нового формата. В конце концов, реализация функции «добавить на домашний экран» в Chrome использует теги <meta>, да и с самых первых дней веба эти теги были родным домом для всякой нестандартной ерунды.

Причины для использования отдельного файла:

  • это экономит кучу информации в шапке документа при загрузке каждой страницы установленного приложения или сайта;
  • после загрузки, файл остаётся в HTTP-кэше браузера.

В спецификации есть более подробная информация о том, почему мы выбрали JSON вместо HTML-тегов.

Кто это внедряет?#

Манифест и прогрессивные веб-приложения реализованы в Chrome, Opera и Samsung Internet для Android. Firefox также подаёт обнадёживающие сигналы, что будет поддерживать эти стандарты (реализации в Gecko уже больше двух лет, но она не используется ни в одном из продуктов).

Взаимодействие с поисковыми роботами#

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

Если разработчик веб-приложения хочет известить поисковых роботов о запрете на сканирование файла, он может сделать это включив манифест веб-приложения в файл robots.txt. Это описано подробнее в протоколе robots.txt. Разработчик веб-приложения также может использовать HTTP-заголовок X-Robots-Tag.

Авторы#

Основная часть этого пояснения первоначально появилась в статье «The W3C App Manifest specification» на HTML5 Doctor, и была написана Маркусом Касересом и Брюсом Лоусоном. Данный материал публикуется на основе лицензии для некоммерческое использования. Вы можете спокойно изменять, повторно использовать, модифицировать и расширять это пояснение. Некоторые авторы сохраняют свои авторские права на отдельные статьи.