> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/get-started/without-viewer.md).

# Build UI-free document processing workflows with Apryse WebViewer SDK

Use the Apryse WebViewer SDK to process, convert, and edit PDFs without the WebViewer UI. Build headless, programmatic workflows for data extraction, page operations, and document automation.

This guide shows how to use the Apryse [WebViewer SDK](https://apryse.com/products/webviewer) for headless, programmatic document processing without rendering the WebViewer UI. This approach is useful when you need to process, convert, or inspect documents directly in your application, or build automated document workflows.

The examples use a simple HTML‑based project to focus on core SDK functionality without UI components. By the end, you’ll be able to:

* Count the number of pages in a PDF.
* Convert a DOCX file to PDF and automatically download it.

## Prerequisites

Before you start:

* Install [Node.js](https://nodejs.org/en/download) and npm. We recommend using the latest active LTS release.
* Install [Visual Studio Code](https://code.visualstudio.com/Download) or another code editor to develop and debug your code.
* Get your Apryse trial key.

{% @apryse-license-key/apryse-license-key platform="WEB\_VIEWER" variant="full" %}

## 1. Create your project

Set up your project by creating a folder and preparing a workspace for building document‑processing workflows with the Apryse WebViewer SDK.

1. In your terminal, go to the directory where you want to create the project.
2. Create a new project folder and move to it so you can start working with it:

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```shell
mkdir webviewer-no-ui
cd webviewer-no-ui
```

{% endcode %}
{% endtab %}
{% endtabs %}

## 2. Download WebViewer

In this step, you’ll manually download the WebViewer package and add it to your project.

1. Download the [WebViewer package](https://downloads.apryse.com/downloads/WebViewer.zip), which includes the library files, samples, and documentation.
2. Extract the downloaded `WebViewer.zip` file into the `webviewer-no-ui` project folder. Your project structure should look similar to this:

{% code lineNumbers="true" %}

```
webviewer-no-ui/
└── WebViewer/
    ├── doc/
    ├── lib/
    ├── licenses/
    ├── samples/
    ├── scripts/
    ├── package.json
    └── server.js
```

{% endcode %}

## 3. Create the PDF viewer

In this section, you’ll add a minimal HTML structure and the JavaScript required to run document processing tasks with the Apryse WebViewer SDK. In this headless setup, only the core SDK scripts are loaded, and document workflows are handled entirely through code rather than a full viewer UI.

1. Open the `webviewer-no-ui` folder in Visual Studio Code.
2. Create a new `index.html` file in the `webviewer-no-ui` folder.
3. Add the following HTML to the `index.html` file:

{% tabs %}
{% tab title="HTML" %}
{% code title="index.html" lineNumbers="true" %}

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Basic WebViewer</title>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    
    <!-- Load WebViewer Core SDK (no UI components) -->
    <script src="./WebViewer/lib/core/webviewer-core.min.js"></script>
    <!-- Use PDFNetLean.js when advanced PDFNet features aren't required -->
    <!-- <script src="./lib/core/pdf/PDFNetLean.js"></script> -->
    <script src="./WebViewer/lib/core/pdf/PDFNet.js"></script>
  </head>

  <body>
    <h1>Working without a viewer</h1>
    <p>Add query params as a verb and the URL of the file to be processed</p>
    <!-- Example query parameters for document processing -->
    <!-- Use to trigger and test each workflow -->
    <ul>
      <li>Count pages: ?countpages=https://apryse.s3.amazonaws.com/public/files/samples/WebviewerDemoDoc.pdf</li>
      <li>Convert to PDF: ?convert=https://pdftron.s3.amazonaws.com/downloads/pl/report.docx</li>
    </ul>
  </body>

</html>
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Info**

WebViewer Core provides the foundation for WebViewer functionality. In a typical UI setup, you would include the `webviewer.min.js` script. In a headless (no‑UI) scenario, you only need to load the core libraries: `webviewer-core.min.js` and `PDFNet.js`.

If you don’t require advanced PDFNet functionality, you can use the lighter `PDFNetLean.js` script instead. It has a smaller footprint, loads faster, and includes the essential PDFNet features without requiring the full API. For this guide, we use the full `PDFNet.js` library for consistency, though it's not required.
{% endhint %}

4. Add the following JavaScript to your `index.html` file, placing it before the closing `</body>` tag:

<pre class="language-js" data-line-numbers><code class="lang-js">&#x3C;script>
  // Set path to WebViewer Core worker files
  // Allow PDFNet to load Web Worker scripts for document processing
  Core.setWorkerPath('./WebViewer/lib/core');

  // Create entry point for all no viewer SDK operations
  async function main() {
    // Get current page URL and extract query parameters
    const currentPageURL = new URL(window.location.href);
    const params = new URLSearchParams(currentPageURL.search);

    // Check for 'countpages' parameter
    // Load PDF from URL, create PDFDoc instance
    // Retrieve and display page count
    if (params.has('countpages')) {
      const inputURL = params.get('countpages');
      const doc = await Core.PDFNet.PDFDoc.createFromURL(inputURL);
      doc.initSecurityHandler();
      // Lock document to ensure safe operations
      doc.lock();
      const pageCount = await doc.getPageCount();
      alert(`Your file has ${pageCount} pages`);
    }

   // Check for 'convert' parameter
   // Convert DOCX from URL to PDF using office2PDF
   // Return PDFDoc object and download it
    else if (params.has('convert')) {
      const inputURL = params.get('convert');

      Core.PDFNet.Convert.office2PDF(inputURL).then(async (outPdfDoc) => {
        const pageCount = await outPdfDoc.getPageCount();
        console.log(`Converted DOCX to PDF with ${pageCount} pages`);
        const outputPath = 'output.pdf';

        // Export PDF as blob for download
        // Refactor into utility function if preferred
        const pdfData = await outPdfDoc.saveMemoryBuffer(Core.PDFNet.SDFDoc.SaveOptions.e_linearized);
        const blob = new Blob([pdfData], {type: 'application/pdf'});

        // Trigger download
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = outputPath;
        a.click();
      });
    }
  }

  // Initialize PDFNet and run main function
  // Replace with your Apryse license key
  Core.PDFNet.runWithCleanup(main, '<code class="expression">visitor.claims.wvKey || "YOUR_LICENSE_KEY"</code>');
&#x3C;/script>
</code></pre>

[Core.setWorkerPath()](https://sdk.apryse.com/api/web/Core.html#.setWorkerPath) [Core.PDFNet.PDFDoc](https://sdk.apryse.com/api/web/Core.PDFNet.PDFDoc.html?#main) [PDFNet.runWithCleanup()](https://sdk.apryse.com/api/web/Core.PDFNet.html#.runWithCleanup) [PDFDoc.createFromURL()](https://sdk.apryse.com/api/web/Core.PDFNet.PDFDoc.html?#.createFromURL__anchor)

5. Save the `index.html` file.

## 4. Verify your output

Once your project files are in place, serve the webpage so that the Apryse WebViewer SDK can load and run document-processing tasks in the browser. This allows you to verify that your setup is working correctly. We use [http-server](https://www.npmjs.com/package/http-server) to preview the page locally in your browser.

1. From your project directory, run the following command to start a local web server:

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```shell
npx http-server -a localhost
```

{% endcode %}
{% endtab %}
{% endtabs %}

If prompted, press `y` to install `http-server`. A successful output looks similar to:

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```shell
Starting up http-server, serving ./

http-server version: 14.1.1

http-server settings: 
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://localhost:8080
```

{% endcode %}
{% endtab %}
{% endtabs %}

2. Open the localhost URL from your terminal to view the project in your browser.
3. Paste this URL into your browser to see an alert showing the PDF's page count, then load the page:

{% code lineNumbers="true" %}

```
http://localhost:8080/?countpages=https://apryse.s3.amazonaws.com/public/files/samples/WebviewerDemoDoc.pdf
```

{% endcode %}

4. Paste this URL into your browser to convert the DOCX file to PDF and automatically download the result, then load the page:

{% code lineNumbers="true" %}

```
http://localhost:8080/?convert=https://pdftron.s3.amazonaws.com/downloads/pl/report.docx
```

{% endcode %}

## Get started video

In this 6-minute video, learn how to integrate the Apryse WebViewer SDK into your application and build document-processing workflows without a viewer interface.

{% embed url="<https://www.youtube.com/embed/s2lKUTNAGdk?si=tAIPzWicfs-4BGlV>" %}
Integrate the WebViewer SDK without the UI to build document-processing workflows.
{% endembed %}

## Next steps

<a href="/web/what-is-webviewer/usage.md" class="button primary">Usage</a><a href="/web/get-started/guides.md" class="button primary">Guides</a><a href="/web/get-started/samples.md" class="button primary">Samples</a><a href="https://sdk.apryse.com/api/web/index.html" class="button primary">API docs</a>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/get-started/without-viewer.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
