Skip to content

Commit

Permalink
Apply suggestions from code review part 1
Browse files Browse the repository at this point in the history
Co-authored-by: hyperlint-ai[bot] <154288675+hyperlint-ai[bot]@users.noreply.github.com>
  • Loading branch information
Oxyjun and hyperlint-ai[bot] authored Oct 14, 2024
1 parent ad3dbec commit 59543da
Showing 1 changed file with 27 additions and 27 deletions.
54 changes: 27 additions & 27 deletions src/content/docs/browser-rendering/how-to/pdf-generation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sidebar:

import { Aside } from "~/components";

As seen in the [Getting Started guide](https://developers.cloudflare.com/browser-rendering/get-started/screenshots/), Browser Rendering can be used to generate screenshots for any given URL. Alongside screenshots, we can also generate full PDF documents for a given webpage, and can also provide the webpage markup and style ourselves.
As seen in the [Getting Started guide](/browser-rendering/get-started/screenshots/), Browser Rendering can be used to generate screenshots for any given URL. Alongside screenshots, we can also generate full PDF documents for a given webpage, and can also provide the webpage markup and style ourselves.

## Prerequisites

Expand All @@ -17,13 +17,13 @@ As seen in the [Getting Started guide](https://developers.cloudflare.com/browser
npm create cloudflare@latest -- browser-worker
```

2. Install `@cloudflare/puppeteer`, allowing us to control the Browser Rendering instance:
2. Install `@cloudflare/puppeteer`, which allows you to control the Browser Rendering instance:

```sh
npm install @cloudflare/puppeteer --save-dev
```

3. Add our Browser Rendering binding to our new `wrangler.toml` configuration:
3. Add our Browser Rendering binding to your new `wrangler.toml` configuration:

```yaml
browser = { binding = "BROWSER" }
Expand Down Expand Up @@ -61,20 +61,20 @@ export default {
};
```

## Step One: Define HTML and CSS
## 1. Define HTML and CSS

Rather than using Browser Rendering to navigate to a user-provided URL, here we’re going to generate a webpage manually and then provide that webpage to the Browser Rendering instance, allowing us to render any design we please.
Rather than using Browser Rendering to navigate to a user-provided URL, manually generate a webpage, then provide that webpage to the Browser Rendering instance. This allows you to render any design you want.

<Aside>
It’s worth noting that you can generate your HTML or CSS using any method
youd like. For now were using string interpolation, but this method is
:::note
It's worth noting that you can generate your HTML or CSS using any method
you'd like. For now we're using string interpolation, but this method is
fully-compatible with web frameworks capable of rendering HTML on Workers such
as React, Remix, and Vue.
</Aside>
:::

For this example, were going to take in user-provided content (via a `?name=` parameter), and have that name output in the final PDF document.
For this example, we're going to take in user-provided content (via a '?name=' parameter), and have that name output in the final PDF document.

To start, lets fill out our `generateDocument` function with the following:
To start, let's fill out our 'generateDocument' function with the following:

```ts
const generateDocument = (name: string) => {
Expand Down Expand Up @@ -127,40 +127,40 @@ const generateDocument = (name: string) => {

This example HTML document should render a beige background imitating a certificate showing that the user-provided name has successfully rendered a PDF using Cloudflare Workers.

<Aside>
It’s usually best to avoid directly interpolating user-provided content into
:::note
It's usually best to avoid directly interpolating user-provided content into
an image or PDF renderer in production applications. To render contents like
an invoice, it wold be best to validate the data input, and fetch data
yourself using tools like [D1](https://developers.cloudflare.com/d1) or
[Workers KV](https://developers.cloudflare.com/workers-kv).
</Aside>
yourself using tools like [D1](/d1/) or
[Workers KV](/kv/).
:::

## Step Two: Load HTML and CSS Into Browser
## 2. Load HTML and CSS Into Browser

Now that we have our fully-styled HTML document, we can take the contents and send it to our browser instance. We can create an empty page to store this document as follows:
Now that you have your fully styled HTML document, you can take the contents and send it to your browser instance. Create an empty page to store this document as follows:

```ts
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();
```

The [`page.setContent()`](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.page.setcontent.md) function can then be used to set the pages HTML contents from a string, so we pass in our created document directly like so:
The [`page.setContent()`](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.page.setcontent.md) function can then be used to set the page's HTML contents from a string, so we pass in our created document directly like so:

```ts
await page.setContent(document);
```

## Step Three: Generate and Return PDF
## 3. Generate and Return PDF

With our Browser Rendering instance now rendering our provided HTML and CSS, we can use the [`page.pdf()`](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.page.pdf.md) command to generate a PDF file and return it to the client.
With your Browser Rendering instance now rendering our provided HTML and CSS, you can use the [`page.pdf()`](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.page.pdf.md) command to generate a PDF file and return it to the client.

```ts
let pdf = page.pdf({ printBackground: true });
```

The `page.pdf()` call supports a [number of options](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.pdfoptions.md), including setting the dimensions of the generated PDF to a specific paper size, setting specific margins, and allowing fully-transparent backgrounds. For now, we’re only overriding the `printBackground` option to allow our `body` background styles to show up.
The `page.pdf()` call supports a [number of options](https://github.com/cloudflare/puppeteer/blob/main/docs/api/puppeteer.pdfoptions.md), including setting the dimensions of the generated PDF to a specific paper size, setting specific margins, and allowing fully-transparent backgrounds. For now, you are only overriding the `printBackground` option to allow your `body` background styles to show up.

Now that we have our PDF data, it’s just a matter of returning it to the client in the `Response` with an `application/pdf` content type:
Now that you have your PDF data, return it to the client in the `Response` with an `application/pdf` content type:

```ts
return new Response(pdf, {
Expand Down Expand Up @@ -252,16 +252,16 @@ export default {
};
```

We can run this script to test it using Wrangler’s `--remote` flag:
You can run this script to test it using Wrangler’s `--remote` flag:

```sh
npx wrangler@latest dev --remote
```

With our script now running, we can pass in a `?name` parameter to the local URL (such as `http://localhost:8787/?name=Harley`) and we should see the following:
With your script now running, you can pass in a `?name` parameter to the local URL (such as `http://localhost:8787/?name=Harley`) and should see the following:

![A screenshot of a generated PDF, with the authors name shown in a mock certificate.](~/assets/images/browser-rendering/pdf-generation.png).
![A screenshot of a generated PDF, with the author's name shown in a mock certificate.](~/assets/images/browser-rendering/pdf-generation.png).

---

Dynamically generating PDF documents solves a number of common use-cases, from invoicing customers to archiving documents to creating dynamic certificates (as seen in our simple example here).
Dynamically generating PDF documents solves a number of common use-cases, from invoicing customers to archiving documents to creating dynamic certificates (as seen in the simple example here).

0 comments on commit 59543da

Please sign in to comment.