When working with Puppeteer for web scraping or screenshot generation, you might need to render pages with different emoji styles rather than the default emoji style provided by the browser.
There are many emoji libraries that can help with this. For example, emoji-js is a popular library that can be used to render emojis in different styles.
Note: Whatever emoji library or style you decide to use, make sure you do not violate any license of the emoji set.
For example, if you use emojis provided by Twitter, you must follow their license requirements.
Using emoji-js with Puppeteer
Here’s how you can use Puppeteer to replace emojis on a page with a different style (like Twitter emojis):
const puppeteer = require("puppeteer");
async function takeScreenshotWithCustomEmojis(url, outputPath) { const browser = await puppeteer.launch(); const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle2" });
// replace emojis with different style await page.evaluate(() => { return new Promise((resolve) => { const script = document.createElement("script"); script.src = "https://cdn.jsdelivr.net/npm/emoji-js@3.8.1/lib/emoji.min.js"; script.crossOrigin = "anonymous"; script.onload = () => { // change to the emoji set you want to use const img_set = "twitter";
const emoji = new window.EmojiConvertor();
emoji.img_sets[img_set].path = `https://cdn.jsdelivr.net/npm/emoji-datasource-${img_set}@15.1.2/img/${img_set}/64/`; emoji.img_sets[img_set].sheet = `https://cdn.jsdelivr.net/npm/emoji-datasource-${img_set}@15.1.2/img/${img_set}/sheets/64.png`; emoji.img_set = img_set; emoji.replace_mode = "img";
// Recursively iterate through DOM and replace emojis only in text nodes function replaceEmojisInTextNodes(node) { if (node.nodeType === Node.TEXT_NODE) { if (node.textContent && node.textContent.trim()) { const span = document.createElement("span"); const replaced = emoji.replace_unified(node.textContent); span.innerHTML = replaced;
if (replaced.trim() !== node.textContent.trim()) { const parent = node.parentNode; if (parent) { while (span.firstChild) { parent.insertBefore(span.firstChild, node); } parent.removeChild(node); } } } } else if (node.nodeType === Node.ELEMENT_NODE) { if (node.tagName === "SCRIPT" || node.tagName === "STYLE") { return; }
const childNodes = Array.from(node.childNodes); childNodes.forEach((child) => replaceEmojisInTextNodes(child)); } }
replaceEmojisInTextNodes(document.body); resolve(); };
document.body.appendChild(script); }); });
await page.screenshot({ path: outputPath });
await browser.close(); console.log(`Screenshot saved to ${outputPath}`);}
takeScreenshotWithCustomEmojis("https://example.com", "screenshot-with-custom-emojis.png").catch( (err) => console.error("Error taking screenshot:", err));
ScreenshotOne API
If you decide to go with the ScreenshotOne API for rendering screenshots, you can just apply the scripts from above as a simple API scripts
parameter:
https://api.screenshotone.com/take?access_key=<your_access_key>&url=https://example.com&scripts=const%20stylesheet%20%3D%20document.createElement%28%27link%27%29%3B%0Astylesheet.href%20%3D%20%27https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Femoji-js%403.8.1%2Flib%2Femoji.min.css%27%3B%0Astylesheet.rel%20%3D%20%27stylesheet%27%3B%0Adocument.head.appendChild%28stylesheet%29%3B%0A%0Aconst%20script%20%3D%20document.createElement%28%27script%27%29%3B%0Ascript.onload%20%3D%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20%2F%2F%20change%20to%20one%20you%20are%20interested%20in%2C%20%0A%20%20%20%20%2F%2F%20check%20the%20library%20documentation%20for%20the%20list%20of%20available%20emoji%20sets%0A%20%20%20%20const%20img_set%20%3D%20%27apple%27%3B%0A%0A%20%20%20%20const%20emoji%20%3D%20new%20window.EmojiConvertor%28%29%3B%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20emoji.img_sets%5Bimg_set%5D.path%20%3D%20%60https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Femoji-datasource-%24%7Bimg_set%7D%4015.1.2%2Fimg%2F%24%7Bimg_set%7D%2F64%2F%60%3B%0A%20%20%20%20emoji.img_sets%5Bimg_set%5D.sheet%20%3D%20%60https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Femoji-datasource-%24%7Bimg_set%7D%4015.1.2%2Fimg%2F%24%7Bimg_set%7D%2Fsheets%2F64.png%60%3B%0A%20%20%20%20emoji.img_set%20%3D%20img_set%3B%0A%0A%20%20%20%20emoji.replace_mode%20%3D%20%27img%27%3B%0A%0A%20%20%20%20function%20replaceEmojisInTextNodes%28node%29%20%7B%0A%20%20%20%20%20%20%20%20if%20%28node.nodeType%20%3D%3D%3D%20Node.TEXT_NODE%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28node.textContent%20%26%26%20node.textContent.trim%28%29%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20span%20%3D%20document.createElement%28%27span%27%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20replaced%20%3D%20emoji.replace_unified%28node.textContent%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20span.innerHTML%20%3D%20replaced%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28replaced.trim%28%29%20%21%3D%3D%20node.textContent.trim%28%29%29%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parent%20%3D%20node.parentNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28parent%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20%28span.firstChild%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.insertBefore%28span.firstChild%2C%20node%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.removeChild%28node%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20%28node.nodeType%20%3D%3D%3D%20Node.ELEMENT_NODE%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28node.tagName%20%3D%3D%3D%20%27SCRIPT%27%20%7C%7C%20node.tagName%20%3D%3D%3D%20%27STYLE%27%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20childNodes%20%3D%20Array.from%28node.childNodes%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20childNodes.forEach%28child%20%3D%3E%20replaceEmojisInTextNodes%28child%29%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20replaceEmojisInTextNodes%28document.body%29%3B%0A%7D%3B%0A%0Ascript.src%20%3D%20%27https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Femoji-js%403.8.1%2Flib%2Femoji.min.js%27%3B%0Ascript.crossOrigin%20%3D%20%27anonymous%27%3B%0A%0Adocument.body.appendChild%28script%29%3B
There is a guide on how to render screenshots with different emoji styles in the ScreenshotOne API docs.
Conclusion
Using emoji-js
with Puppeteer is a simple way to render screenshots with different emoji styles and can be accomplished in a few lines of code.
As an alternative to Puppeteer, you can use the ScreenshotOne API to render screenshots with different emoji styles, and doing the same but with just one simple API option.
If you have any questions or suggestions, and decide to go with the ScreenshotOne API for screenshot generation, please let us know at support@screenshotone.com
.