---
title: "Next.js PDF viewer with React-PDF and Nutrient SDK"
canonical_url: "https://www.nutrient.io/blog/how-to-build-a-nextjs-pdf-viewer/"
md_url: "https://www.nutrient.io/blog/how-to-build-a-nextjs-pdf-viewer.md"
last_updated: "2026-06-26T17:59:40.539Z"
description: "Learn how to build a client-side PDF viewer in a Next.js app using React-PDF and Nutrient Web SDK. This tutorial covers installing the SDK, handling SSR issues, and choosing the right tool for your needs."
---

**TL;DR**

Building a [PDF viewer](https://www.nutrient.io/sdk/solutions/viewing/) in a [Next.js](https://nextjs.org/) application can be tricky due to server-side rendering (SSR) constraints. This tutorial will walk through two solutions:

- Using [React-PDF](https://github.com/wojtekmaj/react-pdf), a lightweight open source library built on PDF.js.

- Using [Nutrient Web SDK](https://www.nutrient.io/guides/web/viewer.md), a commercial PDF viewer with features like annotation, redaction, and form filling.

You’ll learn how to set up each approach to avoid hydration errors, ensure fast client-side rendering, and deliver a reliable viewing experience.

## What is a Next.js PDF viewer?

A Next.js PDF viewer enables users to display and interact with PDF documents directly within a web browser — without needing to download the file or use third-party PDF applications. Since Next.js supports server-side rendering, integrating a [PDF viewer](https://www.nutrient.io/sdk/solutions/viewing/) requires careful handling to avoid hydration mismatches. A client-side viewer ensures compatibility and performance by loading the PDF only after the page has mounted on the client.

## How to build a PDF viewer in Next.js with React-PDF

By the end of this tutorial, you’ll have a PDF viewer with:

- Page navigation (Previous/Next buttons)

- A page counter display

- Responsive design

- Error handling for missing files

- Loading states

- Complete Next.js compatibility

### Prerequisites

Before starting, ensure you have:

- Node.js (version 20 or later)

- Basic knowledge of React and Next.js

- A text editor or IDE (VS Code recommended)

### Setting up your Next.js project

If you don’t yet have a Next.js project, follow these steps to create one.

#### Option 1 — Create a new Next.js project

```bash

npx create-next-app@latest my-pdf-viewer
cd my-pdf-viewer

```

When prompted, choose the following options:

- Would you like to use TypeScript? → **No**

- Would you like to use ESLint? → **Yes**

- Would you like to use Tailwind CSS? → **No** (you’ll use inline styles)

- Would you like to use `src/` directory? → **Yes**

- Would you like to use App Router? → **Yes**

- Would you like to use Turbopack for `next dev`? **Yes**

- Would you like to customize the default import alias? → **No**

#### Option 2 — Add to an existing project

If you already have a Next.js project, make sure it’s using App Router (Next.js 13+). You can check this by looking for an `app` directory in your project root.

#### Verify your setup

Start your development server to make sure everything is working:

```bash

npm run dev

```

Visit `http://localhost:3000` to see the default Next.js page.

### The challenge with React-PDF and Next.js

React-PDF relies on browser APIs that aren’t available during server-side rendering. This causes the infamous “DOMMatrix is not defined” error. You’ll solve this by creating a client-side-only [PDF viewer](https://www.nutrient.io/sdk/solutions/viewing/) using dynamic imports and proper component structure.

### Step 1 — Install dependencies

Navigate to your project directory and install the required package:

```bash

npm install react-pdf

```

### Step 2 — Project structure

Create the following file structure in your Next.js project:

```

src/
├── components/
│   ├── PDFViewerClient.js
│   └── PDFViewer.js
├── app/
│   └── page.js
├── next.config.js
└── public/
    └── example.pdf

```

### Step 3 — Create the PDF viewer client component

This component contains the actual PDF viewing logic and `react-pdf` imports:

```javascript

// components/PDFViewerClient.js

"use client";
import { useState } from "react";
import { Document, Page, pdfjs } from "react-pdf";
import "react-pdf/dist/Page/TextLayer.css";
import "react-pdf/dist/Page/AnnotationLayer.css";

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  "pdfjs-dist/build/pdf.worker.min.mjs",
  import.meta.url,
).toString();
const PDFViewerClient = () => {
  const [numPages, setNumPages] = useState(null);
  const [pageNumber, setPageNumber] = useState(1);

  const onDocumentLoadSuccess = ({ numPages }) => {
    setNumPages(numPages);
  };

  const goToPrevPage = () =>
    setPageNumber(pageNumber - 1 <= 1? 1 : pageNumber - 1);

  const goToNextPage = () =>
    setPageNumber(pageNumber + 1 >= numPages? numPages : pageNumber + 1);

  return (
    <div style={{ padding: "2rem" }}>
      <nav
        style={{
          marginBottom: "1rem",
          display: "flex",
          gap: "1rem",
          alignItems: "center",
        }}
      >
        <button
          onClick={goToPrevPage}
          disabled={pageNumber <= 1}
          style={{
            padding: "0.5rem 1rem",
            backgroundColor: pageNumber <= 1? "#ccc" : "#007bff",

            color: "white",
            border: "none",
            borderRadius: "4px",
            cursor: pageNumber <= 1? "not-allowed" : "pointer",
          }}
        >
          Prev
        </button>
        <button
          onClick={goToNextPage}
          disabled={pageNumber >= numPages}
          style={{
            padding: "0.5rem 1rem",
            backgroundColor: pageNumber >= numPages? "#ccc" : "#007bff",

            color: "white",
            border: "none",
            borderRadius: "4px",
            cursor: pageNumber >= numPages? "not-allowed" : "pointer",
          }}
        >
          Next
        </button>
        <p style={{ margin: 0, fontWeight: "bold", color: "#333" }}>

          Page {pageNumber} of {numPages || "..."}
        </p>
      </nav>

      <div
        style={{
          border: "1px solid #ccc",

          borderRadius: "4px",
          overflow: "hidden",
          display: "flex",
          justifyContent: "center",
        }}
      >
        <Document
          file="/example.pdf"
          onLoadSuccess={onDocumentLoadSuccess}
          loading={
            <div style={{ padding: "2rem", textAlign: "center" }}>
              Loading PDF...
            </div>
          }
          error={
            <div
              style={{
                padding: "2rem",
                textAlign: "center",
                color: "red",
              }}
            >
              Failed to load PDF. Please make sure the file exists in the public
              folder.
            </div>
          }
        >
          <Page
            pageNumber={pageNumber}
            renderTextLayer={true}
            renderAnnotationLayer={true}
            width={800}
          />
        </Document>
      </div>
    </div>
  );
};

export default PDFViewerClient;

```

### Step 4 — Create the PDF viewer wrapper

This wrapper ensures the PDF viewer only renders on the client side:

```javascript

// components/PDFViewer.js
"use client";
import dynamic from "next/dynamic";

// Dynamically import the PDF viewer client component.
const PDFViewerClient = dynamic(() => import("./PDFViewerClient"), {
  ssr: false,
  loading: () => (
    <div
      style={{
        padding: "2rem",
        textAlign: "center",
        fontSize: "1.2rem",
        color: "#333",

      }}
    >
      Loading PDF Viewer...
    </div>
  ),
});

const PDFViewer = () => {
  return <PDFViewerClient />;
};
export default PDFViewer;

```

The `dynamic()` function from Next.js loads components only on the client side, preventing SSR issues.

### Step 5 — Create the main page component

```javascript

// app/page.js
"use client";
import PDFViewer from "../components/PDFViewer";

export default function Home() {
  return (
    <div style={{ minHeight: "100vh", backgroundColor: "#f5f5f5" }}>

      <div
        style={{
          maxWidth: "1200px",
          margin: "0 auto",
          padding: "2rem",
          backgroundColor: "white",
          minHeight: "100vh",
        }}
      >
        <h1
          style={{
            textAlign: "center",
            marginBottom: "2rem",
            color: "#333",

          }}
        >
          PDF Viewer
        </h1>
        <PDFViewer />
      </div>
    </div>
  );
}

```

### Step 6 — Configure Next.js

Update your `next.config.js` file to handle canvas-related issues:

```javascript

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.alias = {...config.resolve.alias,
      canvas: false,
    };

    config.resolve.fallback = {...config.resolve.fallback,
      canvas: false,
    };

    return config;
  },
};

module.exports = nextConfig;

```

### Step 7 — Add your PDF file

Place your PDF file in the `public` folder and name it `example.pdf`. You can [download a sample PDF](https://www.nutrient.io/example.pdf) or use any PDF file you have.

### Step 8 — Run your application

Start your Next.js development server:

```bash

npm run dev

```

Visit `http://localhost:3000` to see your PDF viewer in action!

### How it works

This solution uses a three-layer approach to avoid SSR issues:

1. **PDFViewerClient.js** — Contains the actual React-PDF components and logic.

2. **PDFViewer.js** — A wrapper that ensures client-side-only rendering using Next.js dynamic imports with `ssr: false`.

3. **page.js** — The main page component that uses the PDF viewer.

### Customization options

#### Changing the PDF file

To use a different PDF file:

1. Place your PDF in the `public` folder

2. Update the `file` prop in the `Document` component:

```javascript

<Document
  file="/your-pdf-file.pdf"
  //... other props

>

```

#### Styling

You can customize the appearance by modifying the inline styles or by using CSS modules, Tailwind CSS, or styled components.

#### Adding more features

Consider adding these features:

- Zoom in/out functionality

- Page input field for direct navigation

- Download button

- Print functionality

- Thumbnail view

- Search functionality

### Troubleshooting

Common issues:

1. **“DOMMatrix is not defined”** — This solution prevents this error by avoiding SSR.

2. **PDF not loading** — Ensure your PDF file is in the `public` folder and the path is correct.

3. **Worker errors** — The PDF.js worker is loaded locally from `pdfjs-dist` via `import.meta.url`. Make sure your bundler can resolve the `.mjs` worker file (Next.js with Webpack or Turbopack handles this by default).

### Performance considerations

- Large PDF files may take longer to load

- Consider implementing lazy loading for multipage documents

- Use the `width` prop on the `Page` component to control rendering size

- Consider showing only one page at a time for better performance

### Looking for more advanced features?

While React-PDF is a great starting point for basic PDF rendering in a Next.js app, it doesn’t include higher-level capabilities like annotations, redactions, form filling, or real-time collaboration. If you’re building a more complex document workflow or need production-grade performance with a prebuilt UI, it’s worth exploring Nutrient Web SDK.

The next section walks you through setting up Nutrient’s fully featured PDF viewer in Next.js, designed specifically to handle enterprise use cases with ease.

## Nutrient Next.js PDF viewer

We offer a commercial [Next.js PDF viewer library](https://www.nutrient.io/guides/web/viewer.md) designed for teams that need advanced document capabilities out of the box. It’s easy to integrate, fully client side, and built to scale.

- A prebuilt UI for an improved user experience

- 15+ prebuilt annotation tools to enable document collaboration

- Support for more file types with client-side [PDF](https://www.nutrient.io/guides/web.md), [MS Office](https://www.nutrient.io/guides/web/viewer.md), and [image](https://www.nutrient.io/guides/web/viewer/images.md) viewing

- Dedicated support from engineers to speed up integration

### Example of our Next.js PDF viewer

To demo our [Next.js PDF viewer](https://www.nutrient.io/demo), upload a PDF, JPG, PNG, or TIFF file by clicking **Open Document** under the **Standalone** option (if you don’t see this option, select **Choose Example** from the dropdown). Once your document is displayed in the viewer, try drawing freehand, adding a note, or applying a crop or an eSignature.

### Step 1 — Set up your Next.js project

Start by creating a fresh Next.js app:

```bash

npx create-next-app@latest nutrient-pdf-viewer
cd nutrient-pdf-viewer

```

Use the default settings when prompted.

### Step 2 — Install the Nutrient SDK

Install the viewer package using npm:

```bash

npm install @nutrient-sdk/viewer

# or

yarn add @nutrient-sdk/viewer

# or

pnpm install @nutrient-sdk/viewer

```

This command installs the SDK locally, enabling access to the viewer distribution files.

### Step 3 — Copy the SDK assets

To run Nutrient in the browser, you need to expose the SDK assets publicly. Copy the required files into your project’s `public` directory:

```bash

cp -R./node_modules/@nutrient-sdk/viewer/dist/ public/nutrient-viewer

```

You should see a new folder structure like this:

```

/public
  /nutrient-viewer
    nutrient-viewer.js
    nutrient-viewer-lib/

```

To automate this in development and production builds, modify `package.json`:

```json

"scripts": {
  "copy-assets": "cp -R./node_modules/@nutrient-sdk/viewer/dist/ public/nutrient-viewer",
  "dev": "npm run copy-assets && next dev",
  "build": "npm run copy-assets && next build"
}

```

Add `public/nutrient-viewer/` to your `.gitignore` file to avoid committing binaries.

### Step 4 — Add a PDF file

Place a sample file like `document.pdf` in your `public` directory. You can use our [demo document](https://www.nutrient.io/example.pdf) as an example:

```

/public
  document.pdf

```

### Step 5 — Load the PDF viewer

Before you write code, here’s how it works:

1. **Global script injection** — Nutrient uses global variables, so you need to load the SDK script before any UI renders.

2. **Client-side rendering** — The viewer must be initialized in a React component with `useEffect` so that it only loads in the browser.

3. **Cleanup** — The viewer should be properly unloaded to avoid memory leaks.

The following section provides a step-by-step implementation.

#### 1. Register the viewer script in the layout

Edit `app/layout.tsx`:

```tsx

import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <Script
          src="/nutrient-viewer/nutrient-viewer.js"
          strategy="beforeInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

```

This ensures the SDK is loaded before your page component executes.

#### 2. Add the PDF viewer component

In `app/page.tsx` or `app/page.js`, render the viewer dynamically on the client:

```tsx

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

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

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

    if (container && NutrientViewer) {
      NutrientViewer.load({
        container,
        document: "/document.pdf",
      });
    }

    return () => {
      NutrientViewer?.unload(container);
    };
  }, []);

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

```

Make sure `document.pdf` exists and matches the file path exactly.

#### 3. Configure webpack to exclude bundling

In `next.config.mjs`, prevent webpack from bundling the SDK into your app:

```js

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack(config, { isServer }) {
    if (!isServer) {
      config.externals = config.externals || [];
      config.externals.push({
        "@nutrient-sdk/viewer": "@nutrient-sdk/viewer",
      });
    }
    return config;
  },
  turbopack: {
    resolveAlias: {
      "@nutrient-sdk/viewer": "@nutrient-sdk/viewer",
    },
  },
};

export default nextConfig;

```

### Step 6 — Start the development server

Run your project:

```bash

npm run dev

```

Navigate to `http://localhost:3000/` in your browser. You’ll see all the features you expect from a PDF viewer are present by default.![nutrient demo](@/assets/images/blog/2021/how-to-build-a-jquery-pdf-viewer-with-pdfjs/pspdfkit-demo.png)

<!---

> Interact with the sandbox by clicking the left rectangle icon and selecting <b>Editor</b> > <b>Show Default Layout</b>. To edit, sign in with GitHub — click the rectangle icon again and choose <b>Sign in</b>. To preview the result, click the rectangle icon once more and choose <b>Editor</b> > <b>Embed Preview</b>. For the full example, click the <b>Open Editor</b> button. Enjoy experimenting with the project!

--->

### Adding even more capabilities

Once you’ve deployed your viewer, you can start customizing it to meet your specific requirements or easily add more capabilities. To help you get started, here are some of our most popular Next.js guides:

- [Adding annotations](https://www.nutrient.io/guides/web/annotations.md)

- [Editing documents]

- [Filling PDF forms]

- [Adding signatures to documents]

- [Real-time collaboration]

- [Redaction]

- [UI customization]

## Conclusion

Building a PDF viewer in Next.js requires thoughtful handling of server-side rendering constraints. In this tutorial, you learned about two powerful approaches:

- **[React-PDF](https://github.com/wojtekmaj/react-pdf)** — An open source library that’s ideal for lightweight PDF viewing with basic features and minimal setup.

- **[Nutrient Web SDK](https://www.nutrient.io/guides/web/viewer.md)** — A full-featured, production-ready solution designed for complex use cases like annotation, redaction, form filling, and document collaboration.

Both tools enable client-side rendering that avoids hydration mismatches and ensures smooth PDF loading inside your Next.js app. If you’re building a personal project or prototype, React-PDF may be all you need. But if you’re deploying a scalable, user-facing app that demands advanced features, performance, and cross-document support, Nutrient Web SDK offers a flexible and professional-grade foundation.

You can also deploy our vanilla [JavaScript PDF viewer](https://www.nutrient.io/blog/how-to-build-a-javascript-pdf-viewer/) or use one of our many web framework deployment options like [React.js](https://www.nutrient.io/blog/how-to-build-a-reactjs-pdf-viewer/), [Vue.js](https://www.nutrient.io/blog/how-to-build-a-vuejs-pdf-viewer/), [jQuery](https://www.nutrient.io/blog/how-to-build-a-jquery-pdf-viewer/), and [Angular](https://www.nutrient.io/blog/how-to-build-an-angular-pdf-viewer/).

To see a list of all web frameworks, start your [free trial](https://www.nutrient.io/try). Or, [launch our demo](https://www.nutrient.io/demo) to see our viewer in action.

## FAQ

#### What is Nutrient Web SDK?

Nutrient Web SDK is a browser-based JavaScript library that allows you to render, annotate, redact, and sign PDF and image files using WebAssembly for high performance and full client-side operation.

#### Does Nutrient Web SDK support formats beyond PDFs?

Yes. While it excels at PDF rendering, it also supports Microsoft Office files (like DOCX, XLSX) and image formats (JPG, PNG, TIFF), making it suitable for a wide range of document workflows.

#### Is Nutrient Web SDK production-ready?

Yes. Nutrient Web SDK is a commercial solution with strong rendering performance, advanced document tools, and dedicated support for integration.

#### How do I keep the Nutrient SDK out of my Next.js bundle?

To avoid bundling the SDK, load it via a global `<script>` tag and mark it as an external dependency in your Next.js `next.config.js`. This keeps your app lightweight and reduces build size.

#### Can I use Nutrient Web SDK without a backend server?

Yes. The viewer runs entirely in the browser. As long as your PDF or document is accessible via the `/public` folder or a public URL, the viewer works without any backend services.

#### What is React-PDF?

React-PDF is an open source React library that renders PDFs using Mozilla’s PDF.js. It’s great for basic use cases where you need lightweight, client-only PDF viewing in React or Next.js.

#### Is React-PDF compatible with Next.js?

Yes — but only when rendered on the client. Since React-PDF relies on browser APIs like `canvas`, it must be dynamically imported with `ssr: false` to prevent server-side rendering errors.

#### What are the limitations of React-PDF?

While React-PDF is ideal for simple use cases, it doesn’t support advanced features like annotations, redactions, or form filling. It’s also less performant for large or multipage PDFs.

#### Should I choose React-PDF or Nutrient Web SDK?

Use React-PDF for lightweight, open source needs and simple viewers. Choose Nutrient Web SDK if you need production-grade tools, advanced features, and support for multiple file formats.
---

## 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)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.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)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.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)
- [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)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.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 Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.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)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Linearized Pdf](/blog/linearized-pdf.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 Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.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 Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.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)
- [Process Flows](/blog/process-flows.md)
- [or](/blog/sample-blog-updated.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.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)

