Реализация Web Share API на сайте
Web Share API вызывает нативный диалог шаринга операционной системы — тот же, что открывается при шаринге из мобильного приложения. Пользователь видит свой список приложений: Telegram, WhatsApp, Notes, почта, AirDrop. Никаких кастомных кнопок для каждой соцсети, никаких всплывашек с иконками.
Поддержка: iOS Safari 12.1+, Android Chrome 61+, Edge 79+. На десктопе поддержка частичная — работает в Chrome/Edge на Windows, не работает в Firefox и Safari macOS (без расширений).
Базовый шаринг
interface ShareData {
title?: string
text?: string
url?: string
files?: File[]
}
async function share(data: ShareData): Promise<void> {
if (!navigator.share) {
throw new Error('Web Share API не поддерживается')
}
// Проверка, что браузер поддерживает конкретный набор данных
if (!navigator.canShare(data)) {
throw new Error('Этот тип контента не поддерживается для шаринга')
}
await navigator.share(data)
}
Шаринг файлов
async function shareFile(file: File, title?: string): Promise<void> {
const data: ShareData = { files: [file], title }
if (!navigator.canShare?.(data)) {
// Fallback: предложить скачать файл
const url = URL.createObjectURL(file)
const a = document.createElement('a')
a.href = url
a.download = file.name
a.click()
URL.revokeObjectURL(url)
return
}
await navigator.share(data)
}
// Шаринг Canvas как изображения
async function shareCanvas(
canvas: HTMLCanvasElement,
filename: string,
title?: string
): Promise<void> {
const blob = await new Promise<Blob>((resolve, reject) =>
canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('Ошибка'))), 'image/png')
)
const file = new File([blob], filename, { type: 'image/png' })
await shareFile(file, title)
}
React-компонент с fallback
interface ShareButtonProps {
url: string
title?: string
text?: string
fallbackCopy?: boolean
}
function ShareButton({ url, title, text, fallbackCopy = true }: ShareButtonProps) {
const [copied, setCopied] = useState(false)
const supportsShare = typeof navigator !== 'undefined' && 'share' in navigator
const handleShare = async () => {
if (supportsShare) {
try {
await navigator.share({ url, title, text })
} catch (e) {
// Пользователь отменил — не считается ошибкой
if (e instanceof Error && e.name !== 'AbortError') {
console.error('Share error:', e)
}
}
return
}
if (fallbackCopy) {
await navigator.clipboard?.writeText(url)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
}
return (
<button onClick={handleShare}>
{supportsShare ? 'Поделиться' : copied ? 'Ссылка скопирована' : 'Копировать ссылку'}
</button>
)
}
Что входит в работу
Утилита share с проверкой поддержки и canShare, React-компонент с fallback (копирование в буфер), поддержка файлов и изображений при необходимости, обработка AbortError (пользователь закрыл диалог).
Срок: 2–3 часа.







