Динамические изображения для социальных сетей

Чтобы привлечь внимание к своим записям или твитам, нужно добавить к ним изображения. Согласно исследованиям, наличие изображения в опубликованном посте повышает его привлекательность на 35%-150%. Поэтому при добавлении контента на сайт, следует убедиться, что в нем используются подходящие для социальных сетей изображения.

Добавление изображений для размещения в социальных сетях

Процесс публикации в социальных сетях заключается в добавлении метатега к заголовку страницы с указанием адреса нужного изображения. Когда ссылка на контент сайта добавляется в запись, социальная сеть использует указанное изображение.

<meta property="og:image" content="https://example.com/my_image.jpg">

Но что делать, если у вас нет таких изображений?  С такой ситуацией мы столкнулись, когда хотели добавлять изображения к твитам с анонсами о выходе новых статей. При этом у нас всегда были фотографии авторов.

В результате мы разработали шаблон, который использовал фотографию автора вместе с цитатой из статьи.

Добавление изображений для размещения в социальных сетях

Пример изображения, созданного вручную.

Каждый день мы выбирали цитату из статьи, и вручную изображение для загрузки на сайт. Результаты были великолепны. Но весь процесс был слишком трудоемким.

Разработка нового плана

Для оптимизации процесса я составил следующий план:

  1. Создать CSS для расположения компонента, который можно превратить в изображение.
  2. Добавить в CMS новое поле к статьям для размещения выбранной цитаты.
  3. Создать в CMS новый макет страницы, предназначенный для динамического вывода имени автора и цитаты для любой статьи.
  4. Создание скриншота изображения для публикации.

Создание страницы

Сначала нужно было разобраться с базовым HTML и CSS. В коде используется контейнер размером 600 × 315px. Это сделано для обеспечения правильного соотношения сторон изображения в Facebook.

Наша CMS позволяет отображать контент, используя любое количество шаблонов. Поэтому я создал упрощенную версию шаблона статьи. Она включала в себя только информацию об авторе и цитату, а также специально подготовленную разметку.

Я также добавил в CMS новое поле для цитаты, приведенной в статье, чтобы каждое изображение можно было быстро и легко настроить.

Создание страницы

Я добавил новое поле к шаблону статьи.

В результате мы добились, чтобы для твита использовалось изображение из CMS.

Создание страницы - 2

Автоматически сгенерированный макет непосредственно из CMS  

Вскоре стало ясно, что «Шаг 4» будет довольно сложным. Я могу создать небольшую страницу на сайте, которая выглядит как изображение. Но как превратить ее в единое целое?

Можно сделать скриншот вручную, но это возвращение к старой проблеме. Как автоматически сделать скриншот?

Введение Puppeteer

Puppeteer – это библиотека, созданная на основе Node.js. Она предлагает хороший API для версии Google Chrome, которая  запускается из командной строки. При этом программа ничего не прорисовывает в окне пользовательского интерфейса.

Такой Chrome можно использовать для рендеринга страниц и создания их скриншотов. Именно здесь на помощь приходит Puppeteer. С ее помощь я могу написать небольшой скрипт, который будет многократно превращать URL-адрес в изображение.

Сначала вы устанавливаете Puppeteer. После чего библиотека сама загружает совместимый консольный браузер. Для этого в командной строке набираем:

npm i puppeteer

Затем сохраняем новый файл как example.js и размещаем в нем следующий код:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

Затем запускаем этот файл, используя Node:

node example.js

После этого файл картинки example.png будет выведен на ресурс, который содержит его скриншот. В данном случае https://example.com. Логика кода довольно проста:

  1. Запустить браузер.
  2. Открыть новую страницу.
  3. Перейти по URL- адресу.
  4. Сделать скриншот.
  5. Закрыть браузер.

Функция async и ключевое слово await заставляют скрипт сделать паузу и ожидать возвращения нормального асинхронного кода для продолжения. Это нужно для загрузки веб-страницы. Задача заключается в том, чтобы заставить асинхронный код работать как синхронный. Если вам интересно, то можете подробно ознакомиться с async и await на MDN.

Теперь я могу сделать скриншот URL-адреса. Но что произойдет, если я вставлю сюда URL моей новой специальной страницы?

Введение Puppeteer

Контент находится в углу изображения, при этом много свободного места.

Но Puppeteer делает скриншот с разрешением 800 × 600. Поэтому надо выяснить, как настроить изображение. К счастью, я довольно быстро нашел такой способ —  page.setViewport().

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://24ways.org/2018/clip-paths-know-no-bounds/sharing');
  await page.setViewport({
    width: 600,
    height: 315
  });
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

Это сработало. Теперь разрешение скриншота составляет 600 × 315. Но стоило бы повысить качество получаемого изображения.

В документации я обнаружил параметр deviceScaleFactor, который можно передать в page.setViewport(). Установив значение на 2, мы получим изображение той же области экрана, но с большим количеством пикселей.

  await page.setViewport({
    width: 600,
    height: 315,
    deviceScaleFactor: 2
  });

Теперь у нас есть программный способ превращения URL-адреса в изображение.

Улучшаем скрипт

Создадим скрипт, который можно запустить с URL-адресом в качестве аргумента и заставить его выдать изображение для этой страницы. Благодаря этому мы сможем автоматизировать создания изображения. Наша цель заключается в вызове следующего скрипта:

node shoot-sharing-image.js https://24ways.org/2018/clip-paths-know-no-bounds/

Также я хочу, чтобы изображение выводилось с именем clip-paths-know-no-bounds.png . Для этого необходимо, чтобы скрипт находил аргументы команд, а затем разбивал URL для извлечения slug.

// Получить URL-адрес и slug-сегмент 
const url = process.argv[2];
const segments = url.split('/');
// Получить предпоследний сегмент (slug)
const slug = segments[segments.length-2];

Мы можем использовать эти переменные, не забывая при этом добавить sharing в конце URL-адреса, чтобы получить специальную страницу.

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url + 'sharing');
  await page.setViewport({
    width: 600,
    height: 315,
    deviceScaleFactor: 2
  });
  await page.screenshot({path: slug + '.png'});
  await browser.close();
})();

После генерации изображения с помощью Node.js его можно перенести в нужное место на сайте.

Также можно оптимизировать файл. Чтобы немного уменьшить размер файла, я использовал imagemin вместе с pngquant.

const imagemin = require('imagemin');
const imageminPngquant = require('imagemin-pngquant');

await imagemin([slug + '.png'], 'build', {
  plugins: [
    imageminPngquant({quality: '75-90'})
  ]
});

Вот тут можно посмотреть готовый пример.

Взаимодействие с вашей CMS

Я уже запускал данный скрипт вручную. Он добавляет файл в репозиторий Git и передает его для удаленной загрузки на сервер.

Проявив немного изобретательности, собственные шаблоны CMS и Puppeteer, мы получили надежный способ динамического создания изображений для анонсов статей сайта в социальных сетях.

Дайте знать, что вы думаете по этой теме статьи в комментариях. Мы очень благодарим вас за ваши комментарии, подписки, отклики, дизлайки, лайки!

Пожалуйста, опубликуйте ваши мнения по текущей теме материала. Мы крайне благодарны вам за ваши комментарии, лайки, подписки, отклики, дизлайки!

Наталья Кайдаавтор-переводчик статьи «Dynamic Social Sharing Images»