Skip to content

Developer Insights

Join millions of viewers! Our engineers craft human-written articles solving real-world problems weekly. Enjoy fresh technical content and numerous interviews featuring modern web advancements with industry leaders and open-source authors.

Newest First
Tags:PWA
The Renaissance of PWAs cover image

The Renaissance of PWAs

What Are PWAs? Progressive Web Apps, or PWAs, are not a new concept. In fact, they have been around for years, and have been adopted by companies such as Starbucks, Uber, Tinder, and Spotify. Here at This Dot, we have written numerous blog posts on PWAs. PWAs are essentially web applications that utilize modern web technologies to deliver a user experience akin to native apps. They can work offline, send push notifications, and even be added to a user's home screen, thus blurring the boundaries between web and native apps. PWAs are built using standard web technologies like HTML, CSS, and JavaScript. However, they leverage advanced web APIs to deliver enhanced capabilities. Most web apps can be transformed into PWAs by incorporating certain features and adhering to standards. The keystones of PWAs are the service worker and the web app manifest. Service workers enable offline operation and background syncing by acting as network proxies, managing requests programmatically. The web app manifest, on the other hand, gives the PWA a native-like presence on the user's device, specifying its appearance when installed. Looking Back The concept of PWAs was introduced by Google engineers Alex Russell and Frances Berriman in 2015, even though Steve Jobs had already discussed the idea of web apps that resembled and behaved like native apps as early as 2007. However, despite the widespread adoption of PWAs over the years, Apple's approach to PWAs drastically changed after Steve Jobs' 2007 presentation, distinguishing it from other tech giants such as Google and Microsoft. As a leader in technological innovation, Apple was notably slower in adopting PWA technology, much of which can be attributed to its business model and the ecosystem it built around the App Store. For example, Safari, Apple's web browser, has historically been slow to adopt the latest web standards and APIs crucial for PWAs. Features such as push notifications, background sync, and access to certain hardware functionalities were unsupported or only partially supported for a long time. As a result, the PWA experience on iOS/iPadOS was not - and to some extent, still isn't - on par with that provided by Android. Despite the varying degrees of support from different vendors, PWAs have seen a significant increase in adoption since 2015, both by businesses and users, due to their cross-platform nature, offline capabilities, and the enhanced user experience they offer. Major corporations like Twitter, Pinterest, and Alibaba have launched PWAs, leading to substantial increases in user engagement and session duration. For instance, according to a 2017 Pinterest case study, Pinterest's PWA led to a 60% increase in core engagements and a 44% increase in user-generated ad revenue. Google and Microsoft have also championed this technology, integrating more PWA support into their platforms. Google highlighted the importance of PWAs for the mobile web, while Microsoft sought to populate its Windows Store with PWAs. Apple's Shift Towards PWAs Despite slower adoption and limited support, Apple isn't completely dismissing PWAs. Recent updates have indicated some promising improvements in PWA capabilities on both iOS/iPadOS and MacOS. For instance, in iOS/iPadOS 16 released last year, Apple added notifications for Home Screen web apps, utilizing the Web Push standard with support for badging. They also included an API for iOS/iPadOS browsers to facilitate the 'Add to Home Screen' feature. The forthcoming Safari 17 and MacOS Sonoma releases, announced at June's WWDC, promise even more significant changes, most notably: Installing Web Apps on MacOS, iOS, and iPadOS Any web app, not just PWAs, can now be added to the MacOS dock from the File menu. Once added, these web apps will open in their own window and integrate with operating system features such as the Stage Manager, Screen Time, Notifications, and Focus. They will also have their own isolated storage, and any cookies present in the Safari browser for that web app at the time of installation will be transferred to this isolated storage. This means many users will not need to re-authenticate to web apps after installing them locally. PWAs, in particular, can control the appearance and behavior of the installed web app via the PWA manifest. For instance, if your web app already includes navigation controls, or if they're not necessary in the context of the app, you can manage whether the navigation buttons are displayed by setting the display configuration option in the manifest to standalone. The display option will also be taken into consideration in iOS/iPadOS, where standalone web apps will become *Home Screen web apps*. These apps offer a standalone, app-like experience on iOS, complete with separate cookies and storage from the browser, and improved notification handling. Improved Notifications Apple initially added support for notifications in iOS/iPadOS 16, but Safari 17 and MacOS Sonoma take it a step further. If you've already implemented Web Push according to web standards, then push notifications should work for your web page as a web app on Mac without any additional effort. Moreover, the silent property is now taken into account, and there are several improvements to the Notifications API to enhance its reliability. These recent updates put the support for notifications on Mac on par with iOS/iPadOS, including support for badging, and seamless integration with the Focus mode. Improved API Over the past year, Apple has also introduced several other API-level improvements. The enhancements to the User Activation API aid in determining whether a function that depends on user activation, such as requesting permission to send notifications, is called. Safari 16 updated the un-prefixed Fullscreen API, and introduced preliminary support for the Screen Orientation API. Safari 17 in particular has improved support for the Storage API and added support for ReadableStream. The Renaissance of PWAs? With the new PWA-related features in the Apple ecosystem, it's hard not to wonder if we are witnessing a renaissance of PWAs. Initially praised for their ability to leverage web technology to create app-like experiences, PWAs went through a period of relative stagnation, especially on Apple's platforms. For a time, Apple was noticeably more conservative in their implementation of PWA features. However, their recent bolstering of PWA support in Safari signals a significant shift, aligning the browser with other major platforms such as Google Chrome and Microsoft Edge, both of which have long supported PWAs. The implications of this shift are profound. This widespread and robust support for PWAs across all major platforms could effectively reduce the gap between web applications and native applications. PWAs, with their promise of a single, consistent experience across all devices, could become the preferred choice for businesses and developers. The cost-effectiveness of developing and maintaining one PWA versus separate applications for multiple platforms is an undeniable benefit. The fact that all these platforms are now heavily supporting PWAs might suggest an industry-wide shift toward a more unified and simplified development paradigm, hinting that indeed, we could be on the verge of a PWA renaissance....

WebGL Morph Targets and Ginger: Modernizing for Today's Web cover image

WebGL Morph Targets and Ginger: Modernizing for Today's Web

WebGL Morph Targets and Ginger: Modernizing for Today's Web Ginger is a morph target demo that was initially written in 2011 for chrome experiments, and then rewritten to work as progressive web app in early 2016. In essence, Ginger is a customizable head that uses a slider to tweak various facial features, much like a character customization system one would find in a video game. It also supports taking screenshots, and generating share links that can be used to share your creation with others. The rewrite in 2016 focused on improving performance, and supporting modern web features. Notable improvements were made in the following areas: 1. Utilizing HTTP/2 multiplexing to load model data concurrently, and efficiently. 2. Utilize manifest.json for "Add to Homescreen" capability. 3. Offering a full offline experience with service workers. 4. Performance improvements from the previous version. We inherited the project with our recent acquisition of Stickman Ventures, and thought it appropriate to showcase. Since it was rewritten in 2016, Ginger hasn't been touched, and has fallen into neglect, though it still worked fine in modern browsers. It was using an old version of Polymer 2 which has long since fallen out of use. The Refactor The first order of business was replacing Polymer 2 usage with something more modern. Polymer 2 was bleeding edge at the time, and used many proposed browser features that have since been adopted or dropped in favor for other standards (modules vs HTML imports). Replacing Polymer with lit-html To reduce friction, we opted to refactor Ginger's web components to use lit-html from the Polymer Project. Lit isn't a framework necessarily, it just makes it easier to write standard web components that are efficient, and work across all major browsers. Transitioning from Polymer to lit was not a very complicated process, as they both use the same element lifecycle. The most notable difference was the transition from HTML imports to modules. With Polymer 2, elements are defined inside of HTML files, and are imported directly using HTML imports; however lit-html allows defining elements using a modern class-based approach. ` With lit-html, it's very easy to define custom elements by extending off of the LitElement class, and registering it using either customElements.define or the decorator. We then use rollup.js and babel to create a bundle that works well across browsers. Using Workbox to Support Offline Usage Ginger is able to work completely offline thanks to its use of service workers. The previous iteration of Ginger used a service worker that came from platinum elements. Platinum elements made it possible to add offline capabilities to an application with very little effort. However, they've been deprecated in favor of workbox and sw-toolbox. We chose to go with workbox as it supports all of the features that we need, and I was already familiar with it. The service worker uses caching strategies to cache images, fonts, code and model data. Data that won't change often or at all uses the "cache first" strategy, while code uses the "stale while revalidate" strategy. The cache first strategy will grab the requested file from the cache if it exists, and do nothing else. The stale while revalidate strategy will return the cached data similar to the cache first strategy; however, it will also download a newer version from the server in the background. Here's some basic examples taken directly from Ginger. ` You can find out more about other caching strategies that workbox offers in their docs. Closing You can find Ginger's source code on Github, and it's available under an Apache 2 license. The Ginger model was created, and is copyright of David Steele. This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License....

Announcing Free Trainings - Progressive Web Apps and Using NgUpgrade for your Angular Migration cover image

Announcing Free Trainings - Progressive Web Apps and Using NgUpgrade for your Angular Migration

Less than two weeks after wrapping up our inaugural JavaScript Marathon, we are thrilled to share two brand new free trainings from the team at This Dot Labs - available for you to watch anytime. In Introduction to PWAs and Service Workers, Software Engineer Pato Vargas will walk you through creating your first PWA, implementing push notifications, testing your features, and using Firebase. "I really enjoyed working on this training," says Vargas, "learning service workers is important for any JavaScript developer, so this training appeals to anyone writing JavaScript!" Software Engineer, Frederick Prijk, is also excited to present his new training series, Upgrading AngularJS to Angular Using NgUpgrade, which walks you through a simple AngularJS to Angular migration in just over an hour! You can find these trainings, and all other past trainings, including those presented in the JavaScript Marathon series, by visiting our free resources page! Introducing a new technology to your enterprise development team, or having trouble with an existing technology? Learn more about how This Dot Labs can tailor a training program to your team by chatting with us, or by reviewing the trainings we already offer!...

History of Mobile Web Development and the rise of PWA cover image

History of Mobile Web Development and the rise of PWA

In this post, we are going to cover the history of Mobile Development, provide insightful details of current trends and uses of Progressive Web App development...

How to do social Media sharing in your PWA cover image

How to do social Media sharing in your PWA

PWA using Web Share API Have you wondered how you can make a use of the "social" sharing API PWA? You know, when you want to share something, and it gives you the option to share via email, Twitter, Instagram, etc? Well, it's actually very easy! Take a look at the demo app to test it on your device. LIVE DEMO https://pwa-share-api.firebaseapp.com/ About the project I have built the sample project that can be found in this repo. In this project, you can see how I added the share functionality to the PWA , but you don't need a service worker or a PWA to add this functionality. I added it to this project because I wanted to show you how to do it specifically in a PWA, but you can add my code to any web app easily! Web Share API The bland definition of what a WSA is: > The Web Share API is meant to help developers implement sharing functionality into their apps or websites, but using the device’s native sharing capabilities instead of having to resort to scripts from the individual social platforms and DIY implementations. The API surface is a simple as it gets.- alligator.io The Web Share API has two share methods: share() and canShare(). The ShareData dictionary of the web share v1 consists of several optional members: text member: Arbitrary text that forms the body of the message being shared. title member : The title of the document being shared. May be ignored by the target. url member : A URL string referring to a resource being shared. The canShare() method contains an extra field which is the files property. files member: A File array referring to files being shared. To read more about it, check out this link So let's have a look at how it actually works. First, let's collect data to make our ShareData dictionary. ` Then, after we have declared what we want to share, we can use it in the .share() method. ` We can put that inside of a function, called onShare(), for example. ` Then pass the onShare() as a click handler to the share button. ` If you want to take it to the next level, you can check to make sure the *web share api* is supported by your browser. Your code will look as follows: ` If you want to use the canShare(), to send files, your code might look like this ` Browser Support If you go to canisue.com, you can see that browser's support for the share() method. Pretty much every major browser supports it. What about the canShare() method? Not as good as the share() method, hopefully it gets to more browsers soon. Resources https://www.w3.org/TR/web-share/#sharedata-dictionary https://alligator.io/js/web-share-api/ https://web.dev/web-share/...

PWA Push Notifications with Firebase (Cloud Messaging)-pt1 cover image

PWA Push Notifications with Firebase (Cloud Messaging)-pt1

Push Notification In Your PWA Have you ever wondered how to add the famous/annoying push notifications to your app? Well, in this tutorial I'm going to show you how to do it using Firebase Cloud Messaging. *Note:* This tutorial requires some basic knowledge on PWAs and Service Workers. You can take a look to my Intro to PWA and Service Workers here and About PWA and notifications here. Before we begin, I need to clarify that the Notification API, and the Push API, are not the same. People get them confused all the time. Push API: The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent. This lets developers deliver asynchronous notifications and updates to users that opt in, resulting in better engagement with timely new content. Let's doooo it!! The final code is in the FINAL branch inside of the repo. 1) Clone this repo: https://github.com/devpato/pwa-FCM-notifications-tutorial As you can see, I already have the basic structure of the app created for you, since we are only going to worry about how to send the messages via push notifications using the Firebsae Cloud Messaging service. 2) Navigate to the index.html file. Notice I imported Firebase for you: ` 3) Navigate to Firebase.com, and create an account if you don't have one. 4) Once you are in the Firebase console, navigate to project settings (in case you don't have a project yet - just create it there) 5) Inside of project setting, under the General tab scroll all the way down to find your Firebase SDK snippet (if it's not there yet - this means that you've created a new project, and need to add there an app. Either way, this can be done in the same place where you then will have your SDK snippet - under the General tab). Copy paste it in a safe place. The snippet should look like this: 6) Go to your index.js file, and copy paste the following after the global variables I declared for you. Replace it with your project's customized code - the snippet from step 4. ` 7) Right after - initialize the firebase instance. ` 8) Then, we are going to create a constant called messaging, and will set it to firebase messaging service. ` 9) Time to request permission from firebase cloud messaging. Once we get the thumbs up, they will give us a token as a promise. ` 10) Then, we are going to use the messaging.onMessage() method. This is used for receiving data, and notification payloads, by all users that are currently viewing the page (the page is in the foreground). To do so, we add the following code: ` 11) Notice a firebase-messaging-sw.js file. This file name is going to be searched by the Firebase SDK. The file needs to be in the ROOT of your project. The Firebase SDK will do some magic in the background to register the file as a service worker. 12) Inside of your firebase-messaging-sw.js, initialize the Firebase app by passing in the messagingSenderId. The sender id can be found inside of your project settings as the following image shows. ` 13) Retrieve an instance of Firebase Messaging so that it can handle background messages. ` 14) Background message handler (this one will be invoked when the page is in the backround) ` Test The Notification 15) Run the app using any http server 16) Inside of your Cloud Messaging settings (a tab in the Firebase Console > Project Settings), copy the server key. 17) If you have a Postman http client, do the following: POST URL:* https://fcm.googleapis.com/fcm/send * HEADERS: Content-Type - application/json Authorization - key=server_key BODY: ` Then, click the Send button. At this point, if our app is in the foreground (it is currently opened tab in your browser), then you'll see the message we've sent in the console - handled by messaging.onMessage. But if it is in the background, then it will be handled by messaging.setBackgroundMessageHandler in the service worker, and you'll see something like this: Test your app on a real device by deploying to Firebase or any other hosting provider. If you want to host your app on the Firebase - take a look at my other tutorial. In the next tutorials, I will show you how to successfully subscribe to notifications and push them using the Firebase console....

Intro to PWA  and Service Workers cover image

Intro to PWA and Service Workers

Progressive Web Apps Progressive Web Apps, aka PWAs, are becoming more and more popular everyday. In this tutorial, I'm going to tell you what a progressive web app is, and how to create one using a service worker. What is a PWA? A PWA is an app that is intented to behave like a native app on your phone. It's a regular web app that, when you open it on your browser, displays a message saying "Add to Home Screen" once you click on the message, your app will be intalled on your phone and you will see the logo on your device's home screen. PWAs are becoming very popular because they help incresing the user experience when visiting a website. When visiting a traditional website, it can take several seconds. A PWA's loading time, however, is significantly faster thanks to the use of Service Workers. There are 3 types of apps you can have on your device: -Native -Hybrid -PWA Native: in my opinion unless you are using high graphics, and performing heavy user interaction with the a device (like playing games), I would go with a Native app. Native Apps are expensive to build since they require double effort and time - two separate apps need to be built for Android and iOS. Hybrid: a good way to go, since you have one stack that creates separate builds for Android and iOS platforms from the same sources. I would use hybrid apps if you don't require high speed and graphics on your app. With hybrid apps, you do have access to the device hardware via plugins that are built with native code. What about PWA? PWA: They are cheaper than the previous types of apps when it comes to developing, quick to develop, and they work offline! The same way that you develop a regular responsive web app, you can develop a PWA with the difference of adding a service worker to enable offline support, and things like installing the app on your home screen. What is a Service Worker? A service worker is a script that is running separetly from our website - in the background. Service workers are awesome, they can help us reach different things like caching pages, caching API calls, push notifications, background sync, and more. - A service worker can cache network requests. - A service worker can handle how network requests are done in your website. - A service worker can make the use of the Background Sync API which allows you to defer actions until the user has stable connectivity. - A service worker can't access/interact the DOM directly. - A service worker can cache your things from your website, like static assests. - A service worker can receive push notifications when the app is not active. - A service worker stays inactive when it's not in use. When it gets the "signal" to be used, it reactivates again. - A service worker can be used to make your app work offline. Service Worker's Lifecycle -Register the service worker: The first step into the service worker's lifecycle is to register the service worker. You can do so using the following code: ` Jeff Posnick from Google taught me a little trick in one of his articles about service workers. This trick is a simple way to improve the registration of the service worker. ` This code will register the service worker once the whole page has loaded, but keep in mind that you might delay the registration of the service worker this way. -Installing the service worker: This process is only called once after the service worker has been loaded. If you modify the existing service worker, the browser will update, and install the service worker again. There is an install event that gets emitted while the service worker is being installed. You can handle this event, and perform some async actions if needed (e.g., caching static assests). For this purpose, you can use *event.waitUntil()*. This method will keep the service worker in the install phase until the promise passed to *event.waitUntil()* is settled. Depending on whether that promise is resolved or rejected, the install phase will either finish successfully, or won't. In order to install the service worker, we need to do the following: 1) Open a cache. 2) Cache our files. 3) Confirm whether all the required assets are cached or not. ` The following are instruction on how to check if your service wokers have been successfully installed and registered directly in the browser. In Chrome (duhhh) 1) Open dev tools 2) In the toolbar click on *Application* 3) On your left side, you will see a sidebar. Click on service worker. 4) You should see something like the following: -Activating the service worker: The service worker can get into the activating state in different scenarios. Here are some of those scenarios: - we don't have the existing service worker in our app - we run the *self.skipWaiting()* method in the service worker - the user has navigated away from the page, releasing the previous active worker - a set period of time has passed, releasing the previous active worker -Active service worker: When a service worker is active, you can check its status inside of the register object. ` -Redundant service worker: A Service Worker can be redundant (aka something went WRONG) because of the following reasons: - the installation of the service worker failed - the service worker failed when it was getting activated - a new service worker replaces the existing service worker as the active service worker That's all folks! Sources: -https://developers.google.com/web/fundamentals/primers/service-workers -https://bitsofco.de/the-service-worker-lifecycle/ -https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle...

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co