---
title: "React PDF viewer with pdfjs-dist and Next.js (2026): Step-by-step tutorial"
canonical_url: "https://www.nutrient.io/blog/how-to-build-a-reactjs-viewer-with-pdfjs/"
md_url: "https://www.nutrient.io/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md"
last_updated: "2026-07-07T19:46:30.644Z"
description: "Build a React PDF viewer using pdfjs-dist and Next.js — installation, worker setup, multipage rendering, troubleshooting, and when to switch to a commercial SDK."
---

**TL;DR**

Learn how to build a PDF viewer in React using pdfjs-dist (the official PDF.js npm package) and Next.js, and see how it compares to Nutrient’s commercial SDK.

- **[pdfjs-dist (open source)](#setting-up-a-react-project-with-pdfjs-dist)** — Lightweight and flexible, but requires manual setup for things like annotations, search, navigation, or multipage viewing.

- **[Nutrient SDK](#setting-up-nutrient-web-sdk-with-nextjs)** — Provides 30+ built-in features, including annotation tools, PDF editing, form filling, and Office file support, all with minimal configuration.

This guide walks you through both setups with working code samples, performance tips, and a side-by-side comparison to help you choose the right tool for your use case.

In this tutorial, you’ll learn how to create a React PDF viewer using [`pdfjs-dist`](https://www.npmjs.com/package/pdfjs-dist), the official npm distribution of [PDF.js](https://mozilla.github.io/pdf.js/) — Mozilla’s open source JavaScript library for rendering PDF documents. You’ll use Next.js, a popular React framework, to demonstrate how to integrate pdfjs-dist into a React application.

You’ll first create a PDF viewer using pdfjs-dist and then compare it to a viewer built with [Nutrient Web SDK](https://www.nutrient.io/guides/web.md). If you need to go beyond basic rendering, Nutrient lets you:

- Ship faster — Drop in a [prebuilt, customizable user interface (UI)](https://www.nutrient.io/guides/web/viewer.md) instead of building viewer chrome from scratch.

- Let users annotate — Give users [17+ annotation tools](https://www.nutrient.io/guides/web/annotations.md) (highlight, comment, draw, stamp) without writing a custom toolbar.

- Handle more than PDFs — Open [MS Office documents](https://www.nutrient.io/guides/web/viewer/office-documents.md) and [images](https://www.nutrient.io/guides/web/viewer/images.md) in the same viewer, so you don’t need a separate conversion pipeline.

- Add forms and signatures — Support [PDF form filling](https://www.nutrient.io/guides/web/forms.md) and [digital signatures](https://www.nutrient.io/guides/web/signatures.md) without custom code.

- Collaborate in real time — Enable [live multiuser editing](https://www.nutrient.io/guides/web/instant-synchronization.md) without building your own sync layer.

## Introduction to PDF.js and its capabilities

[PDF.js](https://mozilla.github.io/pdf.js/) is an open source JavaScript library developed by Mozilla that renders PDF documents directly in web browsers. It’s distributed on npm as [`pdfjs-dist`](https://www.npmjs.com/package/pdfjs-dist). PDF.js covers most common PDF viewing needs, including text selection, zooming, and page navigation.

### Why choose PDF.js for React PDF viewing?

PDF.js works well in React applications. Installing pdfjs-dist via npm gives you the core rendering engine and web worker scripts. The web worker approach keeps rendering off the main thread. The project has an active contributor base and frequent releases.

### Integrating a PDF.js viewer with React

PDF.js is organized into three main layers:

- **Core** — Handles the parsing of the binary PDF file. This layer isn’t usually relevant to users, as the library uses it internally.

- **Display** — Uses the core layer and exposes a more straightforward API to render PDFs and expose details.

- **Viewer** — Built on top of the display layer, this is the UI for the PDF viewer in Firefox and the other browser extensions within the project.

## Prerequisites

- Node.js (v18 or later) and npm installed on your machine

- Basic familiarity with React and the command line

## Setting up a React project with pdfjs-dist

Before rendering PDFs, set up your development environment. You’ll use Next.js, a popular React framework, to create the project structure.

1. Run the following command to scaffold a new Next.js project inside a folder named `pdfjs-demo`:

   ```bash

   npx create-next-app@latest pdfjs-demo
   ```

   When prompted, press **Enter** to accept the default options. This will set up the project with the recommended settings, allowing you to focus on integrating PDF.js with Next.js.

2. Next, navigate into your project directory and install the distribution build of PDF.js, available on npm as [`pdfjs-dist`](https://www.npmjs.com/package/pdfjs-dist):

   ```shell

   cd pdfjs-demo && npm install pdfjs-dist
   ```

3. PDF.js uses web workers to offload the parsing and rendering of PDFs to a background thread, improving performance. To keep the setup simple, manually copy the worker script to the `public` directory, which is served statically by Next.js. Run the following command:

   ```shell

   cp./node_modules/pdfjs-dist/build/pdf.worker.min.mjs./public/
   ```

   To automate this step, you can add a script to your `package.json` file. This script will copy the worker file whenever you run the dev or build commands:

   ```diff

   "scripts": {
   +  "copy-assets": "cp./node_modules/pdfjs-dist/build/pdf.worker.min.mjs./public/",
   -  "dev": "next dev",
   -  "build": "next build",
   +  "dev": "npm run copy-assets && next dev",
   +  "build": "npm run copy-assets && next build",
   }
   ```

   This copies the worker script to the public directory on every dev or build run.

### Rendering a PDF in the application

With the setup complete, you can now implement the functionality to render a PDF. Start by creating a React component in the `src/app/page.js` file. This component will load a PDF file and render its first page on a canvas.

The following code defines a React component that uses the `useEffect` hook to load and render the first page of a PDF document on a canvas:

```js

"use client";
import { useEffect, useRef } from "react";

export default function App() {
  const canvasRef = useRef(null);
  const renderTaskRef = useRef(null); // Ref to store the current render task.

  useEffect(() => {
    let isCancelled = false;

    (async function () {
      // Import pdfjs-dist dynamically for client-side rendering.
      const pdfJS = await import("pdfjs-dist");

      // Set up the worker.
      pdfJS.GlobalWorkerOptions.workerSrc =
        window.location.origin + "/pdf.worker.min.mjs";

      // Load the PDF document.
      const pdf = await pdfJS.getDocument("example.pdf").promise;

      // Get the first page.
      const page = await pdf.getPage(1);
      const viewport = page.getViewport({ scale: 1.5 });

      // Prepare the canvas.
      const canvas = canvasRef.current;
      const canvasContext = canvas.getContext("2d");
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      // Ensure no other render tasks are running.
      if (renderTaskRef.current) {
        await renderTaskRef.current.promise;
      }

      // Render the page into the canvas.
      const renderContext = { canvasContext, viewport };
      const renderTask = page.render(renderContext);

      // Store the render task.
      renderTaskRef.current = renderTask;

      // Wait for rendering to finish.
      try {
        await renderTask.promise;
      } catch (error) {
        if (error.name === "RenderingCancelledException") {
          console.log("Rendering cancelled.");
        } else {
          console.error("Render error:", error);
        }
      }

      if (!isCancelled) {
        console.log("Rendering completed");
      }
    })();

    // Cleanup function to cancel the render task if the component unmounts.
    return () => {
      isCancelled = true;
      if (renderTaskRef.current) {
        renderTaskRef.current.cancel();
      }
    };
  }, []);

  return <canvas ref={canvasRef} style={{ height: "100vh" }} />;
}

```

The `example.pdf` file in the code above is present in the `public` directory. The `useEffect` hook with no dependencies gets executed once, just after the component is first rendered.

Note that the component tracks the current render task using a `ref` (`renderTaskRef`) and ensures that multiple render operations don’t overlap. If a new render task starts while the previous one is still running, the new task waits for the previous one to complete.

You can now run the application using `npm run dev`, and the application will open on the `localhost:3000` port.

As you can see, you can only display the first page of your document by default. If you need any other functionality — like page navigation, search, or annotations — you’ll have to implement it yourself.

### Handling common issues with PDF.js in React

When integrating PDF.js into a React application, developers may face several challenges. Here are common issues and how to fix them.

#### Rendering issues

**Problem**

PDF.js relies on a `<canvas>` element to render PDF pages. Issues often arise with canvas size, scaling, and responsiveness within React components.

**Solutions**

- **Proper sizing** — Ensure the canvas element is correctly sized to fit its container. Use CSS or inline styles to set the dimensions, and consider using React’s `useEffect` to adjust the size based on the window or container size.

- **Scaling** — PDF.js provides scaling options to render PDFs at different zoom levels. Configure the scale factor properly to ensure the content is rendered clearly and fits within the viewable area.

- **Viewport management** — Use PDF.js’s viewport settings to manage how pages are displayed. Adjust the viewport based on the container size or user interactions to maintain a responsive design.

  Example code:

```jsx

useEffect(() => {
  const renderPage = (pageNumber) => {
    pdf.getPage(pageNumber).then((page) => {
      const viewport = page.getViewport({ scale: 1.5 });
      const canvas = canvasRef.current;
      const context = canvas.getContext("2d");
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      const renderContext = {
        canvasContext: context,
        viewport: viewport,
      };
      page.render(renderContext);
    });
  };

  renderPage(1);
}, []);

```

#### Worker setup

**Problem**

PDF.js uses web workers to handle PDF rendering tasks off the main thread. Incorrect setup or configuration of these workers can lead to performance issues or failures in rendering.

**Solutions**

- **Worker path** — Ensure the path to the PDF.js worker file is correctly specified. The worker script must be accessible from the client-side.

- **Web worker configuration** — Configure PDF.js to use web workers by setting the `workerSrc` property correctly. This can be done in your React component or globally in your application setup.

Example code:

```jsx

import * as pdfjsLib from "pdfjs-dist";
pdfjsLib.GlobalWorkerOptions.workerSrc = "/path-to/pdf.worker.min.mjs";

```

#### Cross-browser compatibility

**Problem**

Different browsers may have varying levels of support for HTML5 features used by PDF.js, leading to inconsistencies in rendering or functionality.

**Solutions**

- **Testing** — Regularly test your application on multiple browsers (Chrome, Firefox, Safari, Edge) to ensure consistent behavior and appearance.

- **Polyfills** — Use polyfills for missing or inconsistent features in certain browsers. This can help ensure compatibility across different environments.

- **Feature detection** — Implement feature detection to provide fallback solutions or graceful degradation if certain features aren’t supported.

Example code:

```jsx

if (!("HTMLCanvasElement" in window)) {
  console.error("Canvas not supported");
  // Provide fallback or notification.
}

```

### Troubleshooting pdfjs-dist in Next.js

If you run into issues integrating pdfjs-dist with Next.js, here are the most common problems and how to fix them.

#### Worker file not found (404)

**Problem** — The browser console shows a 404 error for `pdf.worker.min.mjs`.

**Fix** — Make sure you’ve copied the worker file to your `public/` directory. The path in `workerSrc` must match the actual file location:

```js

// Correct — file must exist at public/pdf.worker.min.mjs.
pdfJS.GlobalWorkerOptions.workerSrc = "/pdf.worker.min.mjs";

```

If you upgraded pdfjs-dist, the worker file name may have changed. Re-run the copy command:

```shell

cp./node_modules/pdfjs-dist/build/pdf.worker.min.mjs./public/

```

#### Missing “use client” directive

**Problem** — Next.js throws a server-side rendering error because pdfjs-dist accesses browser APIs (`window`, `document`, `canvas`) that don’t exist on the server.

**Fix** — Add `"use client"` at the top of any component that imports or uses pdfjs-dist:

```js

"use client";
import { useEffect, useRef } from "react";
// Now safe to use pdfjs-dist here.

```

#### Version mismatch between pdfjs-dist and its worker

**Problem** — The viewer loads but pages render as blank, or the console shows `Setting up fake worker` warnings.

**Fix** — The pdfjs-dist package version and the worker script version must match exactly. After upgrading, always recopy the worker file and confirm the versions align:

```shell

npm ls pdfjs-dist
cp./node_modules/pdfjs-dist/build/pdf.worker.min.mjs./public/

```

#### Canvas hydration mismatch

**Problem** — Next.js warns about a hydration mismatch because the server-rendered HTML doesn’t include canvas content.

**Fix** — Wrap your PDF rendering in a dynamic import with SSR disabled, or use conditional rendering:

```jsx

import dynamic from "next/dynamic";

const PDFViewer = dynamic(() => import("./PDFViewer"), {
  ssr: false,
});

```

These issues are specific to using raw pdfjs-dist. With [Nutrient Web SDK](https://www.nutrient.io/guides/web.md), worker configuration, SSR handling, and asset management are handled automatically — so you can focus on building your application instead of debugging integration issues.

## Setting up Nutrient Web SDK with Next.js

If the pdfjs-dist setup above feels like a lot of work for just displaying a single page, Nutrient’s [React PDF viewer](https://www.nutrient.io/guides/web/viewer.md) gives you a production-ready viewer — with [annotations](https://www.nutrient.io/guides/web/annotations.md), [form filling](https://www.nutrient.io/guides/web/forms.md), [signatures](https://www.nutrient.io/guides/web/signatures.md), [Office file support](https://www.nutrient.io/guides/web/viewer/office-documents.md), and [real-time collaboration](https://www.nutrient.io/guides/web/instant-synchronization.md) — without building any of it yourself.

Follow the steps below to set it up in the same amount of time.

1. Start a new project using `create-next-app`:

   ```bash

   npx create-next-app@latest nutrient-demo
   cd nutrient-demo
   ```

2. In `app/layout.js`, load Nutrient Web SDK from the CDN using Next.js’s `<Script>` component. No extra dependencies or webpack configuration are needed:

   ```jsx

   import Script from "next/script";

   export default function RootLayout({ children }) {
     return (
       <html lang="en">
         <body>
           <Script
             src="https://cdn.cloud.nutrient.io/pspdfkit-web@1.17.0/nutrient-viewer.js"
             strategy="beforeInteractive"
           />
           {children}
         </body>
       </html>
     );
   }
   ```

3. Render a PDF in `app/page.js`:

   ```js

   "use client";

   import { useEffect, useRef } from "react";

   export default function Home() {
     const containerRef = useRef(null);

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

       if (container && window.NutrientViewer) {
         window.NutrientViewer.load({
           container,
           document: "example.pdf", // Place this file in the public/ directory.
         });
       }

       return () => {
         if (window.NutrientViewer && container) {
           window.NutrientViewer.unload(container);
         }
       };
     }, []);

     return (
       <div ref={containerRef} style={{ height: "100vh", width: "100%" }} />
     );
   }
   ```

4. Start the development server:

   ```bash

   npm run dev
   ```

Visit `http://localhost:3000`, where you’ll see the PDF rendered using Nutrient Web SDK.

That’s it — no webpack plugins, no asset copying, no extra build scripts. The CDN handles loading the SDK and its assets automatically.

### Performance and security best practices for React PDF viewers

Follow these practices when building a React PDF viewer:

- **Use a custom PDF worker URL** — Offload heavy parsing and rendering tasks to a separate thread to keep the UI responsive.

- **Serve over HTTPS** — Always deliver your app and PDF files over HTTPS to protect against tampering and interception.

- **Apply a Content Security Policy (CSP)** — Limit allowed sources for scripts, workers, and fonts to mitigate XSS attacks.

- **Enable a Web Application Firewall (WAF)** — Add an extra security layer to detect and block common exploits at the network level.

[Nutrient](https://www.nutrient.io/security/) adds encryption, CSP support, and secure deployment guidance for production use.

## pdfjs-dist vs. Nutrient: Side-by-side comparison

The table below compares pdfjs-dist and Nutrient by what you can deliver to your users, not just what each library includes.

| What you need to deliver             | pdfjs-dist                                                            | Nutrient SDK                                                                |
| ------------------------------------ | --------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Display a PDF in the browser         | Manual canvas setup, worker configuration, and render-task management | One-line [`NutrientViewer.load()`](https://www.nutrient.io/guides/web/viewer/) call with built-in UI |
| Let users annotate documents         | Build a custom toolbar and annotation engine from scratch             | [17+ annotation tools](https://www.nutrient.io/guides/web/annotations.md) ready to use               |
| Fill and submit PDF forms            | Not supported — you’d need a separate library                         | [Built-in form filler](https://www.nutrient.io/guides/web/forms.md) with validation       |
| Collect signatures                   | Not supported                                                         | [Digital and electronic signatures](https://www.nutrient.io/guides/web/signatures.md)      |
| Open Office files (DOCX, XLSX, PPTX) | Not supported — requires a server-side conversion step                | [Client-side Office viewing](https://www.nutrient.io/guides/web/viewer/office-documents.md) in the same viewer        |
| Enable real-time collaboration       | Build your own sync layer with WebSockets or CRDT                     | [Built-in real-time sync](https://www.nutrient.io/guides/web/instant-synchronization.md)                          |
| Search text inside a PDF             | Implement text layer extraction and search UI manually                | Built-in search with highlighting                                           |
| Go to production with confidence     | You maintain rendering, workers, and cross-browser fixes              | Dedicated support team and [enterprise-grade security](https://www.nutrient.io/security/)            |

### When to use pdfjs-dist vs. Nutrient

**Choose pdfjs-dist if:**

- You only need to display PDFs — no annotations, forms, or signatures.

- You want full control over the rendering pipeline and UI.

- Your team has the bandwidth to build and maintain custom viewer features.

- You’re building a lightweight prototype or internal tool.

**Choose Nutrient if:**

- You need annotations, form filling, or digital signatures and don’t want to build them yourself.

- You need to open Office files or images in the same viewer as PDFs.

- You’re on a deadline and want a production-ready viewer without custom code.

- You need enterprise support, SLAs, or compliance guarantees.

- You want real-time collaboration without building a sync layer.

## Conclusion

In this tutorial, you built a React PDF viewer two ways: first with pdfjs-dist, where you configured workers, managed canvas rendering, and handled cleanup manually; then with [Nutrient Web SDK](https://www.nutrient.io/guides/web/viewer.md), where a single `load()` call gave you a complete viewer with annotations, forms, and signatures included.

pdfjs-dist is a solid choice when you only need to display PDFs and want full control over every detail. But if your users need to annotate, fill forms, sign documents, or collaborate — and you’d rather ship those features this week instead of building them over the next quarter — [Nutrient’s PDF SDK](https://www.nutrient.io/sdk/) handles all of that with no extra build work. For a full feature comparison, see our [PDF.js alternative](https://www.nutrient.io/sdk/vs/pdfjs/) page.

[Try it for free](https://www.nutrient.io/try/), or [see the live demo](https://www.nutrient.io/demo) to explore what’s included.

For other ways to view PDFs in React, see [how to build a React PDF viewer with Nutrient](https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer.md), the [react-pdf library tutorial](https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md), or [how to build a React file viewer](https://www.nutrient.io/blog/how-to-build-a-reactjs-file-viewer.md).

We created similar how-to blog posts using different web frameworks and libraries:

- [How to build an Angular PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs/)

- [How to build a Vue.js PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs/)

- [How to build a jQuery PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-a-jquery-pdf-viewer-with-pdfjs/)

- [How to build a Bootstrap 5 PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-a-bootstrap5-pdf-viewer-with-pdfjs/)

- [How to build an Electron PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-an-electron-pdf-viewer-with-pdfjs/)

- [How to build a TypeScript PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-a-typescript-pdf-viewer-with-pdfjs/)

- [How to build a JavaScript PDF viewer with PDF.js](https://www.nutrient.io/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)

## FAQ

#### What is pdfjs-dist, and how does it relate to PDF.js?

`pdfjs-dist` is the official npm package for PDF.js, Mozilla’s open source PDF rendering library. It includes the prebuilt display and worker layers, so you can install it with `npm install pdfjs-dist` and start rendering PDFs in your React, Next.js, or vanilla JavaScript project without building PDF.js from source.

#### Why do I need to use a worker script with PDF.js?

PDF.js uses web workers to handle the heavy lifting of PDF parsing and rendering in a separate thread. This prevents the main thread from being blocked, keeping the UI responsive during rendering.

#### Can I customize the appearance and functionality of the PDF viewer?

Yes. You can customize the PDF viewer by styling the components with CSS and adding features like text search, annotations, and custom navigation controls using the PDF.js API.

#### What are some common challenges when building a PDF viewer with React.js and PDF.js?

Common challenges include managing state and performance, handling large or complex PDF documents, ensuring cross-browser compatibility, and implementing advanced features like text extraction and annotations.

#### How do I migrate from PDF.js to Nutrient?

See our step-by-step [migration guide](https://www.nutrient.io/guides/web/about/migration-guides/migrating-from-mozilla-pdfjs.md) for side-by-side code comparisons covering viewer setup, search, annotations, forms, and more.

#### What is the Nutrient SDK, and how is it different from PDF.js?

The Nutrient SDK is a commercial PDF library designed for developers who need advanced features like annotations, form filling, digital signatures, collaboration, and support for Office and image files. Unlike PDF.js, which requires manual implementation for most features, Nutrient offers more than 30 out-of-the-box tools with minimal configuration.

#### How do I use the Nutrient SDK in a React or Next.js app?

You can integrate the Nutrient SDK by installing the `@nutrient-sdk/viewer` package and including its script in your layout using Next.js’s `<Script>` component. Then, use the `NutrientViewer.load()` method to render a PDF or DOCX inside a React component. We provide full instructions and copy-ready code samples in the tutorial.

#### What features does the Nutrient SDK support that PDF.js doesn’t?

The Nutrient SDK includes built-in support for annotations, PDF editing, form creation and filling, electronic and digital signatures, PDF/A generation, document redaction, real-time collaboration, and Office document viewing — features that require significant custom development in PDF.js.

#### Is Nutrient secure and compliant for enterprise use?

Yes. Nutrient supports encryption, CSP headers, secure deployment practices, and common compliance standards. Detailed guidance is available in [our security documentation](https://www.nutrient.io/security/).

#### How do I fix pdfjs-dist worker errors in Next.js?

The most common cause is a missing or mismatched worker file. Make sure you copy the worker script from `node_modules/pdfjs-dist/build/pdf.worker.min.mjs` to your `public/` directory, and that the version matches your installed pdfjs-dist package. Also ensure your component includes `"use client"` at the top, since pdfjs-dist requires browser APIs that aren’t available during server-side rendering.

#### What is the difference between pdfjs-dist and react-pdf?

`pdfjs-dist` is the raw PDF.js library from Mozilla — it gives you low-level control over PDF rendering via canvas but requires you to build the UI yourself. `react-pdf` (by wojtekmaj) is a React wrapper around pdfjs-dist that provides `<Document>` and `<Page>` components for easier integration. Both are open source and limited to rendering; neither include annotations, form filling, or signatures.

#### Can I try the Nutrient SDK for free?

Yes. Nutrient offers a [free trial](https://www.nutrient.io/try/) when you sign up. You can evaluate all major features — including viewing, annotation, form filling, and PDF export — directly in your local or production environment.
---

## 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)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.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)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Viewer](/blog/document-viewer.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.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 React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.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 Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.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 Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.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)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Online Document Viewer](/blog/online-document-viewer.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 React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.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 Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [or](/blog/sample-blog-updated.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

