Гайды

Как добавить кнопку «Поделиться» на сайт — системное меню телефона без виджетов соцсетей

Иллюстрация: из одной золотой кнопки веером раскрываются пустые конверты, Кодик отправляет один из них

Ряд кнопок «ВКонтакте», «Telegram», «WhatsApp», «X» под статьёй — это гадание. Ты угадываешь, чем пользуется человек. А телефон уже знает. В нём есть системное меню «Поделиться»: мессенджеры, контакты, заметки, AirDrop — ровно те, что стоят у человека.

Сайт умеет открыть это меню одной функцией — navigator.share(). Это Web Share API. Ниже — рабочая кнопка по шагам, с запасным вариантом там, где меню нет.

Шаг 1. Поставь настоящую кнопку

<button type="button" id="share">Поделиться</button>

Именно <button>, а не div с обработчиком клика. Настоящая кнопка сразу работает с клавиатуры и понятна скринридеру.

Шаг 2. Проверь, умеет ли браузер делиться

Поддержка неровная, и это главное, что надо знать:

  • Safari на iPhone — с версии 12.1;
  • Chrome на Android — давно, с версии 61;
  • Chrome на компьютере — полностью с версии 128, раньше только на Windows и ChromeOS;
  • Firefox на компьютере — только если вручную включить скрытый флаг, то есть у обычных людей нет.

Поэтому кнопку всегда пишем с проверкой if (navigator.share) и запасным путём. Не определяй браузер по названию — проверяй саму функцию. Тогда кнопка сама начнёт открывать меню, когда браузер этому научится.

Шаг 3. Вызови меню внутри клика

Вот весь код кнопки:

const button = document.querySelector('#share');

button.addEventListener('click', async () => {
  const data = {
    title: document.title,
    text: 'Смотри, что нашёл',
    url: location.href,
  };

  if (navigator.share) {
    try {
      await navigator.share(data);
    } catch (err) {
      if (err.name !== 'AbortError') console.error(err);
    }
    return;
  }

  await navigator.clipboard.writeText(data.url);
  button.textContent = 'Ссылка скопирована';
});

Главное правило: navigator.share() вызывается только прямо из действия человека — клика или нажатия клавиши. MDN называет это transient activation. Такая активация живёт недолго. Если перед вызовом ты ждёшь ответ сервера через await fetch(), она может истечь — и браузер вернёт ошибку NotAllowedError. Всё, что нужно для шаринга, готовь заранее.

Про сами данные. Поля title, text, url и files необязательные, но хотя бы одно передать надо. Если объект пустой или ссылка кривая, MDN обещает ошибку TypeError. А пустая строка в url означает текущую страницу.

Шаг 4. Не считай отмену ошибкой

Человек открыл меню и передумал — промис завершится ошибкой AbortError. Ту же ошибку MDN описывает, когда делиться просто некуда. Это нормальный сценарий. Не показывай красную плашку «Что-то пошло не так» — в коде выше такая ошибка просто пропускается.

Ещё один случай — двойное нажатие. Пока одно меню открыто, второй вызов вернёт InvalidStateError: MDN объясняет это тем, что другая операция шаринга ещё идёт. Простое решение — ставить кнопке disabled перед вызовом и снимать в блоке finally.

Шаг 5. Дай компьютеру запасной путь

Где меню нет, кнопка копирует ссылку через navigator.clipboard.writeText() и меняет подпись. Человек вставит ссылку куда хочет сам.

У копирования свои правила, похожие на шаринг. По данным MDN, запись в буфер обмена тоже работает только на защищённых страницах, а Firefox и Safari разрешают её лишь в ответ на действие человека. В нашем коде копирование идёт внутри того же клика, так что условие выполнено. Если нет и буфера обмена — покажи ссылку в текстовом поле, чтобы её можно было выделить вручную.

Шаг 6. Проверь на телефоне по HTTPS

Web Share работает только на защищённых страницах. Тут частая засада: ты запускаешь проект на компьютере и открываешь его с телефона по адресу вида http://192.168.1.5:3000. Это не HTTPS и не localhost — navigator.share на такой странице просто не будет. Проверяй на задеплоенной версии или через туннель, который выдаёт HTTPS-адрес для локального сервера; как выложить проект, разобрано в статье как задеплоить приложение.

И если кнопка живёт внутри чужого iframe, родительская страница должна разрешить её атрибутом allow="web-share".

Что получится

На телефоне тап по кнопке открывает снизу системную шторку с приложениями человека. Заголовок title некоторые приложения игнорируют — MDN об этом предупреждает, поэтому смысл клади в text и url.

Узнать, куда именно поделились, нельзя: промис просто успешно завершается. На Windows это происходит, когда открылось окно, на Android — когда данные переданы приложению.

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

Если собираешь с ИИ, дай ему точное задание:

Слабый промптДобавь кнопку поделиться
Сильный промптДобавь кнопку «Поделиться» на страницу статьи. Используй navigator.share с title, text и url текущей страницы. Вызывай его прямо в обработчике клика, без await перед вызовом. Если navigator.share нет — копируй ссылку через navigator.clipboard.writeText и на 2 секунды меняй текст кнопки на «Ссылка скопирована». AbortError не показывай как ошибку. Используй настоящий button, без сторонних виджетов соцсетей.
Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение

Можно ли поделиться картинкой, а не ссылкой?

Да, через поле files. Сначала проверь navigator.canShare({ files }), потом передавай файлы в share(). Поддерживаются некоторые типы изображений, видео, аудио, PDF и текста.

Можно ли открыть меню автоматически, без кнопки?

Нет. MDN пишет прямо: меню нельзя вызвать из скрипта в произвольный момент, только из обработчика действия в интерфейсе. Попытка без клика закончится ошибкой NotAllowedError.

Почему на компьютере кнопка копирует, а не открывает меню?

Потому что браузер не поддерживает Web Share — чаще всего это Firefox. Запасной путь с копированием для этого и нужен.

Нужно ли подключать скрипты соцсетей?

Для кнопки «Поделиться» — нет. navigator.share() встроен в браузер и не требует ни библиотек, ни ключей API.

Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →