Кнопка «Копировать в буфер» в React
Добавление кнопки «Копировать» улучшает UX: пользователю не нужно вручную выделять текст. В статье показаны два подхода — через Clipboard API и через пакет react-copy-to-clipboard, а также рекомендации по проверке прав, доступности, тестам и критериям приёмки.

Копирование вручную — выделение текста, нажатие сочетания клавиш или долгий тап — может быть долгим и ошибочным, особенно на мобильных устройствах. Функция «копировать в буфер» экономит время и снижает риск опечаток.
Когда нужна кнопка копирования
- Когда пользователи регулярно копируют сниппеты кода, ссылки, токены или шаблоны.
- Когда хочется уменьшить количество ошибочных копирований и сократить поддержку.
- Когда взаимодействие происходит на мобильных устройствах с ограниченной точностью ввода.
Важно: кнопка полезна, если поведение предсказуемо и пользователь получает подтверждение о результате действия.
Настройка компонента CopyButton
Создайте простой компонент CopyButton, который получает prop text и копирует его по клику.
function CopyButton({ text }) {
const copyToClipboard = () => {
// copy to clipboard
}
return (
)
}
export default CopyButtonНиже мы реализуем реальную функцию copyToClipboard двумя способами: через Clipboard API и через npm-пакет.
Использование Clipboard API в React
Clipboard API предоставляет методы для чтения и записи буфера обмена. В современных браузерах доступен объект navigator.clipboard с методом writeText.
Пример реализации функции копирования с обработкой ошибок:
const copyToClipboard = async (text) => {
try {
await navigator.clipboard.writeText(text)
// лучше показывать не alert, а кастомный тост/подсказку
alert('Текст скопирован в буфер')
} catch (error) {
alert('Ошибка при копировании: ' + error)
}
}Советы по UX:
- Не используйте alert в продакшне, он блокирует интерфейс. Сделайте ненавязчивое уведомление (toast) или краткий inline-статус.
- Отправляйте сообщение с помощью aria-live, чтобы скринридеры получали обратную связь.
Проверка прав браузера
Перед записью полезно проверить состояние разрешения через navigator.permissions, если API доступен.
const copyToClipboardWithPermission = async (text) => {
try {
if (navigator.permissions) {
const permissions = await navigator.permissions.query({ name: 'clipboard-write' })
if (permissions.state === 'granted' || permissions.state === 'prompt') {
await navigator.clipboard.writeText(text)
alert('Текст скопирован в буфер')
} else {
throw new Error('Доступ к буферу запрещён')
}
} else {
// fallback: пробуем записать напрямую
await navigator.clipboard.writeText(text)
alert('Текст скопирован в буфер')
}
} catch (error) {
alert('Ошибка при копировании: ' + error)
}
}Примечание: некоторые браузеры разрешают запись только в безопасном контексте (https) или при прямом взаимодействии пользователя.
Использование npm-пакета react-copy-to-clipboard
Если вы не хотите работать напрямую с API, можно использовать готовую библиотеку react-copy-to-clipboard. Она проста в использовании и оборачивает логику копирования.
Установка:
npm install react-copy-to-clipboardПример использования в компоненте:
import { CopyToClipboard } from 'react-copy-to-clipboard'
function CopyButton({ text }) {
return (
console.log('copied:', result)}>
)
}Обработчик onCopy получает текст и булево значение результата операции.
Важно: библиотека упрощает работу, но всё равно следует обеспечить доступность и информирование пользователя о результате.
Доступность (a11y) и безопасность
- Добавьте aria-label или явный текст в кнопке, если содержимое неочевидно.
- Используйте aria-live=”polite” для статуса успешного копирования, чтобы скринридеры получили уведомление.
- Не копируйте конфиденциальные данные без явного согласия пользователя: буфер обмена общесистемный и может быть прочитан другими приложениями.
Когда это не сработает: типичные причины
- Браузер не поддерживает navigator.clipboard (старые версии).
- Страница загружена по http, а не https — некоторые методы требуют безопасного контекста.
- Отсутствие прав clipboard-write или блокировка со стороны политики безопасности.
- Ограничения внутри iframe или при взаимодействии с кросс-доменным содержимым.
- Мобильные ОС или браузеры могут иметь специфические баги или ограничения.
Альтернативные подходы (фоллбэки)
- Вставка скрытого textarea, выделение и document.execCommand(‘copy’) — старый, но всё ещё полезный фоллбэк.
- Использовать проверенные библиотеки, например clipboard.js, для поддержки старых браузеров.
- Отображать короткий туториал с инструкцией, как выделить и скопировать для платформ, где автоматическое копирование невозможно.
Пример фоллбэка с hidden textarea:
const fallbackCopy = (text) => {
const el = document.createElement('textarea')
el.value = text
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
el.select()
try {
document.execCommand('copy')
} finally {
document.body.removeChild(el)
}
}Чек-лист по ролям
Для фронтенд-разработчика:
- Реализовать копирование через Clipboard API с фоллбэком.
- Добавить пользовательские тосты и aria-live уведомления.
- Тестировать на мобильных браузерах.
Для QA:
- Проверить копирование в разных браузерах и с http/https.
- Проверить поведение при отказе в правах.
- Проверить сценарии с длинными строками и спецсимволами.
Для продуктового менеджера:
- Определить, какие данные допустимо копировать автоматически.
- Убедиться, что пользователи получают понятный фидбек.
Сниппет — готовый компонента CopyButton с уведомлением и фоллбэком
import React, { useState } from 'react'
function CopyButton({ text }) {
const [status, setStatus] = useState('')
const copy = async () => {
try {
if (navigator.clipboard) {
await navigator.clipboard.writeText(text)
} else {
// fallback
const el = document.createElement('textarea')
el.value = text
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
}
setStatus('Скопировано')
// aria-live element сможет прочитать это сообщение
} catch (e) {
setStatus('Ошибка при копировании')
}
}
return (
{status}
)
}
export default CopyButtonКритерии приёмки
- Кнопка копирует заданный текст во всех поддерживаемых браузерах, либо отображает понятный фоллбэк или сообщение об ошибке.
- Пользователь получает визуальную и программируемую (aria-live) обратную связь.
- Не используются блокирующие alert в продакшене.
- Проверены сценарии: успешное копирование, отказ в правах, отсутствие поддержки API.
Тест-кейсы / Acceptance
- Нажать кнопку — текст должен появиться в системном буфере; проверить вставкой в поле ввода.
- Симулировать отказ в правах — должна появиться удобная подсказка, объясняющая ограничение.
- Проверить на mobile Safari, Chrome Android, Firefox — убедиться в стабильности и в наличии уведомления.
Важно: хранение и автоматическое копирование конфиденциальных данных требует отдельной оценки безопасности.
Итог
Добавление кнопки «Копировать в буфер» в React — небольшая, но значимая фича UX. Используйте Clipboard API как основной способ, поддерживая фоллбэки для старых браузеров. Обеспечьте доступность, безопасное обращение с данными и ясную обратную связь пользователю.
Краткие рекомендации:
- Используйте navigator.clipboard.writeText в безопасном контексте.
- Добавьте фоллбэк через hidden textarea и document.execCommand(‘copy’).
- Обеспечьте aria-live уведомления и не блокирующие тосты вместо alert.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone