Скриншоты элементов страницы в JavaScript с html-to-image

Введение
Если вы хотите сделать скриншот части или всей веб-страницы через JavaScript, нативного API для этого не существует. Задача сводится к созданию изображения из HTML-узла. На практике это просто при помощи сторонней библиотеки — например, html-to-image. Она превращает DOM-узлы в изображения одной функцией.
Как это работает
html-to-image генерирует изображение в виде base64 data URL и поддерживает форматы PNG, JPG, SVG. Алгоритм библиотеки можно описать так:
- Клонируется целевой HTML-элемент, его дети и псевдоэлементы.
- Для всех клонированных элементов стили копируются и вставляются inline.
- Встраиваются используемые веб-шрифты, если они есть.
- Встраиваются все найденные изображения (включая data URL и внешние, когда это возможно).
- Клонированный узел конвертируется в XML, затем — в SVG.
- SVG используется для создания Data URL.
Краткое определение: data URL — строка, содержащая закодированные в Base64 данные файла, пригодная для установки в src тега img.
Ограничения и подводные камни
Важно: библиотека не универсальна. Основные ограничения:
- Не работает в Internet Explorer и в Safari (из-за различий в поддержке некоторых API и ограничений безопасности).
- Если HTML включает «tainted canvas» (канвас с данными без CORS), попытка конвертации завершится ошибкой — браузер пометит canvas как tainted, и доступ к его данным блокируется.
- Браузеры ограничивают максимальный размер data URL и размер канваса, поэтому очень большие участки страницы или картинки высокого разрешения могут не конвертироваться.
Совет: перед запуском конвертации убедитесь, что внешние изображения доступны с корректными CORS-заголовками или загружены как data URL.
Быстрый пример использования (локальный проект)
- Создайте директорию проекта и установите библиотеку через npm:
npm install --save html-to-image- Установите бандлер (рекомендуется esbuild):
npm install esbuild- Создайте файл index.html и поместите в него следующий HTML (пример):
Document
I'm going to be in a screenshot!
I'm an example of a sufficiently verbose paragraph that
illustrates that taking screenshots in JavaScript is
really very easy, for the following reasons:
- Reason 1
- Reason 2
- Reason 2
- Создайте script.js с кодом, который использует библиотеку:
import * as htmlToImage from "html-to-image";
const elems = ['.colorful-div', '.long-text']
elems.forEach((elem, ind) => {
const node = document.querySelector(elem)
htmlToImage.toPng(node)
.then(function (dataUrl) {
let img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
})
.catch(function (error) {
console.error('oops, something went wrong!');
console.log(error)
});
})- Соберите бандл при помощи esbuild и откройте index.html в браузере:
./node_modules/.bin/esbuild script.js --bundle --outfile=out.js На странице вы увидите оригинальные элементы и их картинные копии (img), полученные из data URL.

Что делает пример
- Импортирует html-to-image.
- Выбирает два селектора в массиве и для каждого узла вызывает htmlToImage.toPng(node).
- Полученный data URL вставляется в src нового тега img, тем самым на странице появляются изображения, идентичные узлам.
Поддержка фреймворков
html-to-image совместима с большинством SPA-фреймворков. Документация показывает примеры для React и других библиотек: принцип тот же — передавать ссылку на DOM-узел (ref) и вызывать методы библиотеки.
Когда это не сработает (контрпримеры)
- Если на странице есть canvas с данными без CORS (tainted canvas) — библиотека не сможет получить пиксели и процесс упадёт.
- Если нужно сделать скриншот страницы в старом IE или на некоторых версиях Safari — не сработает.
- Очень большие области (напимер, изображение 10000×10000) могут превысить ограничения браузера на размер канваса или data URL.
Альтернативные подходы
- Серверные инструменты: wkhtmltoimage, Puppeteer (Headless Chrome) — удобны для полного скриншота страницы на сервере, особенно если требуется рендер без ограничений браузера клиента.
- SVG отрисовка вручную: для простых визуализаций можно генерировать SVG и экспортировать его как изображение.
- Canvas-инструменты: рендеринг UI на canvas и последующий экспорт через toDataURL (но это требует ручной отрисовки).
Мини-методология: безопасный рабочий процесс
- Проверить, что все внешние ресурсы (шрифты, изображения) доступны с корректными CORS-заголовками.
- Тестировать на целевых браузерах (Chrome, Firefox, Edge). Не рассчитывать на IE/Safari.
- Ограничить область снимка и разрешение, чтобы не превысить лимиты браузера.
- Обработать ошибки и уведомлять пользователя о невозможности конвертировать элемент.
Роль‑базовые чеклисты
Разработчик фронтенда:
- Убедиться, что реф на узел доступен после рендера.
- Проверить поддержку шрифтов и внешних изображений (CORS).
- Локально протестировать сборку через esbuild/webpack.
QA / Тестировщик:
- Проверить результат в Chrome/Firefox/Edge.
- Проверить обработку ошибок (tainted canvas, недоступные ресурсы).
- Замерить время генерации для разных размеров узлов.
Бэкенд-разработчик (если требуется серверный вариант):
- Рассмотреть Puppeteer/wkhtmltoimage для серверной генерации.
- Обработать очереди задач и лимиты по памяти/CPU.
Критерии приёмки
- Изображение корректно отображает внешний вид исходного узла (шрифты, фон, изображения).
- Процесс не вызывает утечек памяти или длительных блокировок UI.
- При ошибке отображается понятное сообщение пользователю.
- Производительность: генерация одного изображения занимает приемлемое время (в зависимости от требований проекта).
Советы по совместимости и миграции
- Для старых браузеров используйте серверные решения или прогрессивное улучшение: на современных клиентах — html-to-image, на старых — отображать заглушку/предложение скачать PDF/изображение с сервера.
- Если вам нужен массовый экспорт (тысячи изображений), лучше делать это на сервере с Puppeteer для контроля памяти и параллелизма.
Небольшой словарь (1‑строчные определения)
- data URL — строка вида data:image/png;base64,BASE64…, используемая как src для img.
- tainted canvas — canvas, который содержит пиксели с ресурсами без корректного CORS, доступ к bitmap для чтения запрещён.
- inline-стили — CSS, вставленные прямо в атрибут style у элемента.
Краткое резюме
html-to-image — удобный инструмент для конвертации DOM-узлов в изображения на стороне клиента. Это просто в настройке и интеграции, но требует внимания к совместимости и к CORS у внешних ресурсов. Если нужно обходить браузерные ограничения или генерировать большое количество изображений — рассмотрите серверные инструменты.
Важно: перед использованием в продакшене прогоните тесты на целевых браузерах и проверьте обработку ошибок.
Краткое резюме действий:
- Установить html-to-image и бандлер.
- Импортировать библиотеку и вызвать htmlToImage.toPng/toJpeg/toSvg для узла.
- Обработать ошибки, связанные с CORS и размерами.
Финиш: с помощью html-to-image делать скриншоты DOM-элементов в браузере удобно и быстро, при условии учёта описанных ограничений.