Blazor is an upcoming web framework that allows you to build interactive web UIs with C# and use .NET Core packages in your backend.

If you're interested in integrating a PDF and MS Office document viewing, annotating, and editing solution into your Blazor application, read on. This blog will show you how to embed the powerful PDFTron WebViewer.

Access the source code for this project from our git repo.

linkPrerequisites

To begin with, you will need to have downloaded the latest .NET Core SDK. If you are already familiar with Blazor, feel free to skip ahead.

linkGet started

You can use an existing Blazor application. But if you want to create a new Blazor project from scratch, follow this guide.

Please note the full client-side template from the samples will not work out of the box because the client-side template blocks server configuration and WebViewer needs to configure some MIME-type mappings on the hosting server. For fast integration, use either the Blazor server-side template or the client-side --hosted option.

linkAdd the WebViewer library

First, download WebViewer from our website here.

Next, extract the zip file and move the lib folder into the project's static resources directory(which by default is wwwroot).

To ensure your Blazor app can find the WebViewer Library, add the library as a script tag under your main HTML page, likely wwwroot/index.html for the client-side model or Pages/_Host.cshtml for the server-side model.

Insert the following under the <head> element of that file.

<script src="lib/webviewer.min.js"></script>

linkDefine wrapper functions

Now that we have imported WebViewer into our main HTML file, we will define some JavaScript wrapper functions to instantiate and work with WebViewer. Create a new folder in the resources directory called js, and inside that folder, make a new JavaScript file webviewerScripts.js.

Open the JavaScript file and write a function to instantiate WebViewer and expose it to the browser window:

window.webviewerFunctions = {
    initWebViewer: function () {
        const viewerElement = document.getElementById('viewer');
        WebViewer({
            path: 'lib',
            initialDoc: 'https://pdftron.s3.amazonaws.com/downloads/pl/demo-annotated.pdf', // replace with your own PDF file
        }, viewerElement).then((instance) => {
            // call apis here
        })
    }
};

Again, to make sure Blazor finds this file, we add a script tag to the main HTML file but this time inside the <body> element:

<script src="js/webviewerScripts.js"></script>

linkMake the page

Next, we make a new page to host WebViewer and define the viewer div element referenced in webviewerFunctions.initWebViewer. Navigate to your project’s Pages directory and make a new file called WebViewer.razor.

Inside this file, we need to define the route, inject the JavaScript interop runtime, and define the div element for WebViewer to instantiate in. Add these lines to the top of WebViewer.razor:

@page "/webviewer"
@inject IJSRuntime JSRuntime

<h1>WebViewer</h1>
<div id='viewer' style='width: 1024px; height: 600px; margin: 0 auto;'></div>

We then need to call the JavaScript function we defined earlier through the interop. We can define a script section after the div declaration and call the initWebViewer method we defined earlier inside the OnAfterRender() function for the page:

@code {
    protected override async void OnAfterRender()
    {
        await JSRuntime.InvokeAsync<object>("webviewerFunctions.initWebViewer");
    }
}

linkConfigure MIME types

Before we run our application, we first need to add MIME-type mappings to our hosting server so it can find the WebViewer library files. The process is different for every type of server. If you are using an ASP.NET server, consult our guide on how to add those mappings.

You may also find this guide helpful.

linkRun the application

We have now successfully integrated WebViewer into Blazor. To see WebViewer in action, run the application via dotnet run or by opening the solution in Visual Studio.

Navigate to the localhost:XXXX/webviewer page of the Blazor application and you should see WebViewer:

WebViewer in Blazor

linkCustomize WebViewer

You can call WebViewer APIs straight inside initWebViewer(defined in js/webviewerScripts.js). For example, to set WebViewer to dark mode, you can add this line inside initWebViewer:

...
}, viewerElement).then((instance) => {
    // call apis here
+    instance.setTheme('dark');
...

If you restart the application and navigate to localhost:XXXX/webviewer again, you should see the theme has changed:

Dark theme webviewer

You can also define more JavaScript functions in webviewerScripts.js and call them from the C# side. First, add a variable above the window.webViewerFunctions declaration to expose the WebViewer instance:

+var wvInstance;
window.webviewerFunctions = {
    ...

Then in initWebViewer, set the variable to the WebViewer instance:

...
}, viewerElement).then((instance) => {
    // call apis here
+    wvInstance = instance;
...

Next, we can define a new function inside window.webviewerFunctions to load another document into the WebViewer instance from a given URL:

loadDocURL: function(url) {
    wvInstance.loadDocument(url);
},

Now inside WebViewer.razor, we can call this function via JSInterop:

await JSRuntime.InvokeAsync<object>("webviewerFunctions.loadDocURL", "YOUR-URL-HERE");

linkWrapping up

In this article, we demonstrated how to add WebViewer to a Blazor application. If you have any questions about integrating WebViewer into Blazor or any other web frameworks, get in touch with us and we will be happy to help!