How to use Puppeteer on Vercel

Joel Griffith
Joel Griffith
/
March 21, 2023
Puppeteer and Vercel powered by browserless

Vercel is a hosting platform, powered mostly by NextJS, to deploy and scale your Node and TypeScript applications. As with many hosting providers this comes with its limits and caveats. When wanting to do actions with headless Chrome and puppeteer on Vercel and you'll likely immediately run into a few issues regarding size and memory limits which make it tough to use puppeteer effectively. Below we detail how you can get around these issues easily with browserless. You can also check out our example project here.

Best practices and setting up

Before we dive too far into it, we'll need to cover a few pre-requisites here. Don't worry, we'll have examples of each including a demo repo to get you started!

  1. We're using NextJS as our main technology since it's incredibly effective and popular for Vercel deployments.
  2. You should be somewhat familiar with how environment variables work in NextJS to properly store secrets. Feel free to read more here.
  3. For the purpose of this blogpost we'll create a simple route that generates a PDF of a URL. Feel free to alter this, but it'll be enough to get you started!

Setting up Puppeteer for Vercel

If you're working on something entirely new then you can simply run the following command, answer a few questions, and get a demo app set up very easily. The command is:

$ npx create-next-app@latest

This command will create your basic "Hello World" app and then exit. For NextJS apps in particular, you'll likely have a "pages" directory with an "api" folder as well. This is where we'll be spending most of our time since our functionality is created inside the NodeJS environment.

Once your application is set up then we'll also install Puppeter since it is required by Vercel in order to deploy properly. We'll opt for the 'puppeteer-core' module to avoid the first issue in Vercel: the 50MB file-size limit. Puppeteer by default ships with headless Chrome bundled together, which is easily over 50MB in size. By using 'puppeteer-core' we can get around this by only having puppeteer's code installed and not the browser binary. To install Puppeteer for Vercel, simply do the following:

$ npm i puppeteer-core

Writing our Puppeteer API

Next we'll set up our API handler to generate these PDFs. By default NextJS adds a "/api" path pre-pended to whatever our route's name is. For this post, we'll have a "pdf.ts" route in the "pages/api" directory. We'll explain everything below but here's the code to get started:


import type { NextApiRequest, NextApiResponse } from 'next'
import puppeteer from 'puppeteer-core'

type Json = {
  message: string
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { searchParams } = new URL(
    req.url as string,
    `http://${req.headers.host}`
  )
  const url = searchParams.get('url')

  if (!url) {
    return res
      .status(400)
      .json({ message: `A ?url query-parameter is required` })
  }

  const browser = await puppeteer.connect({
    browserWSEndpoint: `wss://chrome.browserless.io?token=${process.env.BLESS_TOKEN}`,
  })

  const page = await browser.newPage()
  await page.setViewport({ width: 1920, height: 1080 })
  await page.goto(url)

  return res.status(200).send(await page.pdf())
}

To get started we import some type information for NextJS and then import the puppeteer module from puppeteer-core. The typings aren't required if you're using plain NodeJS, so feel free to delete those in that case.

Next is a "Json" type to describe our responses back to the client. Since our handler can convert any URL into a PDF we need to make sure users supply one! Feel free to alter this block to fit your use-case or needs with puppeteer.

Finally we have our route file. This handler will check to see if there's a "?url" query-parameter for the site to convert to a PDF. If it's missing we'll return a 400 message and a response indicating that it's required. After that we simply connect to a live browser on browserless, create a page, and generate that PDF.

Making puppeteer work on Vercel with browserless

The reason we're able to get puppeteer and Chrome working on Vercel is by avoiding having to download and run Chrome inside of our Vercel app. Separating your puppeteer code from Chrome is actually a great best practice as it cleanly separates Chrome from your application code. Think of it like a database: you don't want to have your database and application code co-located on the same machine ideally.

In order to connect to browserless and use headless Chrome you'll need to get an API token. We offer free accounts with no credit card required here. Once you have your API key, you'll want to create an env.local file with it:


# The browserless API Token
BLESS_TOKEN=YOUR-API-TOKEN

Now that that's set up, let's start our application and visit the route to see if it works properly. From the root of the project, run the following command. You'll want to restart this as any environment variable changes do require a restart of the dev server:

npm run dev

Then, once it's up and ready, go to http://localhost:3000/api/pdf?url=https://www.browserless.io/docs/start. You should get a PDF file downloaded!

Deploy your Puppeteer Code on Vercel

Once we've verified everything is working properly, the next step is getting our Puppeteer + NextJS application onto Vercel. There's two ways of doing this: either the Vercel CLI or via Github. For now we'll use GitHub as a deployment method. You'll want to create a new app on Vercel by clicking "Create a New Project":

Create a new Vercel Project

This will prompt you for a few options, but we'll want to deploy from GitHub. After adding access here's the permissions and screen grab of our GitHub selection:

Set sane Github Permissions

Vercel should automatically recognize that this is a NextJS application, which means we won't have to inform it how to build or bundle Puppeteer, npm run build, or anything else. We will want to input our browserless token, however, as it's necessary for browserless to work:

Add your environment variables

Once in you'll click "Add" then "Deploy." After a few seconds your page should load and display their "Hello World" Screen since we never altered it:

Puppeteer and Chrome on Vercel live!

From here you can edit the page's URL and add "/api/pdf?url=https://example.com" to it. This will verify that our Puppeteer code on Vercel works swimmingly!

Closing thoughts

Using Puppeteer on Vercel doesn't have to be a chore. With browserless you can easily get past any file-size limits, memory limits, and have a great developer experience without the headache. Feel free to sign-up for a hosted account and get started today, or check out our example repo here. Happy Coding!

Share this article

Ready to try the benefits of Browserless?

Sign Up