# Load and View PDF Files in React

Learn how to load and view PDF files in a React application. Get started and see more from Document Solutions today.

## Content

This tutorial shows how to integrate the **Document Solutions for PDF Viewer (DsPdfViewer)** into a React application using Vite. The DsPdfViewer lets users view and edit PDF files directly in the browser, including interactive PDF forms, and save modified documents on the client side. It supports all modern browsers and provides an efficient way to load and display PDF files in web applications.

## Prerequisites

Before you begin, make sure the following tools are installed:

* Node.js (download the latest version from the official Node.js site)
* NPM (included with Node.js)
* A code editor, such as Visual Studio Code

Once these are installed, you can create and configure your React project.

***

## Create a React Project with Vite

Open a terminal and run the following command to create a new React application using Vite:

```auto
npm create vite@latest dspdfviewer-react -- --template react
```

During setup, you may be prompted to select a framework and variant. Select **React** as the framework and choose the variant that applies to your project. This tutorial uses JavaScript.
![Vite project set up for the React Framework](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer1-20260529.b2b5c4.png)

After the project is created, navigate to the project folder and install the required dependencies:

```auto
cd dspdfviewer-react
npm install
```

You can confirm that the project runs successfully with the following command:

```auto
npm run dev
```

This starts the Vite development server and displays the default React application in the browser.

***

## Install the Document Solutions PDF Viewer Package

To add the PDF Viewer to your React project, install the **@mescius/dspdfviewer** package from npm:

```auto
npm install @mescius/dspdfviewer
```

You can also install Bootstrap for optional styling:

```auto
npm install bootstrap
```

After installation, the library files will be available in:
node\_modules/@mescius/dspdfviewer/
![React Vite Project Folder | NPM install for a React PDF Viewer | Document Solutions DsPdfViewer](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer2-20260529.3548f3.png)
***

## Add the PDF Viewer Component to the React Application

Open the index.html file and make sure the page includes a root element where the React application will be mounted:

```auto
<!-- index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>DsPdfViewer | Vite + React</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>
```

Next, open main.jsx and remove StrictMode from the default React template. This helps avoid compatibility issues such as double mounting or duplicate viewer initialization during development.

```auto
// main.jsx
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <App />
)
```

Update index.css so the application and viewer can fill the browser window:

```auto
/* index.css */
html,
body,
#root {
  height: 100%;
  margin: 0;
  padding: 0;
}

#viewer {
  width: 100%;
  height: calc(100vh - 10px);
}
```

Finally, replace the contents of App.jsx with the following code to initialize DsPdfViewer and add the default toolbar and sidebar panels:

```auto
// App.jsx
import { useEffect, useRef } from 'react';
import { DsPdfViewer } from '@mescius/dspdfviewer';
import 'bootstrap/dist/css/bootstrap.css';
import './App.css';

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

  useEffect(() => {
    if (!viewerRef.current) {
      console.error('Viewer container element not found');
      return;
    }

    let viewer = null;

    try {
      viewer = new DsPdfViewer(viewerRef.current, {
        workerSrc: './node_modules/@mescius/dspdfviewer/dspdfviewer.worker.js',
        restoreViewStateOnLoad: false
      });

      viewer.addDefaultPanels();
    } catch (error) {
      console.error('Failed to initialize DsPdfViewer:', error);
    }

    return () => {
      if (viewer) {
        viewer.dispose();
      }
    };
  }, []);

  return <div id="viewer" ref={viewerRef}></div>;
}

export default App;
```

The **[workerSrc](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/ViewerOptions#workersrc "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/ViewerOptions#workersrc")** option improves performance when rendering PDFs, and **[addDefaultPanels()](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#adddefaultpanels "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#adddefaultpanels")** adds the standard toolbar and navigation panels to the viewer.

Run the React application with the following command:

```auto
npm run dev
```

Once the app builds, DsPdfViewer will display as an empty viewer in the browser window.
![A React App with an Empty PDF Viewer and Default Controls/Panels](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer3-20260529.bcfe70.png)

***

## Load a Local PDF File in a React Application

With the viewer running, you can load a PDF stored locally in your project. For this example, place a file named social\_media\_schedule.pdf in the public/pdfs/ folder.

To display the file automatically when the app starts, call the **[open()](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#open "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#open")** method after adding the default panels:

```auto
viewer.addDefaultPanels();
viewer.open('./pdfs/social_media_schedule.pdf');
```

The full App.jsx file should look like this:

```auto
// App.jsx
import { useEffect, useRef } from 'react';
import { DsPdfViewer } from '@mescius/dspdfviewer';
import 'bootstrap/dist/css/bootstrap.css';
import './App.css';

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

  useEffect(() => {
    if (!viewerRef.current) {
      console.error('Viewer container element not found');
      return;
    }

    let viewer = null;

    try {
      viewer = new DsPdfViewer(viewerRef.current, {
        workerSrc: './node_modules/@mescius/dspdfviewer/dspdfviewer.worker.js',
        restoreViewStateOnLoad: false
      });

      viewer.addDefaultPanels();
      viewer.open('./pdfs/social_media_schedule.pdf');
    } catch (error) {
      console.error('Failed to initialize DsPdfViewer:', error);
    }

    return () => {
      if (viewer) {
        viewer.dispose();
      }
    };
  }, []);

  return <div id="viewer" ref={viewerRef}></div>;
}

export default App;
```

When you run the application, the specified PDF file will load automatically in DsPdfViewer.
![React App | Loading a PDF into a JS Viewer/Editor Control | Developer Solution](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer4-20260529.c50cce.png)
You can also use the **[openLocalFile()](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#openlocalfile "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#openlocalfile")** method to let users select a PDF through a native open-file dialog.

***

## Load a PDF from a URL in a React Application

You can also open PDFs hosted on the same domain as your React application. Use the same **[open()](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#open "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#open")** method and provide the relative URL to the PDF:

```auto
viewer.open('/document-solutions/javascript-pdf-viewer/demos/product-bundles/assets/pdf/helloworld.pdf');
```

The viewer will download and render the file directly in the browser. This method works for any PDF that resides within your web application’s domain.
![Loading PDF from URL into React App using a JS PDF Viewer Control](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer5-20260529.b1cdbc.png)

***

## Load a PDF from Another Domain (Using a CORS Proxy) in a React Application

When loading a PDF from a different domain, browsers may block the request due to CORS (Cross-Origin Resource Sharing) restrictions. To handle this, DsPdfViewer supports a **SupportApi** configuration, which uses an ASP.NET Core service as a proxy for loading and streaming remote PDF files.

### Create a CORS Proxy Endpoint

In your ASP.NET Core project, add a controller named CorsProxyController:

```auto
[ApiController]
[Route("[controller]")]
public class CorsProxyController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;
    public CorsProxyController(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;

    [HttpGet]
    public async Task<IActionResult> Get(string url)
    {
        if (string.IsNullOrEmpty(url)) return BadRequest("Missing 'url' query parameter.");
        var client = _httpClientFactory.CreateClient();
        var response = await client.GetAsync(url);
        if (!response.IsSuccessStatusCode) return StatusCode((int)response.StatusCode);
        var stream = await response.Content.ReadAsStreamAsync();
        var contentType = response.Content.Headers.ContentType?.ToString() ?? "application/pdf";
        return File(stream, contentType);
    }
}
```

Register the HTTP client, controllers, CORS policy, and DsPdfViewer services in Program.cs:

```auto
// Add CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

// Register HTTP client and controllers
builder.Services.AddHttpClient();
builder.Services.AddControllers();
GcPdfViewerHub.ConfigureServices(builder.Services);

var app = builder.Build();

// Use CORS with the custom policy
app.UseCors("AllowAll");
app.MapControllers();
```

### Update the React Component to Use the Proxy

Once the proxy service is running, configure the supportApi object in your React viewer setup. Then call the **open()** method and pass in the proxy endpoint:

```auto
// App.jsx
import { useEffect, useRef } from 'react';
import { DsPdfViewer } from '@mescius/dspdfviewer';
import 'bootstrap/dist/css/bootstrap.css';
import './App.css';

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

  useEffect(() => {
    if (!viewerRef.current) {
      console.error('Viewer container element not found');
      return;
    }

    let viewer = null;

    try {
      viewer = new DsPdfViewer(viewerRef.current, {
        workerSrc: 'https://cdn.mescius.com/ds-pdfviewer/latest/dspdfviewer.worker.js',
        restoreViewStateOnLoad: false,
        supportApi: {
          apiUrl: 'https://localhost:7126',
          token: 'support-api-demo-net-core-token-2021',
          webSocketUrl: false
        }
      });

      viewer.addDefaultPanels();
      viewer.open('https://localhost:7126/CorsProxy?url=https://cdn.mescius.io/sites/developer/legal/eula/ds/20250401-DOCUMENTS-EULA.pdf');
    } catch (error) {
      console.error('Failed to initialize DsPdfViewer:', error);
    }

    return () => {
      if (viewer) {
        viewer.dispose();
      }
    };
  }, []);

  return <div id="viewer" ref={viewerRef}></div>;
}

export default App;
```

After these steps, your React app can securely open and render PDFs from external domains without encountering CORS errors.
![Load or Open a PDF from Another Domain URL into a React app using a CORS Proxy](https://cdn.mescius.io/document-site-files/images/9cff3ae8-6cf4-4362-9202-5833da8e6dd7/ReactViewer6-20260529.8f0ab3.png)

***

## FAQ

**Why doesn’t my PDF load when using a URL from another domain?**
This is typically caused by browser CORS restrictions. To fix this, configure the **[supportApi](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#supportapi "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/DsPdfViewer#supportapi")** option in DsPdfViewer to proxy remote file requests through your own server, such as an ASP.NET Core endpoint.
<br>
**Can DsPdfViewer be used directly in a React application without a backend?**
Yes. For local files, project assets, and same-domain URLs, no backend is required. A backend is only needed when loading files from external URLs that do not include the required CORS headers.
<br>
**Does DsPdfViewer support editing or only viewing PDFs in React?**
DsPdfViewer supports both viewing and editing features. Users can fill interactive forms, modify annotations, add comments, and save updated PDFs directly in the browser. Editing features require a **Professional DsPdfViewer license** and are not included in the standard DsPdfViewer license provided with every DsPdf license.
<br>
**Why should StrictMode be removed from the React template?**
React StrictMode may mount components more than once during development, which can cause the PDF Viewer to initialize twice. Removing StrictMode from this sample helps avoid duplicate initialization behavior while setting up DsPdfViewer.
<br>
**Can DsPdfViewer work with frameworks other than React?**
Yes. DsPdfViewer is framework-agnostic and works in React, Vue, Angular, or plain JavaScript/HTML applications. The API usage and configuration remain consistent across frameworks.

***

## Next Steps

* [Try the online demos to see features like form filling, annotation, and client-side saving in action](https://developer.mescius.com/document-solutions/javascript-pdf-viewer/demos/ "https://developer.mescius.com/document-solutions/javascript-pdf-viewer/demos/").
* [Review the full Document Solutions PDF Viewer documentation for more examples](https://developer.mescius.com/document-solutions/dot-net-pdf-api/docs/online/pdfviewer "https://developer.mescius.com/document-solutions/dot-net-pdf-api/docs/online/pdfviewer").
* [Learn more about upgrading to the Professional DsPdfViewer](https://developer.mescius.com/webinars/document-solutions-for-pdf-professional-viewer "https://developer.mescius.com/webinars/document-solutions-for-pdf-professional-viewer").
