Generate Signable PDF Forms with React
Tags: pdf, react, typescript, fileforge
Published: 2024-07-11 15:55:28


## Why use React to generate PDF Forms?

When Generating PDF Forms, React (or HTML) may not be the first thing that comes to mind! It makes more sense when we compare it with website forms: we want to lay out the form fields, add labels, and make it easy to fill out. React is a great tool for this, and using Fileforge's react-print library and API, we can easily convert the form into a PDF.

### Easy and Dynamic Layout

Placing form inputs in React is easy! With a little bit of CSS (or using [Tailwind](/blog/react-tailwind-dynamic-pdf/)). We can create a dynamic layout that adapts to the user's screen size. We may even add or remove some fields based on the user's input.

### Eliminate Manual Tagging

When dealing with E-Signature services, you often have to indicate form and signature fields with special tags such as hidden text. This is hard to control and you don't have precise control on the resulting input. It just feels wrong? Given that we generate our PDF from a React/HTML model, we know where the boxes are (and Fileforge will generate them for you!). Then it's as easy as 1-2-3 to add a signature field.

## Creating a PDF Form with react-print

Let's see how we can create a simple PDF form with React and react-print. We will use the following libraries:

- [@fileforge/react-print](https://www.npmjs.com/package/@fileforge/react-print): A React library that converts React to HTML ready for PDF generation.
- [@fileforge/client](https://www.npmjs.com/package/@fileforge/client): A client library to interact with Fileforge's API. Fileforge is free for 500 API calls per month. [Get your API key now](https://app.fileforge.com/).

### Setting up our Render Function

> [!note] Get your API Key
> Fileforge's API is free for 500 calls per month. [Get your API key now](https://app.fileforge.com/)

Let's set up a simple render file that will generate the PDF file. This could be adapted to other languages or frameworks, but we will use React for this example. Here is a sample file, named `render.tsx`:

```jsx
import fs from "fs";
import { pipeline } from "stream/promises";

import React from "react";

import { FileforgeClient } from "@fileforge/client";
import { compile } from "@fileforge/react-print";

const onedoc = new FileforgeClient({
  apiKey: process.env.FILEFORGE_API_KEY!,
});

(async () => {
  const file = await onedoc.pdf.generate(await compile(<h1>Hello World!</h1>), {
    options: {},
  });

  await pipeline(file, fs.createWriteStream("form.pdf"));
})();
```

We can run this file easily using `tsx`:

```bash
npx tsx render.tsx
```

You should now have a `form.pdf` file in your directory!

### Setting up the Document

Let's change our `render.tsx` file to include a `<Form/>` component:

```jsx
import fs from "fs";
import { pipeline } from "stream/promises";

import React from "react";

import { FileforgeClient } from "@fileforge/client";
import { compile } from "@fileforge/react-print";

import { Form } from './Form.tsx'

const onedoc = new FileforgeClient({
  apiKey: process.env.FILEFORGE_API_KEY!,
});

(async () => {
  const file = await onedoc.pdf.generate(await compile(<Form />), {
    options: {},
  });

  await pipeline(file, fs.createWriteStream("form.pdf"));
})();
```

Let's also create a simple form in the `Form.tsx` file:

```jsx
import React from "react";
import { Tailwind } from "@fileforge/react-print";

const LineInput = ({ label }) => {
  return (
    <div className="flex items-center my-2">
      <div className="font-bold mr-4">{label}</div>
      <div className="grow relative">
        <input className="w-full border-b-2 border-black h-6" />
      </div>
    </div>
  );
};

export const Form = () => {
  return (
    <Tailwind>
      <h1 className="text-2xl font-bold text-center mb-4">Registration Form</h1>
      <p className="mb-4">
        Thanks for your interest in the next event! Please fill out the form
        below to register for the event. We look forward to seeing you there!
      </p>
      <LineInput label="Name" />
      <div className="flex items-center">
        <div className="basis-0 grow mr-4">
          <LineInput label="Email" />
        </div>
        <div className="basis-0 grow">
          <LineInput label="Email" />
        </div>
      </div>
      <p className="my-4">
        I hereby agree to the terms and conditions of the event and give my
        consent to receive marketing communications from the event organizers.
      </p>
      <label htmlFor="DocusignSignHere" className="block mt-4">
        Signature
      </label>
      <input
        name="DocusignSignHere"
        className="w-72 border-b-2 border-black h-24 bg-gray-50"
      />
    </Tailwind>
  );
};
```

We have created a simple React component for the form inputs, as it will make it easier to add more fields later on. We have also added a signature field at the end of the form.

> [!note] Magic Input Names
> As you may have noticed, the signature field has a special name: `DocusignSignHere`. This is a special name that Fileforge will pass when the document is generated. You can use this name to place the signature field in the right place using DocuSign.

### Generating the PDF Form using Fileforge

Let's run the `render.tsx` file again:

```bash
npx tsx render.tsx
```

We now have a `form.pdf` file in our directory! You can open it in your favorite PDF viewer and see the form we just created.

![Preview of the Generated PDF Form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7vlouh6m4vl418xa91r.jpg)

### Transforming the PDF Form into a Signable Document

The PDF file returned by Fileforge contains all our fields as inputs. However, we want the signature field to be replaced by a `SignHere` tag in DocuSign.

DocuSign provides an easy way to convert PDF fields into DocuSign fields using the [PDF Field Transformation](https://developers.docusign.com/docs/esign-rest-api/esign101/concepts/tabs/pdf-transform/) feature. Other providers do not support this feature, so you will have to manually place the signature field in the right place.

- DocuSign: [PDF Field Transformation (Reference)](https://developers.docusign.com/docs/esign-rest-api/esign101/concepts/tabs/pdf-transform/), [with multiple signees](https://stackoverflow.com/questions/24189713/docusign-transform-pdf-fields-for-multiple-recipients)
- HelloSign: does not support field transformation
- YouSign: does not support field transformation

## Conclusion

Using `@fileforge/react-print` and the Fileforge API, we were able to create a simple PDF Form in just minutes, and we could hand it off to DocuSign for signature. This is a great way to create signable documents for your users, and it's easy to customize the form to your needs.

This post was originally authored on the [Fileforge blog](https://www.fileforge.com/blog/generate-signable-pdf-forms-with-react/).