How to create a React signature pad

Table of contents

    In this post, you’ll learn how to create a signature pad for your React.js web application using the Nutrient library. You’ll first create a React.js project using Vite, and then you’ll install the Nutrient library to add a signature pad to PDF documents.
    How to create a React signature pad
    Summary

    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 or start your free trial.

    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 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

    Creating a new React project

    Use vite(opens in a new tab) to scaffold out a simple React application:

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

    Install Nutrient Web SDK

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

    Terminal window
    npm i @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:

    /* 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:

    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, add a baseUrl property to your configuration.

    Once everything is configured, start your app:

    Terminal window
    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.

    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:

    import { useEffect, useRef } from "react";
    53 collapsed lines
    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

    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:

    import { useEffect, useRef } from "react";
    49 collapsed lines
    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

    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:

    import { useEffect, useRef } from "react";
    47 collapsed lines
    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.

    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

    Ready to go further?

    Want to see it in action? Check out our interactive demos or start a free trial to build your own signature-enabled document app today.

    If you have questions or run into any issues, our Support team 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.

    Asaolu David

    Asaolu David

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    FREE TRIAL Ready to get started?