Skip to content

Latest commit

 

History

History

webviewer-salesforce

How to Add an Apryse WebViewer to Salesforce as a Lightning Web Component

WebViewer is a powerful JavaScript-based PDF Library that is part of the Apryse SDK. It provides a slick out-of-the-box responsive UI that enables you to view, annotate and manipulate PDFs and other document types inside any web project.

The quickest way to getting started with WebViewer in Salesforce is to follow the instructions below.

Get your trial key

A license key is required to run WebViewer. You can obtain a trial key in our get started guides, or by signing-up on our developer portal.

Requirements

Installing WebViewer Sample App using Salesforce DX

  1. Install Salesforce DX. Enable the Dev Hub in your org or sign up for a Dev Hub trial org and install the Salesforce DX CLI. Follow the instructions in the Salesforce DX Setup Guide or in the App Development with Salesforce DX Trailhead module. The steps include:

  2. Clone the webviewer-salesforce from Github repo:

git clone --depth=1 https://github.com/ApryseSDK/webviewer-samples.git
cd webviewer-samples/webviewer-salesforce
  1. [Needed once] - If you already have the Static Resources and do not need to upgrade/downgrade to a different version, you can skip to step 5. Otherwise, extract WebViewer.zip, cd to the directory the contents were extracted
$ npm run optimize

Optimize: Do you want us to backup your files before optimizing? [y/n]:  y

Optimize: Will you be using WebViewer Server? See https://docs.apryse.com/documentation/web/guides/wv-server/ for more info. [y/n]:  n

Optimize: Will you be converting all your documents to XOD? See https://docs.apryse.com/documentation/web/guides/optimize-lib-folder for more info. [y/n]:  n

Optimize: Do you need client side office support (docx, pptx, xlsx)? [y/n]:  y

Optimize: Do you need client side office support for legacy office files (doc, ppt, xls)? [y/n]:  y

Optimize: Do you need the full PDF API? See https://docs.apryse.com/documentation/web/guides/optimize-lib-folder for more info (most users dont need this option). [y/n]:  y

Optimize: Do you want to use the production version of PDFNet.js? The production version does not have type checking and console messages, but is much smaller than the development version. [y/n]:  n

Optimize: Do you need to use the content editing feature? (This is for editing content on the page in the viewer) [y/n]:  y

Optimize: Do you need to use the office editing feature? (This is for editing docx files in the viewer) [y/n]:  y

Optimize: Do you need to deploy to Salesforce? See https://docs.apryse.com/documentation/web/guides/optimize-lib-folder for more info (most users dont need this option). [y/n]:  y

Optimize: Would you like to use the web component version of WebViewer (instead of the iframe)? [y/n]:  n

This optimization process produces zip files of size 5 MB or less, which enables you to safely upload to the Salesforce platform.

Note that in certain circumstances, you may need the full PDF API. For more details on when you may need to enable it, see:

https://www.docs.apryse.com.com/documentation/web/guides/full-api-overview/

  1. [Needed once] - Copy all the zip files from webviewer-salesforce folder, which were generated after running above npm optimization script, into force-app/main/default/staticresources.

Zip files

Every *.zip file should have a corresponding *.resource-meta.xml file, where the contents of each .xml file are identical to the other .xml files.

XML files

  1. If you have a paid license key, you can remove the watermark from rendered documents by adding the key to the PDFTron.WebViewer constructor here ./force-app/main/default/lwc/webViewer/webViewer.js.

  2. If you haven’t already done so, authenticate with your hub org and provide it with an alias (DevHub in the command below):

sfdx force:auth:web:login --setdefaultdevhubusername --setalias DevHub
  1. Enter your Dev Hub org credentials in the browser that opens. After you log in successfully, you can close the browser. Create a scratch org using the config/project-scratch-def.json file, set the username as your default, and assign it an alias.
sfdx force:org:create --setdefaultusername -f config/project-scratch-def.json --setalias my-scratch-org
  1. Push the app to your scratch org:
sfdx force:source:push -f
  1. Open the scratch org:
sfdx force:org:open
  1. Click the app launcher icon App Launcher icon to open the App Launcher, then click PDFTron.

PDFTron app

WebViewer

Note: Include the following to your profile .xml for application and tab access

    <applicationVisibilities>
        <application>PDFTron</application>
        <default>false</default>
        <visible>true</visible>
    </applicationVisibilities>
    <tabVisibilities>
        <tab>File_Browser</tab>
        <visibility>DefaultOn</visibility>
    </tabVisibilities>
    <tabVisibilities>
        <tab>WebViewer</tab>
        <visibility>DefaultOn</visibility>
    </tabVisibilities>

Implementation Details for Developers

Communicating with CoreControls from Lightning Web Component

On the Salesforce platform, Lightning Web Component have limits accessing to WebViewer’s iframe due to LockerService requirements. Lightning Component can use limited communication mechanism between components using postMessage. You can find more information about LockerService here.

Here is implementation of the postMessage mechanism used in our sample github project and you can use this similar approach to communicate with the iframe’s contentWindow.

Inside config.js file, use following:

window.addEventListener('message', receiveMessage, false);

function receiveMessage(event) {
  if (event.isTrusted && typeof event.data === 'object') {
    switch (event.data.type) {
      case 'OPEN_DOCUMENT':
        instance.loadDocument(event.data.file)
        break;
      default:
        break;
    }
  }
}

and in the Lightning Web Component send messages with postMessage as following:

import { LightningElement, track, wire } from 'lwc';
import myfilesUrl from '@salesforce/resourceUrl/myfiles';
import libUrl from '@salesforce/resourceUrl/lib';

export default class WebViewer extends LightningElement {

  handleFileSelected(file) {
    this.iframeWindow.postMessage({type: 'OPEN_DOCUMENT', file: file})
  }

  initUI() {
    const myObj = {
      libUrl: libUrl,
      fullAPI: false,
      namespacePrefix: '',
    };

    const viewerElement = this.template.querySelector('div');
    const viewer = new WebViewer({
      path: myObj.libUrl,
      fullAPI: myObj.fullAPI,
      custom: JSON.stringify(myObj),
      initialDoc: 'file.pdf',
      config: myfilesUrl + '/config.js',
    }, viewerElement);

    viewerElement.addEventListener('ready', () => {
      this.iframeWindow = viewerElement.querySelector('iframe').contentWindow
    });
  }
}