DEV Community

TZGyn
TZGyn

Posted on

How to turn any website into png

In this tutorial we will be using puppeteer to screenshot/screen record any website. For a full api version made with bun and nitro go here.

Prerequisite:

  • chromium installed on your computer
  • bun (for top level await, you can also copy the code to a express server for the same result)

Screenshot any website

Puppeteer made it really easy to screenshot any webpage, they provided a screenshot api with option to switch between visible or full page screenshot. All you need to do is spawn a new chrome browser, go to the website, and use the screenshot api to take a screenshot, the function will return the image data.

Here is the following code to screenshot the landing page of shadcn ui.

import puppeteer from 'puppeteer'

const url = 'https://ui.shadcn.com'

const browser = await puppeteer.launch()

const page = await browser.newPage()

await page.goto(url, {
    waitUntil: 'networkidle2',
})

const data = await page.screenshot({ fullPage: true })

await browser.close()
Enter fullscreen mode Exit fullscreen mode

Result

screenshot result

Screen Record with smooth scrolling

Puppeteer has builtin screen recorder, check out https://pptr.dev/api/puppeteer.page.screencast, but you will be limited to webm format and 30 fps. So we are going to use puppeteer-screen-record package for simpler setup.

To implement smooth scrolling, we will be simulating a touch scroll instead of a mouse scroll.

The following code will record a full page scroll on shadcn ui and write it to video.mp4.

import puppeteer from 'puppeteer'
import { PuppeteerScreenRecorder } from 'puppeteer-screen-recorder'

const browser = await puppeteer.launch()

const page = await browser.newPage()

await page.goto(url, {
    waitUntil: 'networkidle2',
})

const recorderOptions = {
    fps: 60,
}

const recorder = new PuppeteerScreenRecorder(page, recorderOptions)

await recorder.start('video.mp4')

const height = await page.evaluate(() => {
    return document.body.scrollHeight
})

// simulating touch scroll
const session = await page.createCDPSession()

await session.send('Input.synthesizeScrollGesture', {
    x: 0,
    y: 0,
    yDistance: -height,
    speed: 400,
})

await recorder.stop()

await browser.close()
Enter fullscreen mode Exit fullscreen mode

Adding Dark Mode

import puppeteer from 'puppeteer'

const url = 'https://ui.shadcn.com'

const browser = await puppeteer.launch()

const page = await browser.newPage()

// dark mode
await page.emulateMediaFeatures([
    {
        name: 'prefers-color-scheme',
        value: 'dark',
    },
])

await page.goto(url, {
    waitUntil: 'networkidle2',
})

const data = await page.screenshot({ fullPage: true })

await browser.close()
Enter fullscreen mode Exit fullscreen mode

Result

dark mode screenshot

That's all, checkout my github for my other projects, I love to implement stuff from scratch and share my knowledge through open sourcing my work.

Top comments (0)