{"id":1466,"date":"2021-04-15T12:09:19","date_gmt":"2021-04-15T19:09:19","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=1466"},"modified":"2021-04-15T12:09:19","modified_gmt":"2021-04-15T19:09:19","slug":"dual-screen-pwa","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/dual-screen-pwa\/","title":{"rendered":"Build and deploy dual-screen progressive web apps"},"content":{"rendered":"<p>\n  Hello web developers,\n<\/p>\n<p>\n  We&#8217;ve posted previously about using <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/build-and-test-dual-screen-web-apps\/?WT.mc_id=blog-surfaceduoblog-justinwillis96\">dual-screen media queries and JavaScript<\/a> to adapt web apps for Microsoft Surface Duo. Today\u2019s post is about how you can use those dual-screen capabilities in your progressive web app (PWA) and deploy to both the Google Play Store AND the Microsoft Store using <a href=\"https:\/\/twitter.com\/pwabuilder?s=20\">PWABuilder<\/a>! We\u2019ll share a little about the benefits of PWAs and then walk through how to create one from this photo-editing example that\u2019s available on <a href=\"https:\/\/thankful-tree-07da4921e.azurestaticapps.net\/\">the web<\/a>.\n<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-web-800.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-web-800.png\" alt=\"Surface Duo showing photo editing app in Edge browser\" width=\"800\" height=\"620\" class=\"alignnone size-full wp-image-1474\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-web-800.png 800w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-web-800-300x233.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-web-800-768x595.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><em>Figure 1: Screenshot of the SimpleEdit website being used on Surface Duo<\/em>\n<\/p>\n<h2>What is a progressive web app?<\/h2>\n<p>\n  A progressive web app, or PWA for short, is a web app that uses modern web APIs to enable a true app-like experience delivered over the web. PWAs, through the usage of standard web APIs, can also tie into the same features as any other app on Android and Windows from using the built-in sharing UI all the way to Bluetooth, background data sync, push notifications, and more! Finally, because your PWA is still delivered through the web just like any other web app, you still retain all the benefits of being a web app, such as fast updates and being totally cross-platform. \n<\/p>\n<h2>But wait, what if web apps can\u2019t do something my app needs? <\/h2>\n<p>\n  While web app functionality may have been limited in the past, with initiatives such as <a href=\"https:\/\/web.dev\/fugu-status\/\">Project Fugu<\/a> from the Chromium community, the list of things PWAs CAN\u2019T do has become much shorter. For example, PWAs on both Android and Windows have access to the following APIs:\n<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/microsoft-edge\/progressive-web-apps-chromium\/webappmanifests\/?WT.mc_id=docs-surfaceduoblog-justinwillis96#use-shortcuts-to-provide-quick-access-to-features\">Shortcuts (previously called Jumplists)<\/a>\n  <\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/microsoft-edge\/progressive-web-apps-chromium\/webappmanifests\/?WT.mc_id=docs-surfaceduoblog-justinwillis96#identify-your-app-as-a-share-target\">Share Target<\/a>\n  <\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/updates\/2015\/07\/interact-with-ble-devices-on-the-web\">Web Bluetooth<\/a>\n  <\/li>\n<li><a href=\"https:\/\/components.pwabuilder.com\/demo\/web_share\">Web Share<\/a>\n  <\/li>\n<li><a href=\"https:\/\/web.dev\/badging-api\/\">App Badging<\/a>\n  <\/li>\n<li><a href=\"https:\/\/www.webcomponents.org\/introduction\">Web Components<\/a>\n  <\/li>\n<li><a href=\"https:\/\/web.dev\/notification-triggers\/\">Notification Triggers<\/a>\n  <\/li>\n<li><a href=\"https:\/\/web.dev\/idle-detection\/\">Idle Detection API<\/a>\n  <\/li>\n<li><a href=\"https:\/\/components.pwabuilder.com\/demo\/wake_lock\">Wake Lock API<\/a>\n  <\/li>\n<li><a href=\"https:\/\/doc.babylonjs.com\/divingDeeper\/webXR\/introToWebXR\">WebXR<\/a>\n  <\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/WebGL_API\/Tutorial\">WebGL 2.0<\/a>\n  <\/li>\n<li><a href=\"https:\/\/webassembly.org\/\">WebAssembly<\/a>\n  <\/li>\n<\/ul>\n<p>\n  And many, many more! Because of this, we recommend taking a second look if you were not able to achieve certain functionality in the past on the web. Chances are, the web CAN do that now! For example, the <strong>SimpleEdit<\/strong> site lets the user take a photo, open a file from the device, and trigger the share sheet. It also uses the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/web\/css-media-spanning\/?WT.mc_id=docs-surfaceduoblog-justinwillis96\">CSS media query for screen-spanning<\/a> to make <a href=\"https:\/\/github.com\/pwa-builder\/pwa-starter\/blob\/master\/src\/script\/pages\/app-home.ts#L48-L58\">dual-screen layout adjustments<\/a> for Surface Duo.\n<\/p>\n<h2>Web and app stores?<\/h2>\n<p>\n  Before we dive into how PWABuilder helps you build great dual-screen enabled PWAs and package them for app stores, let\u2019s first discuss why we might want to ship our web app to an app store. First, it is important to remember that because your app is a PWA, your main delivery channel will always be the open web! Every PWA still has a URL (eg. <a href=\"https:\/\/webboard-app.web.app\/\">webboard-app.web.app<\/a>) and therefore, your users can still get to your app without having to download the app from an app store. However, it is also important to remember that most users are accustomed to getting their apps from an app store, especially on mobile, and therefore you may be missing out on a large portion of potential users by not being in an app store. This is a big part of the magic of PWAs, with only one app and one codebase you can target a wide range of users on a wide range of operating systems, even if that user prefers to just stay in their web browser!\n<\/p>\n<h2>How to use PWABuilder<\/h2>\n<p><a href=\"https:\/\/www.pwabuilder.com\/\">PWABuilder<\/a> is an open-source project from Microsoft that enables you to easily package your PWA for app stores like Google Play and the Microsoft Store. Microsoft also provides a <a href=\"https:\/\/medium.com\/pwabuilder\/building-pwas-with-web-components-33f986bf8e4c?source=friends_link&amp;sk=9f449e76bbb37f063283602c6c3f946f\">PWA starter kit<\/a> that can make it easier to build high quality, store ready PWAs with a tech stack that the PWABuilder team itself uses to build PWAs. Today however, we are going to focus on the packaging abilities of PWABuilder. Let\u2019s take a PWA I have built, <strong>SimpleEdit<\/strong>  (available on <a href=\"https:\/\/thankful-tree-07da4921e.azurestaticapps.net\/\">the web<\/a>) and use PWABuilder to generate both a dual-screen ready package for the Google Play Store and a Windows package for the Microsoft Store.\n<\/p>\n<ol>\n<li>\n  Go to <a href=\"https:\/\/www.pwabuilder.com\">https:\/\/www.pwabuilder.com<\/a> and enter the URL to your PWA.\n  <br \/>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-3.png\" alt=\"Input box to supply PWA URL\" width=\"338\" height=\"120\" class=\"alignnone size-full wp-image-1479\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-3.png 338w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-3-300x107.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a>\n<\/li>\n<li>\n  Click start to analyze the URL and then click <strong>Build My PWA.<\/strong><br \/>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-4.png\" alt=\"Build PWA button\" width=\"338\" height=\"129\" class=\"alignnone size-full wp-image-1480\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-4.png 338w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-4-300x114.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a>\n<\/li>\n<li>\n  You are then asked which app stores to publish in. Choose <strong>Android<\/strong> to package for the Google Play Store.\n  <br \/>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-5.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-5.png\" alt=\"Android app download button\" width=\"338\" height=\"338\" class=\"alignnone size-full wp-image-1481\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-5.png 338w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-5-300x300.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/pwa-image-5-150x150.png 150w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a>\n<\/li>\n<li>\n  Tap <strong>Download<\/strong> to get your Google Play Store ready package!  \n  <br \/>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-6.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-6.png\" alt=\"Choose Download button in dialog\" width=\"338\" height=\"165\" class=\"alignnone size-full wp-image-1482\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-6.png 338w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-6-300x146.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a>\n<\/li>\n<li>\n  Finally, make sure you tap the <strong>Readme<\/strong> file in the downloaded folder if you need help with publishing this package to the store or are just looking for more details.\n  <br \/>\n   <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-7.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-7.png\" alt=\"README file is in the output directory\" width=\"338\" height=\"195\" class=\"alignnone size-full wp-image-1483\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-7.png 338w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/word-image-7-300x173.png 300w\" sizes=\"(max-width: 338px) 100vw, 338px\" \/><\/a>\n<\/li>\n<\/ol>\n<p>\n  And just like that, you can now publish your PWA to Google Play! <strong>SimpleEdit<\/strong> is <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=net.azurestaticapps.thankful_tree_07da4921e.twa&amp;hl=en&amp;gl=US\">already available<\/a> to install on your Android device:\n<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-pwa-800.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-pwa-800.png\" alt=\"Surface Duo showing photo editing PWA\" width=\"800\" height=\"620\" class=\"alignnone size-full wp-image-1476\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-pwa-800.png 800w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-pwa-800-300x233.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/04\/simpleedit-pwa-800-768x595.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><em>Figure 2: Screenshot of SimpleEdit as a progressive web app on Surface Duo<\/em>\n<\/p>\n<h2>Publishing for Windows<\/h2>\n<p>\n  For publishing to the Microsoft Store, the steps are very much the same. Check out <a href=\"https:\/\/medium.com\/pwabuilder\/bringing-chromium-edge-pwas-progressive-web-apps-to-the-microsoft-store-c0bd07914ed9?source=friends_link&amp;sk=04ca8b2ae2bd094b04ef6b53780b5698\">this tutorial<\/a> for more information on shipping your PWA to the Microsoft Store!\n<\/p>\n<p>\n  Here\u2019s the link for <strong>SimpleEdit<\/strong> on the <a href=\"https:\/\/www.microsoft.com\/store\/productId\/9NQW566N4866\">Microsoft Store<\/a> for you to try out.\n<\/p>\n<h2>Resources and feedback<\/h2>\n<p>\n  Source code is available on GitHub for both <a href=\"https:\/\/github.com\/jgw96\/simple-image-editor\">SimpleEdit<\/a> and <a href=\"https:\/\/github.com\/jgw96\/web-whiteboard\">webboard<\/a> PWAs mentioned in the post.\n<\/p>\n<p>\n  We&#8217;re excited to see more web apps come to Surface Duo. Ask questions or tell us about your projects using our <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a> or message us on Twitter <a href=\"https:\/\/twitter.com\/surfaceduodev\">@surfaceduodev<\/a>.\n<\/p>\n<p>Finally, join us at 11am PST tomorrow on <a href=\"https:\/\/\">twitch.tv\/surfaceduodev<\/a> to discuss progressive web apps and how you can enhance them for dual-screens and publish to app stores. You can also check out past streams on <a href=\"https:\/\/www.youtube.com\/channel\/UClGu9QLtPNz8OdddBfhZXPA\">YouTube<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello web developers, We&#8217;ve posted previously about using dual-screen media queries and JavaScript to adapt web apps for Microsoft Surface Duo. Today\u2019s post is about how you can use those dual-screen capabilities in your progressive web app (PWA) and deploy to both the Google Play Store AND the Microsoft Store using PWABuilder! We\u2019ll share a [&hellip;]<\/p>\n","protected":false},"author":56669,"featured_media":1476,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[412,716,530],"class_list":["post-1466","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-javascript","tag-progress-web-apps","tag-web"],"acf":[],"blog_post_summary":"<p>Hello web developers, We&#8217;ve posted previously about using dual-screen media queries and JavaScript to adapt web apps for Microsoft Surface Duo. Today\u2019s post is about how you can use those dual-screen capabilities in your progressive web app (PWA) and deploy to both the Google Play Store AND the Microsoft Store using PWABuilder! We\u2019ll share a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/56669"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=1466"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1466\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/1476"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=1466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=1466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=1466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}