|
| 1 | +# JavaScript Hello World Sample - PWA |
| 2 | + |
| 3 | +[PWA](https://web.dev/progressive-web-apps/) is short for Progressive Web Apps which stand for web applications that have been designed to behave like platform-specific (native) applications. Check out the following on how to implement Dynamsoft Barcode Reader JavaScript SDK (hereafter called "the library") into a PWA application. |
| 4 | + |
| 5 | +## Official Sample |
| 6 | + |
| 7 | +* <a target = "_blank" href="https://demo.dynamsoft.com/Samples/DBR/JS/1.hello-world/10.read-video-pwa/helloworld-pwa.html">Hello World in PWA - Demo</a> |
| 8 | +* <a target = "_blank" href="https://github.com/Dynamsoft/barcode-reader-javascript-samples/tree/main/1.hello-world/10.read-video-pwa">Hello World in PWA - Source Code</a> |
| 9 | + |
| 10 | +## Preparation |
| 11 | + |
| 12 | +We will try to turn our most basic hello world sample into a PWA. |
| 13 | + |
| 14 | +First, create a file with the name "helloworld-pwa.html" and fill it with the following code: |
| 15 | + |
| 16 | +```html |
| 17 | +<!DOCTYPE html> |
| 18 | +<html lang="en"> |
| 19 | + |
| 20 | +<head> |
| 21 | + <meta charset="utf-8"> |
| 22 | + <meta name="viewport" content="width=device-width,initial-scale=1.0"> |
| 23 | + <title>Dynamsoft Barcode Reader PWA Sample - Hello World (Decoding via Camera)</title> |
| 24 | +</head> |
| 25 | + |
| 26 | +<body> |
| 27 | + <h1 style="font-size: 1.5em;">Hello World for PWA</h1> |
| 28 | + Loading... |
| 29 | + <script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.6.20/dist/dbr.js"></script> |
| 30 | + <script> |
| 31 | + Dynamsoft.DBR.BarcodeReader.license = 'DLS2eyJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSJ9'; |
| 32 | + (async function() { |
| 33 | + try { |
| 34 | + const scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance(); |
| 35 | + scanner.onFrameRead = results => { |
| 36 | + console.log("Barcodes on one frame:"); |
| 37 | + for (let result of results) { |
| 38 | + const format = result.barcodeFormatString; |
| 39 | + console.log(format + ": " + result.barcodeText); |
| 40 | + } |
| 41 | + }; |
| 42 | + scanner.onUniqueRead = (txt, result) => { |
| 43 | + alert(txt); |
| 44 | + console.log("Unique Code Found: ", result); |
| 45 | + } |
| 46 | + await scanner.show(); |
| 47 | + } catch (ex) { |
| 48 | + let errMsg = ex.message||ex; |
| 49 | + console.error(errMsg); |
| 50 | + alert(errMsg); |
| 51 | + } |
| 52 | + })(); |
| 53 | + |
| 54 | + if ('serviceWorker' in navigator) { |
| 55 | + navigator.serviceWorker.register('./service-worker.js'); |
| 56 | + }; |
| 57 | + </script> |
| 58 | +</body> |
| 59 | + |
| 60 | +</html> |
| 61 | +``` |
| 62 | + |
| 63 | +Next, set up a secure environment (HTTPs) to run the page "helloworld-pwa.html". This is required because PWAs only run in secure environments. |
| 64 | + |
| 65 | +In our case, we use IIS to set up a secure site at "https://localhost" and the page is put at the root so that it can be accessed at "https://localhost/helloworld-pwa.html". |
| 66 | + |
| 67 | +## Make the app progressive |
| 68 | + |
| 69 | +### Register a service worker for offline support |
| 70 | + |
| 71 | +As the basis for PWAs, Service Workers are a virtual proxy between the browser and the network. A service worker can serve content offline, handle notifications and perform heavy calculations, etc. all on a separate thread. |
| 72 | + |
| 73 | +To use a service worker, we first need to register it. In the helloworld-pwa.html file, add the following at the end of the script: |
| 74 | + |
| 75 | +```javascript |
| 76 | +if ('serviceWorker' in navigator) { |
| 77 | + navigator.serviceWorker.register('./service-worker.js'); |
| 78 | +}; |
| 79 | +``` |
| 80 | + |
| 81 | +Create the service-worker.js file with the following content: |
| 82 | + |
| 83 | +```javascript |
| 84 | +// Files to cache |
| 85 | +const cacheName = 'helloworld-pwa'; |
| 86 | +const appShellFiles = [ |
| 87 | + './helloworld-pwa.html', |
| 88 | +]; |
| 89 | + |
| 90 | +// Installing Service Worker |
| 91 | +self.addEventListener('install', (e) => { |
| 92 | + console.log('[Service Worker] Install'); |
| 93 | + e.waitUntil((async () => { |
| 94 | + const cache = await caches.open(cacheName); |
| 95 | + console.log('[Service Worker] Caching all: app shell and content'); |
| 96 | + await cache.addAll(appShellFiles); |
| 97 | + })()); |
| 98 | +}); |
| 99 | + |
| 100 | +self.addEventListener('fetch', (e) => { |
| 101 | + e.respondWith((async () => { |
| 102 | + const r = await caches.match(e.request); |
| 103 | + console.log(`[Service Worker] Fetching resource: ${e.request.url}`); |
| 104 | + if (r) { return r; } |
| 105 | + const response = await fetch(e.request); |
| 106 | + const cache = await caches.open(cacheName); |
| 107 | + console.log(`[Service Worker] Caching new resource: ${e.request.url}`); |
| 108 | + if (e.request.method !== "POST") |
| 109 | + cache.put(e.request, response.clone()); |
| 110 | + return response; |
| 111 | + })()); |
| 112 | +}); |
| 113 | +``` |
| 114 | + |
| 115 | +With the above code, the application can now work offline because the service worker will cache the page helloworld-pwa.html and its related resources. |
| 116 | + |
| 117 | +For more information, refer to [Making PWAs work offline with Service workers](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Offline_Service_workers). |
| 118 | + |
| 119 | +> NOTE |
| 120 | +> |
| 121 | +> Since the files are being cached, changes we make in later steps may not be reflected. Therefore, don't forget to clear the cache after a change is made. To do so, you can run the following in the browser console. |
| 122 | +> |
| 123 | +> ```javascript |
| 124 | +> const cacheName = 'helloworld-pwa'; |
| 125 | +> const cache = await caches.delete(cacheName); |
| 126 | +> ``` |
| 127 | +
|
| 128 | +### Use a web manifest file to make the application installable |
| 129 | +
|
| 130 | +A web manifest file contains a list of information about a website in a JSON format. This information is used to present the web app correctly for installation on a device. |
| 131 | +
|
| 132 | +In our example, we first create a file "helloworld-pwa.webmanifest" with the following content: |
| 133 | +
|
| 134 | +```json |
| 135 | +{ |
| 136 | + "name": "Dynamsoft Barcode Reader Progressive Web App", |
| 137 | + "short_name": "DBR-PWA", |
| 138 | + "description": "Progressive Web App that reads barcodes from a video input with Dynamsoft Barcode Reader.", |
| 139 | + "start_url": "./helloworld-pwa.html", |
| 140 | + "scope": ".", |
| 141 | + "display": "standalone", |
| 142 | + "theme_color": "#B12A34", |
| 143 | + "background_color": "#B12A34", |
| 144 | + "icons": [ |
| 145 | + { |
| 146 | + "src": "./dynamsoft-512x512.png", |
| 147 | + "sizes": "512x512", |
| 148 | + "type": "image/png" |
| 149 | + }, |
| 150 | + { |
| 151 | + "src": "./dynamsoft-192x192.png", |
| 152 | + "sizes": "192x192", |
| 153 | + "type": "image/png" |
| 154 | + } |
| 155 | + ] |
| 156 | +} |
| 157 | +``` |
| 158 | +
|
| 159 | +> The icon files can be found in the github repository. |
| 160 | +
|
| 161 | +Then we include the file in the <head> block of the helloworld-pwa.html file: |
| 162 | + |
| 163 | +```html |
| 164 | +<link rel="manifest" href="helloworld-pwa.webmanifest"> |
| 165 | +``` |
| 166 | + |
| 167 | +For compatibility on safari, we need add some `meta` in `<head>`: |
| 168 | + |
| 169 | +```html |
| 170 | +<meta name="theme-color" content="#B12A34"> |
| 171 | +<meta name="mobile-web-app-capable" content="yes"> |
| 172 | +<meta name="apple-mobile-web-app-title" content="sample for ios"> |
| 173 | +<meta name="apple-mobile-web-app-capable" content="yes"> |
| 174 | +<meta name="apple-mobile-web-app-status-bar-style" content="default"> |
| 175 | +<link rel="apple-touch-icon" sizes="192x192" href="./dynamsoft-192x192.png" /> |
| 176 | +<link rel="apple-touch-icon" sizes="512x512" href="./dynamsoft-512x512.png" /> |
| 177 | +``` |
| 178 | + |
| 179 | +Now, if you open the application again in your browser, you will notice an install icon appear on the right side of the address bar. When you click on it, a pop-up will appear asking if you want to install the app. |
| 180 | + |
| 181 | +Once installed, you can use it like a native app. |
| 182 | + |
| 183 | +For offline use, you need to cache more files. |
| 184 | + |
| 185 | +service-worker.js |
| 186 | +```javascript |
| 187 | +const dbrVersion = "9.6.20"; |
| 188 | +const dbrCdn = `https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@${dbrVersion}/dist/`; |
| 189 | + |
| 190 | +const appShellFiles = [ |
| 191 | + './helloworld-pwa.html', |
| 192 | + './dynamsoft-192x192.png', |
| 193 | + './dynamsoft-512x512.png', |
| 194 | + './helloworld-pwa.json', |
| 195 | + `${dbrCdn}dbr.js`, |
| 196 | + `${dbrCdn}dbr-${dbrVersion}.full.wasm`, |
| 197 | + `${dbrCdn}dbr-${dbrVersion}.full.wasm.js`, |
| 198 | + `${dbrCdn}dbr-${dbrVersion}.browser.worker.js`, |
| 199 | +]; |
| 200 | +``` |
| 201 | + |
| 202 | +## Summary |
| 203 | + |
| 204 | +In this article we took a look at how you can turn a simple barcode reading page into a PWA that is installable, re-engageable and capable of working offline. To learn more about Progressive web apps, you can click [here](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps). |
0 commit comments