Создание скриншотов DOM в JavaScript с html-to-image
Что делает html-to-image и как это работает
html-to-image генерирует изображение в виде base64 data URL. Поддерживаемые форматы: PNG, JPG и SVG. Вкратце алгоритм выглядит так:
- Клонируется целевой HTML-элемент вместе с потомками и псевдоэлементами.
- Для всех клонированных узлов копируются и встраиваются inline-стили.
- Если есть веб-шрифты, библиотека пытается их встраивать в результат.
- Встраиваются все внешние изображения (при возможности, с учётом CORS).
- Клонированный узел преобразуется в XML, а затем в SVG.
- SVG используется для создания Data URL (base64), который возвращается в промисе.
Ключевая идея: вместо «скриншота окна» библиотека рендерит копию узла в SVG и экспортирует её как картинку.
Ограничения и подводные камни
Важное: библиотека удобна, но не всесильна.
- Не работает в Internet Explorer и некоторых версиях Safari.
- Если на странице есть tainted canvas (канвас с данными без CORS), конвертация упадёт — браузер блокирует экспорт таких данных.
- На размер получаемого data URL накладывают ограничения сами браузеры — очень большие узлы могут не поместиться в память или превысить лимиты URL.
- Шрифты и внешние ресурсы требуют корректного CORS и доступности; если ресурс недоступен, он может отсутствовать в итоговом изображении.
Примечание: всегда тестируйте экспорт на целевых браузерах и профилируйте потребление памяти для больших областей.
Быстрый пример: установка и минимальный проект
- Инициализируйте папку проекта и установите пакеты:
npm install --save html-to-image
npm install --save-dev esbuild- Создайте index.html и откройте его через локальный сервер. Ниже — пример HTML (сохраните как index.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После загрузки страницы вы увидите оригинальные DOM-узлы и вставленные в документ изображения, сгенерированные библиотекой.

Работа с фреймворками и форматами
html-to-image хорошо интегрируется с React, Vue и другими фреймворками: вместо document.querySelector вы передаёте ref на узел. Документация библиотеки содержит примеры для React и методы для получения JPG и SVG.
Если вам нужен полный скриншот страницы (включая невидимую область), html-to-image фокусируется на отдельных узлах. Для полного рендера страницы рассмотрите другие инструменты (см. раздел «Альтернативы»).
Альтернативные подходы
- html2canvas — рисует DOM на canvas и экспортирует изображение; чаще сталкивается с ограничениями по стилям и шрифтам, но работает в большем числе случаев.
- wkhtmltoimage (CLI) — рендерит страницу на сервере через WebKit; полезно для серверного получения скриншотов целых страниц.
- Puppeteer / Playwright — headless-браузеры, дающие максимально точные скриншоты и контроль; подходят для серверной автоматизации.
Когда html-to-image не подходит: большие страницы, tainted canvas, строгие требования к точности рендеринга (в этом случае Puppeteer/Playwright предпочтительнее).
Практические рекомендации и чек-лист по внедрению
Роль — frontend-разработчик:
- Проверить совместимость браузеров у аудитории.
- Убедиться, что все внешние ресурсы (шрифты, картинки) доступны с корректными CORS-заголовками.
- Ограничить область для скриншота по размеру и сложности (текст вместо тяжёлых SVG/канвасов).
- Тестировать на мобильных и настольных браузерах.
Роль — backend-разработчик (серверная генерация):
- Рассмотреть Puppeteer/Playwright или wkhtmltoimage вместо html-to-image.
- Организовать очередь задач и лимиты памяти, чтобы избежать OOM при больших рендерингах.
Критерии приёмки:
- Сгенерированное изображение визуально соответствует исходному элементу на большинстве тестовых страниц.
- Нет ошибок, связанных с CORS или tainted canvas.
- Время генерации — допустимое для UX (обычно < 2–3 с для небольших блоков).
Безопасность и приватность
- Не отправляйте на сервер пользовательские данные или приватные ресурсы без согласия. Если вы используете серверные рендеры (Puppeteer), соблюдайте правила хранения и удаления временных изображений.
- Если страница содержит приватные CORS-ограниченные ресурсы, они могут не попасть в итоговое изображение.
- Для GDPR/LPD: документируйте, где и как вы храните сгенерированные скриншоты, и давайте пользователю возможность удалить свои данные.
Тесты и приёмка
Минимальные тест-кейсы:
- Экспорт простого блока с цветным фоном и текстом.
- Экспорт блока с веб-шрифтом (проверьте, встраивается ли шрифт).
- Экспорт блока с внешними изображениями, проверка поведения при отсутствующем ресурсе.
- Поведение при наличии canvas на странице (ожидаемая ошибка в tainted-случае).
Ментальные модели и рекомендации по отладке
- Представляйте преобразование как «клонирование → встраивание ресурсов → сериализация в SVG». Если что-то не отображается — выясняйте, на каком шаге ресурс теряется (CORS, отсутствующий URL, нестандартный шрифт).
- Для воспроизведения ошибок используйте минимальный пример: удаляйте части узла, пока не найдете проблемный ресурс.
Решение проблем: быстрый чек-лист
- Если картинка обрезана или искажена — проверьте размеры контейнера и box-sizing.
- Если шрифты заменяются — убедитесь, что шрифты загружаются по CORS и @font-face корректно описан.
- Если возникает ошибка с canvas — определите, откуда берётся tainted canvas и можно ли получить ресурс через CORS или заменить реализацию.
Итог
html-to-image — простой и удобный инструмент для преобразования DOM-узлов в изображения на клиенте. Для большинства случаев (компоненты, карточки, превью) он работает «из коробки». Для серверной генерации целых страниц и высокоточных скриншотов лучше применять headless-браузеры или специализированные CLI-инструменты.
Краткие выводы:
- Используйте html-to-image для клиентских лайт‑скриншотов отдельных узлов.
- Проверьте CORS и canvas, чтобы избежать сбоев.
- Для полного контроля и точности используйте Puppeteer/Playwright.
Конец статьи.
Похожие материалы
YouTube Music на Windows — PWA и десктопные клиенты
Family Pairing в TikTok — как включить контроль
Apple Pay не работает — как быстро исправить
Проверка и очистка использования диска Docker
Как исправить ошибки Hulu на Xbox One