Year of PWA: A Summary

On New Year’s Eve 2017, Maxim Salnikov proclaimed 2018 to be the year of Progressive Web Apps. The #YearOfPWA is almost over now and we’ve come a long way. Here’s a short recap of all the fantastic things that happened.

January: Apple Joins The PWA Movement

In January, Apple announced that it would release support for service workers and the Web App Manifest with Safari 11.1 in iOS 11.3 and macOS 10.13.4. With Apple on board, the application model of Progressive Web Apps finally became a viable alternative to native app development.

February: Microsoft Welcomes PWAs to The Microsoft Store

In 2017, Microsoft announced to implement service workers, one of the basic technologies of Progressive Web Apps, in Edge. In February 2018, Microsoft welcomes PWAs on Windows and makes them first-class citizens: There’s absolutely no difference between a “native” UWP app and a PWA. Ever since Windows 8, HTML5/JS-based Windows Store apps have been on par with their native counterparts written in C++ or C#. When installed from the Microsoft Store, PWAs can access any UWP API (the Twitter app uses this approach to pin tiles to Start) and they are no longer subject to space quotas.

The official Twitter client on Windows is a PWA

March: Payment Request API Lands in Safari

Together with service workers and the Web App Manifest, the Payment Request API lands in Safari 11.1 and iOS 11.3, released in March. This API allows developers to request payments from the user. Platform vendors can decide which payment methods they want to implement. Whereas Microsoft and Google both implement the Basic Card payment method for requesting basic credit card information, Apple exclusively implements its own, proprietary payment method Apple Pay. Unfortunately, the Push API is not supported by Safari yet, and it’s also not a part of the WebKit feature focus for 2018/19.

Payment Request API in Apple Safari on iOS

April: PWAs on Chrome OS Canary

In April, Chrome OS Canary allows installing PWAs. On Google’s desktop OS, PWAs run offline, in a separate window and get an own icon added to the shelf from Google Chrome 68 onwards. This marks the beginning of desktop PWA support in Google Chrome that was even further extended by the end of 2018.

May: Angular CLI & PWAs in a Breeze

In May, Google releases Angular CLI 6. This new version of Angular’s command-line tool introduces an ng add command which makes installing libraries a walk in the park. By running ng add @angular/pwa, developers can easily enable PWA support for their Angular applications.

June: Google Search & Service Worker

In June, Google starts rolling out service workers for Google Search. The service worker is used to speed up repeated searches on Chrome for Android in order to show the search results twice as fast.

July: Fresher Service Workers and Mini-Infobars

With Google Chrome 68 released in July, service worker scripts will stop obeying the HTTP cache by default. This prevents the service worker script from being cached (willingly or unwillingly), thereby delaying website updates. In addition, the app install banner on Chrome for Android was temporarily replaced by a mini-infobar and is expected to be ultimately superseded by an app installation button in the address bar.

The old app install banner (left) vs. the temporary mini infobar (right)

August: Vue CLI & PWAs in a Breeze

With Vue CLI 3.0 released in August, developers can add PWA support for their Vue-based projects by running vue add @vue/pwa.

September: Maskable PWA icons

In September, the Web App Manifest specification was extended by a new icon purpose called maskable. This purpose allows user agents to crop app icons to the needs of the platform, e.g. squares for Windows, rounded corners for iOS or circles for Android.

The maskable icon purpose makes your icons ready for cross-platform usage

October: Desktop PWAs on Windows & Linux

From Google Chrome 70 onwards (released in October), Progressive Web Apps can also be installed on the desktop operating systems Windows and Linux. The add to home screen (A2HS) support for macOS remains in the works and is expected to arrive soon.

Spotify PWA on Microsoft Windows 10

November: Chrome Capabilities

Google’s Project Fugu, called Capabilities in the developer documentation, is another initiative by the Chrome team to further improve the feature set of Progressive Web Apps. The first APIs to arrive are Web Share Target API shipped in Chrome 71, the Badging API (notification badges for the PWA’s app icon) and Writable Files API (restricted access to the native file system). There are lots of interesting APIs on the backlog, including contact pickers, geofencing, system tray/menu and touchbar access, Web NFC, run on startup and many more.

The Badging API will allow PWAs to control their notification badge

December: Edge Goes Chromium

In December, Microsoft announced that its browser Microsoft Edge will be based on Chromium (Blink and V8) in the future. This step makes testing more comfortable for web developers, as only three different rendering engines (Gecko, Blink, WebKit) remain. The new Microsoft Edge will allow users to install PWAs to their home screen, a feature that was missing before. The first beta version is expected to arrive in early 2019.

On a personal note, I am very proud to announce that my (German) book on Progressive Web Apps was published today. It is the tangible result of my last two years’ dedicated PWA research plus my contributions to 26 national and international conferences. My Thinktecture colleague Steffen Jahr and I held workshops at ng-europe, AngularConnect and many more conferences which were always well attended—the huge developer interest in PWA remains unbroken. I’d like to thank all participants and partners for their questions and feedback, Kenneth R. Christiansen for his help on my first W3C spec contributions, and all of you for this amazing year of PWA.

Alexa, Tell Azure Logic Apps to Post a Message to Slack

Alexa is Amazon’s voice-controlled personal assistant. It’s super convenient and so you might want to create your own skills as well. You’ll be surprised how easy this is can be with the help of Microsoft Azure Logic Apps.

Here’s our sample project: Let’s say you share a family Slack with your spouse and children. Whenever food is ready or the rabbits need to be fed, you want to send a Slack message to your children. This should be as easy as saying:

Alexa, tell my children: food is ready.
Alexa, tell my children to feed the bunnies.

We’ll do all of this with zero lines of code, in less than 15 minutes. Ready, set, go!

Continue reading Alexa, Tell Azure Logic Apps to Post a Message to Slack

Push Your ASP.NET Core 2.0 App to Azure Container Registry via Bitbucket Pipelines

Bitbucket is a quite popular cloud-hosted source code repository. It has a free plan which includes unlimited private Git or Mercurial repositories for up to five team members and even 50 build minutes per month. Bitbucket Pipelines is its integrated Continuous Integration tool, comparable to Travis or AppVeyor: A repository can be configured to run a certain script after each commit. For example, to check if the build passes—or to build a Docker container of your ASP.NET Core 2.0 app which is automatically pushed to Azure Container Registry (ACR), from where you can deploy your container to Azure App Services or robust Kubernetes clusters. In this blog post, I will explain how to set up Bitbucket Pipelines, build your ASP.NET Core 2.0 app (checked in to a BitBucket Git repository), package it as a Docker container and push it to your Azure Container Registry.

Continue reading Push Your ASP.NET Core 2.0 App to Azure Container Registry via Bitbucket Pipelines

Angular & TypeScript: How to Import RxJS Correctly?

Important update: RxJS 5.5 brought us Pipeable Operators that eliminate some of the problems noted below. If you can update to TypeScript 2.4, RxJS 5.5, Angular 5 and Angular CLI 1.5, you should definitely go with Pipeable Operators.

Angular has some third-party dependencies, one of which is RxJS, a library which makes reactive programming very easy to use. The library is obtained as an npm package. In order to use functionality from the RxJS library, it has to be imported first. So before you can use an operator such as map in the following snippet, it has to be imported:

  .map(params =>
  .subscribe(id => console.log(id));

Whereas IDEs such as WebStorm (prior to 2017.2) or Visual Studio Code do a good job for auto-importing symbols, they don’t suggest anything at all for RxJS symbols. Both IDEs simply print the following error message from TypeScript:

Property ‘map’ does not exist on type ‘Observable’.

Continue reading Angular & TypeScript: How to Import RxJS Correctly?

Angular & TypeScript: Writing Safer Code with strictNullChecks

On May 4, Angular 4.1.1 was released. This release fulfils a promise already made for Angular 4.1: Adding support for TypeScript’s strictNullChecks compiler option added in TypeScript 2.0.

Strict Null Checking = Safer Code

This transpiler flag enables us to write safer code. TypeScript with strict null checking enabled feels even more comfortable for developers with a static-typed language background. Without strict null checking, assigning null or undefined for instance to a variable of type number is perfectly possible:

Continue reading Angular & TypeScript: Writing Safer Code with strictNullChecks

Angular 2 & Protractor Timeout: Here’s How to Fix It

Testability is an important discipline in application development. Angular was always built with testability in mind. Protractor is Angular’s end-to-end testing framework. It was originally created for AngularJS, the first edition of the popular SPA framework, but works perfectly with Angular 2 by simply setting useAllAngular2AppRoots to true in Protractor’s config.js. In addition, you can optionally specify an element name for the rootElement property to exclusively test against this element.

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['spec.js'],
    useAllAngular2AppRoots: true,
    // rootElement: 'root-element'

However, if you are using Angular 2 and Protractor in combination, you might stumble upon one of the following error messages:

Failed: Timed out waiting for Protractor to synchronize with the page after 11 seconds. Please see

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Here’s how to fix those errors:

Continue reading Angular 2 & Protractor Timeout: Here’s How to Fix It

Testing Cordova Apps on Your BlackBerry 10 Phone

Apache Cordova, better known as PhoneGap, Adobe’s commercialized edition of Cordova, allows developers to create apps for a variety of platforms using a single HTML5, CSS and JavaScript code base. This approach of cross-platform development works for all established mobile platforms and doesn’t stop at exotic ones, such as BlackBerry 10.

Despite its infinitesimal market share, there are valid reasons to target the BlackBerry 10 platform. Adding BlackBerry 10 as a target platform to a Cordova-based project is as easy as running the cordova platform add blackberry10 command on your terminal. However, if you try to deploy your app to the device and run cordova run blackberry10, you might stumble upon the following error message:

blackberry-nativepackager cannot be found on the path. Aborting.

It seems as if we are missing the native platform SDK here. In this article, I want to show you which steps are required in order to successfully run and debug your Cordova-based app on your BlackBerry 10 phone. Please note that I’m using OS X, so the exact steps may and will differ on other platforms.

Note: macOS 10.12 Sierra does not support the BlackBerry Link drivers required to connect to your device.

Continue reading Testing Cordova Apps on Your BlackBerry 10 Phone

Configure Sinopia npm Repository Server to Cache Scoped Packages

If you are working with Node.js Package Manager (npm), you will usually retrieve npm packages from the official registry of npm ( and publish own packages there. But in some cases, you might want to keep packages private, such as internal components. For this purpose, you could either go with npm which offers paid plans and on-premises installations of the package registry or you could alternatively decide to run a custom repository server. Sinopia is such a private npm repository server, which in addition acts as a proxy for the official npm package registry and caches downloaded packages. This saves bandwidth and continues to work if the internet connection or the original package registry is down.

npm has a concept of scoped packages, where similar or related packages are grouped together. Angular 2 utilizes this concept in its packages named like @angular/core, with angular being the scope and core being the package name. But if you try to install a scoped package via Sinopia, the installation fails. In the Sinopia logs, you will see an error message similar to:

http < -- 404, user: undefined, req: 'GET /@angular%2fcompiler', error: no such package available

Here’s how to fix this.

Continue reading Configure Sinopia npm Repository Server to Cache Scoped Packages

Connecting to the WWW With Windows for Workgroups 3.11

Microsoft Windows for Workgroups (WfW) 3.11, released back in 1993, was the first operating system I ever used. As the name suggests, WfW was designed for networking in workgroups of a few people and workstations. This included centralized authentication, file and printer sharing based on Microsoft NetBEUI or NetBIOS (transported for example over Novell’s IPX/SPX protocols). This however was restricted to a local network.

In 1993, the Internet and its protocols were invented for a long time and the World Wide Web (WWW) based on Internet protocols started to emerge. But WfW didn’t ship with a TCP/IP stack and thus was incapable of connecting to the Internet. Luckily, this stack is available as a separate download which will allow us to connect to the Internet using WfW 3.11 even today. Nostalgia alert!

Continue reading Connecting to the WWW With Windows for Workgroups 3.11

Angular 2: A Simple Click Outside Directive

Detecting clicks on a component is easy in Angular 2: Just use the (click) event binding, pass a function from the component’s instance and you are done. However, if you need to detect clicks outside of your component, things are getting tricky. You will usually need this for custom implementations of drop-down lists, context menus, pop-ups or widgets.

As this is a functionality which you might use more often, you should wrap it in a reusable directive. Angular 2 offers a syntactically nice way to implement such a directive. So let’s go ahead and implement a simple click-outside directive in Angular 2!

tl;dr: Implementing this directive is super easy. If you feel lazy, just run npm i angular2-click-outside.

Continue reading Angular 2: A Simple Click Outside Directive