---
title: "How to create a React signature pad"
canonical_url: "https://www.nutrient.io/blog/how-to-create-a-react-js-signature-pad/"
md_url: "https://www.nutrient.io/blog/how-to-create-a-react-js-signature-pad.md"
last_updated: "2026-07-24T20:39:08.462Z"
description: "Build a signature pad in React using Nutrient Web SDK. This step-by-step guide covers how to draw, insert, and programmatically add signatures to PDF documents."
---

**TL;DR**

Learn how to build a signature pad in a React.js app using Nutrient Web SDK. This guide walks you through setting up a project with Vite, integrating Nutrient’s PDF viewer, and adding both ink and image signatures — manually via the user interface (UI) or programmatically via code. You’ll also learn how to create interactive signature fields. Try the [demo](https://www.nutrient.io/demo/) or [start your free trial](https://www.nutrient.io/sdk/web/getting-started.md).

## What is a React.js signature pad?

A signature pad is a graphical interface that can be inserted into documents your users need to sign. It enables them to draw their signatures on a document using their mouse, electronic pens, or dedicated signing devices. It also enables saving signatures as images and vice versa.

Signature pads are used in web applications that need an applicant’s handwritten signature, such as when:

- Adding signatures to ID cards or official documents

- Signing forms, contracts, or other financial and legal documentation

- Signing bills, receipts, and invoices

## Why build a React.js signature pad?

The conventional way of signing documents — using pen and paper — can be inefficient. This is especially true if you have to sign PDF documents and the recipient isn’t physically present; you then have to print, sign, and scan the document before sending it to the receiver.

Replacing signed paper documentation with an electronic signature process by adding a signature pad to your PDFs allows organizations to operate more efficiently, and it can help them save time, resources, and money.

Nutrient helps you create, edit, view, annotate, and sign PDF documents in your React.js applications. You can customize the layout based on your specific requirements.

## Nutrient React.js library

We offer a commercial [React.js PDF library](https://www.nutrient.io/guides/web/signatures.md) that can easily be integrated into your web application. It has a rich set of features, including:

- A prebuilt and polished user interface (UI)

- Multiple annotation tools

- Support for various document formats

- Dedicated support from engineers

Nutrient includes comprehensive documentation and a user interface for PDF editing and annotation.

## Requirements

- [Node.js](http://nodejs.org/) installed on your computer.

- A code editor of your choice.

- A package manager compatible with npm.

### Creating a new React project

Use [`vite`](https://vite.dev/) to scaffold out a simple React application:

```bash

npm create vite@latest nutrient-react-example -- --template react
cd nutrient-react-example

```

### Install Nutrient Web SDK

Next, install the `@nutrient-sdk/viewer` package:

```bash

npm install @nutrient-sdk/viewer

# or

yarn add @nutrient-sdk/viewer

# or

pnpm install @nutrient-sdk/viewer

```

### CSS setup requirements

**Important**: Nutrient Web SDK requires that the container has an explicit width and height. The container cannot be 0×0 pixels or the SDK will fail to initialize.

For new Vite projects, remove conflicting CSS from your `src/index.css` file:

```css

/* src/index.css - Remove these properties from body */
body {
  /* DELETE: */
  display: flex;
  /* DELETE: */
  place-items: center;
}

```

The default Vite React template includes CSS that interferes with container dimensions. Removing these properties ensures the PDF viewer container renders properly.

### Displaying a PDF

Now that everything is set up, you’ll render a PDF using the Nutrient SDK.

Basic usage in `App.tsx`:

```tsx

import { useEffect, useRef } from "react";

function App() {
  const containerRef = useRef(null);

  useEffect(() => {
    const container = containerRef.current;
    let cleanup = () => {};

    (async () => {
      const NutrientViewer = (await import("@nutrient-sdk/viewer")).default;

      // Ensure there's only one `NutrientViewer` instance.
      NutrientViewer.unload(container);

      if (container && NutrientViewer) {
        NutrientViewer.load({
          container,
          document: "https://www.nutrient.io/downloads/nutrient-web-demo.pdf",
        });
      }

      cleanup = () => {
        NutrientViewer.unload(container);
      };
    })();

    return cleanup;
  }, []);

  return <div ref={containerRef} style={{ height: "100vh", width: "100vw" }} />;
}

export default App;

```

Key points about the code above:

- `NutrientViewer.unload()` ensures any existing instance is cleaned up before loading a new one.

- `NutrientViewer.load()` is called without `await` — it loads asynchronously in the background.

- The cleanup function in `useEffect` ensures proper unloading when the component unmounts.

- It uses a publicly accessible PDF for testing.

To use your own PDF file, place it in the `public` folder (e.g. `public/example.pdf`) and change the document path to `"/example.pdf"`.

**Note**: The SDK loads assets from the CDN by default. If you’re [self-hosting the SDK assets](https://www.nutrient.io/guides/web/self-host-assets.md), add a `baseUrl` property to your configuration.

Once everything is configured, start your app:

```bash

npm run dev

```

You’ll now see the Nutrient Web SDK UI rendering your PDF inside the browser!

Note that because Nutrient is a commercial product, you’ll see a Nutrient Web SDK evaluation notice on the document. To get a license key, contact [Sales](https://www.nutrient.io/contact-sales/).

## 1. Adding eSignatures via the Nutrient UI

Users can annotate, edit, and sign PDF documents through the Nutrient interface. This section shows how to sign PDF documents using the UI.

1. In the Nutrient web interface, click the icon with the sign symbol.

2. Sign on the dialog box that appears. You can change the color of the pen, and Nutrient also allows you to draw your signature and insert an image or text as your signature.

3. You can then resize and change the position of the signature.

Next, you’ll learn how to sign documents programmatically in React.js.

## 2. Adding eSignatures programmatically in React.js

You can add two types of signatures to PDF documents: ink and image signatures. This section covers creating both signature types and adding signature fields to PDFs.

### Adding ink signatures in a React.js web application

Ink signatures are similar to signatures done using a pen on paper. In this use case, Nutrient provides a signature pad where you can draw your signature.

Update the `App.tsx` file to add an ink signature programmatically:

```tsx

import { useEffect, useRef } from "react";

function App() {
  const containerRef = useRef(null);

  useEffect(() => {
    const container = containerRef.current;
    let cleanup = () => {};

    (async () => {
      const NutrientViewer = (await import("@nutrient-sdk/viewer")).default;

      NutrientViewer.unload(container);

      if (container && NutrientViewer) {
        const instance = await NutrientViewer.load({
          container,
          document: "/example.pdf",
        });

        const annotation = new NutrientViewer.Annotations.InkAnnotation({
          pageIndex: 0,
          isSignature: true,
          lines: NutrientViewer.Immutable.List([
            NutrientViewer.Immutable.List([
              new NutrientViewer.Geometry.DrawingPoint({ x: 5, y: 5 }),
              new NutrientViewer.Geometry.DrawingPoint({ x: 95, y: 95 }),
            ]),
            NutrientViewer.Immutable.List([
              new NutrientViewer.Geometry.DrawingPoint({ x: 95, y: 5 }),
              new NutrientViewer.Geometry.DrawingPoint({ x: 5, y: 95 }),
            ]),
          ]),
          boundingBox: new NutrientViewer.Geometry.Rect({
            left: 0,
            top: 0,
            width: 100,
            height: 100,
          }),
        });

        const createdAnnotations = await instance.create(annotation);
        console.log(createdAnnotations);
      }

      cleanup = () => {
        NutrientViewer.unload(container);
      };
    })();

    return cleanup;
  }, []);

  return <div ref={containerRef} style={{ height: "100vh", width: "100vw" }} />;
}

export default App;

```

In the code above:

- `NutrientViewer.Annotations.InkAnnotation` creates an ink signature annotation.

- `isSignature: true` marks this as a signature (required for signature functionality).

- `lines` defines the drawing points that create the signature’s shape (an “X” in this example).

- `boundingBox` determines the position and size of the signature on the page.

- You can customize the coordinates in `DrawingPoint` and `boundingBox` to create different signature shapes and positions.![Ink Signature Example](@/assets/images/blog/2022/how-to-create-a-react-js-signature-pad/ink.png)

### Adding image signatures in a React.js web application

In this section, you’ll learn how to add images as signatures on PDF documents using Nutrient in a React.js web application.

Update the `App.tsx` file to add an image signature:

```tsx

import { useEffect, useRef } from "react";

function App() {
  const containerRef = useRef(null);

  useEffect(() => {
    const container = containerRef.current;
    let cleanup = () => {};

    (async () => {
      const NutrientViewer = (await import("@nutrient-sdk/viewer")).default;

      NutrientViewer.unload(container);

      if (container && NutrientViewer) {
        const instance = await NutrientViewer.load({
          container,
          document: "/example.pdf",
        });

        // Fetches the image via its URL.
        const request = await fetch("<image_url>"); // Replace <image_url> with the actual URL.
        const blob = await request.blob();
        const imageAttachmentId = await instance.createAttachment(blob);

        const annotation = new NutrientViewer.Annotations.ImageAnnotation({
          pageIndex: 0,
          isSignature: true,
          contentType: "image/jpeg",
          imageAttachmentId,
          description: "Image Description",
          boundingBox: new NutrientViewer.Geometry.Rect({
            left: 30,
            top: 20,
            width: 300,
            height: 150,
          }),
        });

        await instance.create(annotation);
      }

      cleanup = () => {
        NutrientViewer.unload(container);
      };
    })();

    return cleanup;
  }, []);

  return <div ref={containerRef} style={{ height: "100vh", width: "100vw" }} />;
}

export default App;

```![Image Signature Example](@/assets/images/blog/2022/how-to-create-a-react-js-signature-pad/image.png)

In the code snippet above:

- The code fetches an image from a URL, converts it to a blob, and creates an attachment.

- `ImageAnnotation` with `isSignature: true` creates an image-based signature.

- The `boundingBox` controls where the image signature appears on the page.

### Creating signature fields in PDF documents

Signature fields are interactive areas where users can click to add their signature. This is useful for forms and documents that require signatures.

Update the `App.tsx` file to create a signature field:

```tsx

import { useEffect, useRef } from "react";

function App() {
  const containerRef = useRef(null);

  useEffect(() => {
    const container = containerRef.current;
    let cleanup = () => {};

    (async () => {
      const NutrientViewer = (await import("@nutrient-sdk/viewer")).default;

      NutrientViewer.unload(container);

      if (container && NutrientViewer) {
        const instance = await NutrientViewer.load({
          container,
          document: "/example.pdf",
        });

        const widget = new NutrientViewer.Annotations.WidgetAnnotation({
          pageIndex: 0,
          boundingBox: new NutrientViewer.Geometry.Rect({
            left: 200,
            top: 200,
            width: 250,
            height: 150,
          }),
          formFieldName: "My signature form field",
          id: NutrientViewer.generateInstantId(),
        });

        const formField = new NutrientViewer.FormFields.SignatureFormField({
          name: "My signature form field",
          annotationIds: NutrientViewer.Immutable.List([widget.id]),
        });

        await instance.create([widget, formField]);
      }

      cleanup = () => {
        NutrientViewer.unload(container);
      };
    })();

    return cleanup;
  }, []);

  return <div ref={containerRef} style={{ height: "100vh", width: "100vw" }} />;
}

export default App;

```

In the code snippet above:

- `WidgetAnnotation` creates the visual signature field box on the page,

- `SignatureFormField` defines the form field properties,

- `formFieldName` links the widget to the form field,

- Users can click the signature field to open the signature pad and add their signature,

## Conclusion

Building a signature pad in React is straightforward with [Nutrient Web SDK](https://www.nutrient.io/sdk/web/).

In this tutorial, you learned how to:

- Set up a React project with Vite

- Integrate Nutrient’s viewer to load and display PDF documents

- Add ink and image-based signatures programmatically

- Create signature fields that users can interact with inside the browser

Whether you’re building a paperless onboarding experience, a contract-signing portal, or a document workflow, Nutrient provides tools to handle signatures securely.

[Explore the Nutrient demo](https://www.nutrient.io/demo)

Ready to go further?

- Explore [advanced form fields](https://www.nutrient.io/guides/web/forms/form-filling.md)

- Learn to [fill and sign PDF forms](https://www.nutrient.io/guides/web/signatures/fill-and-sign-forms.md)

Want to see it in action? Check out our [interactive demos](https://www.nutrient.io/demo/) or start a [free trial](https://www.nutrient.io/sdk/web/getting-started.md) to build your own signature-enabled document app today.

If you have questions or run into any issues, our [Support team](https://www.nutrient.io/support/request/) is always here to help.

## FAQ

#### What is a React signature pad?

A React signature pad is a user interface component that enables users to draw and save their signatures electronically in a React.js application.

#### Why use Nutrient for a React signature pad?

Nutrient provides a customizable signature pad with features for annotating and signing PDF documents in React.js.

#### How do I add a signature pad to my React project?

Start by creating a React project with Vite. Then install Nutrient and configure it to handle signature annotations in your PDF documents.

#### Can I add image signatures with Nutrient?

Yes. Nutrient enables you to add image signatures by fetching and embedding image files as annotations in your PDFs.

#### How can I create signature fields in a PDF with Nutrient?

You can create signature fields by using Nutrient’s API to add widget annotations and form fields, which users can interact with to sign documents digitally.
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [or](/blog/sample-blog-updated.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

