Easily load right-to-left language PDFs and Office documents and interact with them directly in your browser, without server-side dependencies.
This demo allows you to:
Implementation steps
To add Left-to-Right Language capability in WebViewer:
Step 1: Choose your preferred web stack
Step 2: Add the ES6 JavaScript sample code provided in this guide
1// ES6 Compliant Syntax
2// Copilot name: GitHub Copilot, version: 1.0.0, model: GPT-4, version: 2024-06, date: 2025-10-21
3// File: showcase-demos/rtl-language-support/index.js
4
5import WebViewer from '@pdftron/webviewer';
6
7function initializeWebViewer() {
8 WebViewer(
9 {
10 path: '/lib',
11 enableFilePicker: true, // Enable file picker to open files. In WebViewer -> menu icon -> Open File
12 licenseKey: 'YOUR_LICENSE_KEY', // Replace with your license key
13 },
14 document.getElementById('viewer')
15 ).then((instance) => {
16
17 // Customize the webviewer left panel
18 UIElements.customizeUI(instance);
19
20 // Listen for language change events
21 instance.UI.addEventListener('languageChanged', e => {
22 // Log the previous and new language codes to the console
23 console.log(`Previous language: ${e.detail.prev} -> New language: ${e.detail.next}`);
24 });
25
26 console.log('WebViewer loaded successfully.');
27 }).catch((error) => {
28 console.error('Failed to initialize WebViewer:', error);
29 });
30};
31
32// Function to handle RTL language selection
33window.SelectRTLLanguage = (instance, rtlLanguage, matchingButton) => {
34 UIElements.supportedRtlLanguages.forEach((lang) => {
35 lang.button.className = 'rtl-button';
36 });
37
38 if (rtlLanguage !== null) {
39 // Set the selected rtl language and load the corresponding document
40 matchingButton.className = 'rtl-button-selected';
41 UIElements.selectedRtlLanguage = rtlLanguage;
42 instance.UI.setLanguage(UIElements.selectedRtlLanguage.id);
43 instance.UI.loadDocument(UIElements.selectedRtlLanguage.file);
44 } else {
45 // Reset language to English
46 UIElements.selectedRtlLanguage = null;
47 instance.UI.setLanguage('en');
48 }
49};
50
51//helper function to load the ui-elements.js script
52function loadUIElementsScript() {
53 return new Promise((resolve, reject) => {
54 if (window.UIElements) {
55 console.log('UIElements already loaded');
56 resolve();
57 return;
58 }
59 const script = document.createElement('script');
60 script.src = '/showcase-demos/rtl-language-support/ui-elements.js';
61 script.onload = function () {
62 console.log('✅ UIElements script loaded successfully');
63 resolve();
64 };
65 script.onerror = function () {
66 console.error('Failed to load UIElements script');
67 reject(new Error('Failed to load ui-elements.js'));
68 };
69 document.head.appendChild(script);
70 });
71}
72
73// Load UIElements script first, then initialize WebViewer
74loadUIElementsScript().then(() => {
75 initializeWebViewer();
76}).catch((error) => {
77 console.error('Failed to load UIElements:', error);
78});
1// ES6 Compliant Syntax
2// Copilot name: GitHub Copilot, version: 1.0.0, model: GPT-4, version: 2024-06, date: 2025-10-21
3// File: showcase-demos/rtl-language-support/ui-elements.js
4
5// Class with static UI elements and related functions for the rtl language support demo
6
7class UIElements {
8
9 // The list of registered panels in the webviewer
10 static viewerPanels = null;
11
12 // The tab panel, representing the webviewer left panel
13 static tabPanel = {
14 handle: null,
15 dataElement: 'tabPanel'
16 };
17
18 // The rtl language support sub-panel to be registered
19 static rtlLanguagePanel = {
20 handle: null,
21 dataElement: 'rtlLanguagePanel',
22 render: null,
23 };
24
25 static apryseFilesUrl = 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/';
26
27 // The list of supported rtl languages along with their sample files
28 static supportedRtlLanguages = [
29 {
30 id: 'ar',
31 name: 'العربية',
32 englishName: 'Arabic',
33 file: `${UIElements.apryseFilesUrl}UDHR-arabic.pdf`,
34 },
35 {
36 id: 'he',
37 name: 'עברית',
38 englishName: 'Hebrew',
39 file: `${UIElements.apryseFilesUrl}UDHR-hebrew.pdf`,
40 },
41 {
42 id: 'fa',
43 name: 'فارسی',
44 englishName: 'Persian',
45 file: `${UIElements.apryseFilesUrl}UDHR-persian.pdf`,
46 },
47 {
48 id: 'ur',
49 name: 'اردو',
50 englishName: 'Urdu',
51 file: `${UIElements.apryseFilesUrl}UDHR-urdu.pdf`,
52 },
53 ];
54
55 // The currently selected rtl language. Default to the first language in the supportedRtlLanguages list
56 static selectedRtlLanguage = UIElements.supportedRtlLanguages[0];
57
58 // Customize the webviewer left panel
59 static customizeUI = (instance) => {
60 const { UI } = instance;
61
62 // Set the toolbar group to the Annotations tools
63 UI.setToolbarGroup('toolbarGroup-Annotate');
64
65 // Close the tab panel (if it's open) for refreshment.
66 UI.closeElements([UIElements.tabPanel.dataElement]);
67
68 // Get the list of registered panels in the webviewer
69 UIElements.viewerPanels = UI.getPanels();
70
71 // Find the Tab Panel to modify. The rtl language sub-panel will be added to this Tab panel.
72 UIElements.tabPanel.handle = UIElements.viewerPanels.find((panel) => panel.dataElement === UIElements.tabPanel.dataElement);
73
74 // Register the rtl language sub-panel
75 UIElements.RegisterRtlLanguagePanel(instance);
76
77 // Add the new rtl language sub-panel to list of sub-panels under the Tab Panel
78 UIElements.rtlLanguagePanel.handle = { render: UIElements.rtlLanguagePanel.dataElement };
79 UIElements.tabPanel.handle.panelsList = [UIElements.rtlLanguagePanel.handle, ...UIElements.tabPanel.handle.panelsList];
80
81 UI.openElements([UIElements.tabPanel.dataElement]);
82 };
83
84 // Register the rtl language sub-panel
85 static RegisterRtlLanguagePanel = (instance) => {
86 UIElements.rtlLanguagePanel.render = UIElements.createRtlLanguagePanelElements(instance);
87 instance.UI.addPanel({
88 dataElement: UIElements.rtlLanguagePanel.dataElement,
89 location: 'left',
90 icon: '<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="796 796 200 200" enable-background="new 796 796 200 200" xml:space="preserve"><g><path d="M973.166,818.5H818.833c-12.591,0-22.833,10.243-22.833,22.833v109.333c0,12.59,10.243,22.833,22.833,22.833h154.333 c12.59,0,22.834-10.243,22.834-22.833V841.333C996,828.743,985.756,818.5,973.166,818.5z M896,961.5h-77.167 c-5.973,0-10.833-4.859-10.833-10.833V841.333c0-5.974,4.86-10.833,10.833-10.833H896V961.5z M978.58,872.129 c-0.547,9.145-5.668,27.261-20.869,39.845c4.615,1.022,9.629,1.573,14.92,1.573v12c-10.551,0-20.238-1.919-28.469-5.325 c-7.689,3.301-16.969,5.325-28.125,5.325v-12c5.132,0,9.924-0.501,14.366-1.498c-8.412-7.016-13.382-16.311-13.382-26.78h11.999 c0,8.857,5.66,16.517,14.884,21.623c4.641-2.66,8.702-6.112,12.164-10.351c5.628-6.886,8.502-14.521,9.754-20.042h-49.785v-12 h22.297v-11.986h12V864.5h21.055c1.986,0,3.902,0.831,5.258,2.28C977.986,868.199,978.697,870.155,978.58,872.129z"/><g><g><path d="M839.035,914.262l-4.45,11.258h-15.971l26.355-61.09h15.971l25.746,61.09h-16.583l-4.363-11.258H839.035zM852.475,879.876l-8.902,22.604h17.629L852.475,879.876z"/></g></g></g></svg>',
91 title: 'RTL Languages',
92 render: () => UIElements.rtlLanguagePanel.render,
93 });
94 };
95
96 // Create the rtl language panel elements.
97 static createRtlLanguagePanelElements = (instance) => {
98 let panelDiv = document.createElement('div');
99 panelDiv.id = 'rtlLanguagePanel';
100
101 let paragraph = document.createTextNode('Load right to left language PDFs and Office documents and interact with them directly in your browser, without server-side dependencies, thanks to the Apryse Web SDK\'s RTL capabilities.');
102 panelDiv.appendChild(paragraph);
103
104 let dividerDiv = document.createElement('div');
105 dividerDiv.style.borderTop = '1px solid #ccc';
106 dividerDiv.style.margin = '10px 0';
107 panelDiv.appendChild(dividerDiv);
108
109 // Languages division title
110 let languagesTitle = document.createElement("h3");
111 languagesTitle.textContent = "Languages";
112 panelDiv.appendChild(languagesTitle);
113
114 // Create a button for each supported rtl language
115 UIElements.supportedRtlLanguages.forEach((rtlLanguage) => {
116 let button = UIElements.createButton(instance, rtlLanguage);
117 rtlLanguage.button = button;
118 panelDiv.appendChild(document.createElement("p"));
119 panelDiv.appendChild(button);
120 });
121
122 panelDiv.appendChild(dividerDiv.cloneNode());
123
124 // Create the reset language button
125 let resetButton = UIElements.createButton(instance);
126 panelDiv.appendChild(document.createElement("p"));
127 panelDiv.appendChild(resetButton);
128
129 // Select the first rtl language by default
130 UIElements.selectedRtlLanguage.button.click();
131
132 return panelDiv;
133 };
134
135 // Create a button for the given rtl language.
136 // If rtlLanguage is null, create the reset language button.
137 static createButton = (instance, rtlLanguage = null) => {
138 let button = document.createElement("button");
139 button.id = (rtlLanguage === null) ? `resetBtn` : `${rtlLanguage.id}Btn`;
140 button.textContent = (rtlLanguage === null) ? 'Reset Language' : `${rtlLanguage.name} (${rtlLanguage.englishName})`;
141 button.style.width = '100%';
142 button.style.backgroundColor = 'blue';
143 button.style.color = 'white';
144 button.style.border = 'none';
145 button.style.padding = '10px 15px';
146 button.style.borderRadius = '12px';
147 button.onmouseover = () => button.style.opacity = '0.8';
148 button.onmouseout = () => button.style.opacity = '1.0';
149 button.style.cursor = 'pointer';
150 button.onclick = () => window.SelectRTLLanguage(instance, rtlLanguage, button);
151
152 return button;
153 };
154}
1/* RTL Language Support Demo Styles */
2
3.rtl-button {
4 background-color: blue;
5}
6
7.rtl-button-selected {
8 background-color: darkblue;
9}
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales