PDF.js Express Plusplay_arrow

Professional PDF.js Viewing & Annotations - Try for free

side menu

Get Started

play_arrow

Learn more

play_arrow

Common use cases

play_arrow

Open a document

play_arrow

Save a document

play_arrow

Viewer

play_arrow

UI Customization

play_arrow

Annotations

play_arrow

Collaboration

play_arrow

Forms

play_arrow

Signature

play_arrow

Searching

play_arrow

Measurement

play_arrow

Compare

play_arrow

Advanced Capabilities

play_arrow

PDF.js Express REST API

play_arrow

Migration Guides

play_arrow

Integrating PDF.js Express Plus into an existing Blazor project

This guide will help you integrate a free trial of PDF.js Express WebViewer into existing Blazor applications. You can find a new project guide here. Your free trial includes unlimited trial usage and support from solution engineers.

If you are using the client-side model of Blazor, please make sure the server hosting the static files includes the MIME type mappings outlined here.

Prerequisites

Download PDF.js Express
No trial license key required.
The trial of PDF.js Express SDK works without a license key. A commercial license key is required for use in a production environment. Please purchase a license key if you do not have one.

Setup

  1. Navigate to your Blazor project. Let's call the path to your project PROJ_ROOT:
PROJ_ROOT = path/to/your/blazor/project/
  1. From the PDFJSExpress.zip file you downloaded, copy the lib folder into the static folder of your application, which is usually wwwroot.

Integrate PDF.js Express WebViewer

  1. First to ensure Blazor can use the WebViewer library and APIs, open the main HTML file of your project(should be either PROJ_ROOT/wwwroot/index.html or PROJ_ROOT/Pages/_Host.cshtml). Add the WebViewer library as a script tag in the <head> element of that file:
<script src="lib/webviewer.min.js"></script>
  1. Next to call WebViewer APIs, we need to wrap them in a JavaScript object. Make a js folder in your static directory if it does not exist already, and make a new file in it called webviewerScripts.js.

  2. Inside that file, we define a new object called webviewerFunctions and expose that to window:

window.webviewerFunctions = {
  initWebViewer:  () => {
    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
    })
  }
};

Then to make sure Blazor can find this file, again add a script tag to the main html file of your project, but this time inside the <body> element:

<script src="js/webviewerScripts.js"></script>
  1. Now that we have wrapped the WebViewer JavaScript instantiation function, we need to define the actual page for WebViewer to run in. Make a new page under PROJ_ROOT/Pages and call it WebViewer.razor.

  2. Inside this page make a div element called viewer for the instantiation to attach to:

<h1>PDF.js Express WebViewer</h1>
<div id='viewer' style={{"width":"1024px","height":"600px","margin":"0 auto"}}></div>

Then override the OnAfterRender() method of the page and invoke the initWebViewer function we defined earlier:

await JSRuntime.InvokeAsync<object>("webviewerFunctions.initWebViewer");

Your final WebViewer.razor file should look something like this:

@page "/webviewer"
@inject IJSRuntime JSRuntime

<h1>PDF.js Express WebViewer</h1>
<div id='viewer' style={{"width":"1024px","height":"600px","margin":"0 auto"}}></div>

@code {
  protected override async void OnAfterRender(bool firstRender)
  {
    if (firstRender) {
+          await JSRuntime.InvokeAsync<object>("webviewerFunctions.initWebViewer");
    }
  }
}
  1. Add the required WebViewer MIME type formats by adding a provider to startup.cs:
using System.IO;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;

var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".res"] = "application/octet-stream";
provider.Mappings[".pexe"] = "application/x-pnacl";
provider.Mappings[".nmf"] = "application/octet-stream";
provider.Mappings[".mem"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
        ContentTypeProvider = provider
});

Your final startup.cs should look something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using BlazorWebViewerServer.Data;
+using System.IO;
+using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.FileProviders;

namespace BlazorWebViewerServer
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

+            var provider = new FileExtensionContentTypeProvider();
+            provider.Mappings[".res"] = "application/octet-stream";
+            provider.Mappings[".pexe"] = "application/x-pnacl";
+            provider.Mappings[".nmf"] = "application/octet-stream";
+            provider.Mappings[".mem"] = "application/octet-stream";
+            provider.Mappings[".wasm"] = "application/wasm";
+            app.UseStaticFiles(new StaticFileOptions
+            {
+                FileProvider = new PhysicalFileProvider(
+                    Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
+                    ContentTypeProvider = provider
+            });

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
    }
}

  1. You can test that the WebViewer is now part of your application by running the following:
dotnet run

In your browser, go to https://localhost:5001/webviewer to see the WebViewer in action.

WebViewer integrated in Blazor sample

Next step

GuidesSamplesAPI docs

Troubleshooting

MIME issues
Enable MIME type mappings for WebViewer to load documents.

Server-side document operations with .NET Core SDK
Handle document operations through the JavaScript interop by passing its base64 data.