Some test text!


WebViewer in Salesforce - Frequently Asked Questions

What is WebViewer?

WebViewer is a pure client-side JavaScript library to annotate, view, and edit documents such as PDF, MS Office, Images, CAD, Video and more.

How can we use WebViewer in Salesforce?

We can embed WebViewer UI in Salesforce, contained in an iframe. WebViewer source code can be stored in Salesforce static resources, which allows for advanced document working client side without external dependencies and without your data ever leaving your Salesforce organization.

How can I try out WebViewer in Salesforce?

The easiest way is to install our Showcase package which can be found here, or by following steps in this video.

How do I optimize WebViewer for Salesforce

In Salesforce, we need to upload our WebViewer source files to static resources. Salesforce imposes a file size limit of 5MB for static resources, so we need to optimize our WebViewer worker files.

Since static resources are served from a different origin, we need to use a config.js file which runs in context of the WebViewer iframe. You can check out a sample config.js file here.

What are the limitations of WebViewer in Salesforce?

Due to Salesforce's Governor Limits, we can only use Salesforce files within the allowed heap size (6MB/12MB async). WebViewer supports external file storage, from providers such as AWS, GCP, Azure, Dropbox and others - this allows for file support for sizes up to 2GB.

How to load WebViewerEntry Point with loadScript()?

After uploading your WebViewer worker files, make sure you use Salesforce's loadScript API to load the WebViewer entry point like so:

//in your pdftronInstance.js LWC file
renderedCallback() {
  //your renderedCallback logic here...

  var self = this;
  if (this.uiInitialized) {
    return; // prevent multiple initializations of WebViewer on each re-render
  this.uiInitialized = true;

    loadScript(self, libUrl + '/webviewer.min.js'),
  .then(() => this.initUI())

How to instantiate WebViewer with Salesforce using a config file?

In Salesforce, the config file is used to set worker paths for our optimized WebViewer files and to access WebViewer objects and APIs. You can check out WebViewer fundamentals , which explains how WebViewer creates the UI app inside an iframe, so that Core namespaces and classes are encapsulated.

The iframe window and document object are still accessible through contentWindow and contentDocument, but it can still be tricky to run scripts or listen to events happening inside the iframe.

The config file gives you easy access to the Document, DocumentViewer and AnnotationManager objects (among others) which can allow you to make more complicated customizations.

To instantiate WebViewer with a config file you just need to set the config option in the WebViewer constructor. For example:

//in your pdftronInstance.js LWC file
const viewerElement = this.template.querySelector('div')

const viewer = new WebViewer({
  // snipped for brevity

  config: myfilesUrl + this.config, // path to the config.js file in your static resources
}, viewerElement);

How do I setup worker paths in the config.js?

Before using WebViewer, you need to specify the worker paths for WebViewer with the below API calls. Keep in mind that some workers, such as office workers are only required if you want to include MS Office support and can be safely omitted if not required for your implementation.

// staticresource/config.js

// office workers - optional
window.Core.setOfficeWorkerPath(resourceURL + 'office')
window.Core.setOfficeAsmPath(resourceURL + 'office_asm');
window.Core.setOfficeResourcePath(resourceURL + 'office_resource');

// legacy office workers - optional
window.Core.setLegacyOfficeWorkerPath(resourceURL + 'office')
window.Core.setLegacyOfficeAsmPath(resourceURL + 'office_asm');
window.Core.setLegacyOfficeResourcePath(resourceURL + 'office_resource');

// pdf workers
window.Core.setPDFResourcePath(resourceURL + 'resource')
if (custom.fullAPI) {
  window.Core.setPDFWorkerPath(resourceURL + 'pdf_full')
  window.Core.setPDFAsmPath(resourceURL + 'asm_full');
} else {
  window.Core.setPDFWorkerPath(resourceURL + 'pdf_lean')
  window.Core.setPDFAsmPath(resourceURL + 'asm_lean');

// external 3rd party libraries
window.Core.setExternalPath(resourceURL + 'external');

How do I pass custom data to WebViewer?

You can use a custom object and pass it to your WebViewer constructor to pass data from LWC to your config file upon initialization. To do this you can use the custom option in the WebViewer constructor. The property expects a string value. So for example to pass an object:

// LWC js file
var myObj = {
    libUrl: libUrl, // staticresources/ folder used for setting workerPaths
    myfilesUrl: myfilesUrl,
    fullAPI: this.fullAPI || false,
    namespacePrefix: '', // pass a namespace prefix for managedpackages
    //var url = myfilesUrl + '/WVSF-Account-info-sample.pdf';

const viewerElement = this.template.querySelector('div')
    // eslint-disable-next-line no-unused-vars
const viewer = new WebViewer({
// snipped for brevity
    custom: JSON.stringify(myObj),
    }, viewerElement);

Then inside the config file you access this data as follows:

instance.UI.addEventListener('viewerLoaded', () => {
  const custom = JSON.parse(instance.UI.getCustomData());
  console.log(custom.fullAPI); // outputs true or false

instance.UI.addEventListener('documentLoaded, () => {
  const docViewer = instance.Core.documentViewer;

How do I use a config file when the path is on another domain

If you have the WebViewer path on a different domain than your app, then to protect against XSS attacks you will need to edit the lib/ui/configorigin.txt file to whitelist your app's domain(s). Add each domain on a separate line, for example:


Domains in this list will be allowed to have WebViewer specify config files that can be loaded.

Accessing outer page inside the iframe

If you want to access the outer page from inside the iframe (for Salesforce it is the parent LWC component), for example from code in your config file, you can access the parent window using window.parent. So if you defined an API that's loaded on your HTML page, you could access it from inside the iframe like window.parent.myApi.myFunction().

You could hook into WebViewer events and notify the parent LWC like so:

window.addEventListener('viewerLoaded', () => {
  // notify parent LWC that viewer has loaded and is ready for processing documents
  window.parent.postMessage({ type: 'VIEWER_LOADED' }, window.origin);

Get the answers you need: Support

Upcoming Webinar: How Developers Add Office Viewing Without Downloading | June 9th at 11 am PT


The Platform


© 2022 PDFTron Systems Inc. All rights reserved.


Terms of Use