PWA Starter: Manifest


The first, and easier, aspect of a PWA is the manifest. This is a JSON file that holds information about the content and gives supporting browsers hints and instructions for installing the content in the user’s homescreen.

<link rel="manifest" href="/manifest.json" />

The manifest itself is a JSON file that contanins information about the application. The sample manifest below contains the following information:

  • name: Full name of the application
  • short name: Short name of the application
  • description
  • icons: An array of available icons to use for different aspects of the application
  • (default) orientation
  • start_url: The entry point for the application
  • display: how is the application UI presented to the user
  • background_color while the application is loading
  • text direction: rtl, ltr
  • lang: default language
  "name": "BookReader",
  "short_name": "BookReader",
  "description": "An ebook reader application",
  "icons": [{
    "src": "images/touch/homescreen48.png",
    "sizes": "48x48",
    "type": "image/png"
  }, {
    "src": "images/touch/homescreen72.png",
    "sizes": "72x72",
    "type": "image/png"
  }, {
    "src": "images/touch/homescreen144.png",
    "sizes": "144x144",
    "type": "image/png"

  "orientation": "portrait",
  "start_url": "index.html?utm_source=homescreen",
  "display": "standalone",
  "background_color": "#fff",
  "dir": "ltr",
  "lang": "en-us",

Orientation may be one of the following values:

  • any
  • natural
  • landscape
  • portrait

There are additional values for orientation that I’m researching. I think they move the app to primary or secondary display but, as far as I understand them, only landscape and portrait are currently supported. The additional values are:

  • landscape-primary
  • landscape-secondary
  • portrait-primary
  • portrait-secondary

The display mode attribute controls how much of the browser’s chrome and UI is show for your application. Each of the 4 modes in the table below falls back to the next one on the table, except for browser, which is the default.

Display Mode Description Fallback Display Mode
fullscreen All of the available display area is used for content and none of the browser chrome is visible. standalone
standalone The application will look and feel like a standalone application. In this mode, the user agent will exclude UI elements for controlling navigation, but can include other UI elements such as a status bar. minimal-ui
minimal-ui The application will look and feel like a standalone application, but will have a minimal set of UI elements for controlling navigation. The included elements vary by browser. browser
browser This is the default mode. The application opens in a conventional browser tab or new window, depending on the browser and platform. (None)


Splash Screen

Chrome 47 and later, display a splash screen for a web application launched from a home screen. This splashscreen is auto-generated using properties in the web app manifest, specifically: name, background_color, and the icon in the icons array that is closest to 128dpi for the device.

Even if it’s not a PWA, the ability to save a web site or app to the homescreen greatly improves the user experience for the content.

PWA Starter: Introduction

Last year I worked at Google creating ILT curriculum for Progressive Web Applications. It’s a great idea and I think the final product worked well, but it’s not complete. If you’re getting started you need hand holding but what if you’ve built PWAs before and want a reference or examples that will do what you want so you can either modify them for your project or copy it as is.

I’m making assumpttions that you’re already familiar with the technologies that make up a progressive web application so I won’t delve too much in the details about what they are. I’m also assuming that you’ve already created your build system, minimize your scripts and style sheets and other performance optimizations.

Also note that we’re only working on the technical side of a PWA. When we look at the PWA Checklist we’ll see that there are other aspects to a good and exemplary PWA than what we cover in detail below.

If you’re interested in learning more about PWAs you can check the manual my team wrote for PWA concepts.

Quick Recap

Frances Berriman and Alex Rusell coined the term progressive web application in 2015 to describe a set of technologies that enable web content (sites or applications) to behave more like native mobile apps without loosing the advantages of the web. According to the Alex these applications would work like this:

  1. The site begins life as a regular tab. It doesn’t have super-powers, but it is built using Progressive App features including TLS, Service Workers, Manifests, and Responsive Design.
  2. The second (or third or fourth) time one visits the site — roughly at the point where the browser it sure it’s something you use frequently — a prompt is shown by the browser (populated from the Manifest details)
  3. Users can decide to keep apps to the home screen or app launcher
  4. When launched from the home screen, these apps blend into their environment; they’re top-level, full-screen, and work offline. Of course, they worked offline after step 1, but now the implicit contract of “appyness” makes that clear.

Alex Russell: Progressive Web Apps: Escaping Tabs Without Losing Our Soul

For sites or apps only?

Naming progressive web applications can be a little tricky. Do the technologies only apply to web applications or can we use the technologies when building web sites?

I think that we don’t need to make the distinction. These technologies will work just as well with websites when used properly. Granted there are new technologies in the web stack that are more appropriate for applications than sites (thinking about the payment API)

As Aaron Gustafson points out:

“Web apps” in this context can be any website type—a newspapers, games, books, shopping sites—it really doesn’t matter what the content or purpose of the website is, the “web app” moniker is applicable to all of them. The term could just have easily been progressive web site and it may be helpful to think of it as such. It doesn’t need to be a single page app. You don’t need to be running everything client side. There are no particular requirements for the type of PWA you are developing.

Aaron Gustafson — Progressive Web App And The Windows Ecosystem

I like to think that the PWA is a better way to build our web content that combine the best things of the web for an experience that works almost like a native application. We get ease of use and a technology stack that we’re familiar and comfortable with (PWAs don’t dictate the stack you use, only that they have a manifest and a service worker) and a rapidly growing set of APIs available.

See Aaron’s full presentation from Microsoft Build to get a better idea of progressive enhancement in the context of a PWA:

Toolkit or Recipes?

PWAs are a toolkit that will give you the tools and methods to create your applications and sites. You’re expected to write more code but you also decide the functionality

To avoid issues like those faced with App Cache service workers make no assumptions about how you will cache your content and what else you can and will do with the tools you have available.

In this post we’ll talk about the technologies that make a basic PWA: web application manifest and service worker and discuss basic ways of configuring them.

Rememeber: HTTPS only!

For a PWA to work it must be served through HTTPS with a modern encryption schema. As we’ll see in the service worker section they are powerful and any mistakes you make when creating them can have serious security repercusions. so TLS/HTTPS only.

Pre Commit Hooks: Combating Laziness

I have to admit that I’m absolutely lazy when it comes to actually testing and linting my Javascript code. I make sure it works but not to run unit tests or make sure that the code I write follows the coding style I always say I do.

Git to the rescue!

Git creates hooks when you initialize the repository and you can customize the hooks to perform taks during the life time of the request. There are hooks that we run during the commit process but before the files are actually pushed to the server.

We’ll take advantage of the pre-commit hook to force Eslint to run before the code is committed to the repository. According to the Git Book:

The pre-commit hook is run first, before you even type in a commit message. It’s used to inspect the snapshot that’s about to be committed, to see if you’ve forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code. Exiting non-zero from this hook aborts the commit, although you can bypass it with git commit --no-verify. You can do things like check for code style (run lint or something equivalent), check for trailing whitespace (the default hook does exactly this), or check for appropriate documentation on new methods.

Note that this is a client-side hook that will not be part of the repository… We can copy this hook as part of the buiild process to make sure that all developers have the same commit hooks available to them.

The structure of the .git directory inside your project looks like this:

├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
├── objects
│   ├── info
│   └── pack
├── packed-refs
└── refs
    ├── heads
    ├── remotes
    └── tags

We activate a hook by switching to the .git/hooks directory, removing the .sample suffix and replacing the content of the file with the actions that you want to perform. In this case the pre-commit script is a bash script that will run Eslint in the modified files before commiting them to the repository

#!/usr/bin/env bash

STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js\?$')
BIN_PATH="$(git rev-parse --show-toplevel)/node_modules/.bin"

eslint() {

  # Check for eslint
  if [[ ! -x "$ESLINT" ]]; then
    printf "\t\033[41mPlease install ESLint\033[0m\n"
    exit 1

  echo "Linting modified files"

  echo $STAGED_FILES | xargs $ESLINT

  if [[ $? == 0 ]]; then
    printf "\n\033[1;32mLint Passed\033[0m\n"
    printf "\n\033[41mLint Failed:\033[0m Fix lint errors and try again!\n"
    exit 1

# Exit if no files modified
if [[ "$STAGED_FILES" = "" ]]; then
  exit 0


exit $?

As I noted earlier this is a client side hook. If you want to enforce policy at the server level, check in Git Pro .

Variable fonts for the win!

A lot of this material is taken from Get started with variable fonts and the CSS Fonts Module Level 4

Version 1.8 of the OpenType font format specification introduces an extensive new technology, affecting almost every area of the format. An OpenType variable font is one in which the equivalent of multiple individual fonts can be compactly packaged within a single font file. This is done by defining variations within the font, which constitute a single- or multi-axis design space within which many font instances can be interpolated. A variable font is a single font file that behaves like multiple fonts.

There are numerous benefits to this technology. A variable font is a single binary with greatly-reduced comparable file size and, hence, smaller disc footprint and webfont bandwidth. This means more efficient packaging of embedded fonts, and faster delivery and loading of webfonts. The potential for dynamic selection of custom instances within the variations design space — or design-variations space, to use its technical name — opens exciting prospects for fine tuning the typographic palette, and for new kinds of responsive typography that can adapt to best present dynamic content to a reader’s device, screen orientation, or even reading distance.

The technology behind variable fonts is officially called OpenType Font Variations. It has been jointly developed by Microsoft, Google, Apple, and Adobe, in an unprecedented collaborative effort also involving technical experts from font foundries and font tool developers. In addition to specifying the font format additions and revisions, the working group has also committed to the goal of interoperable implementation, defining expected behaviors and test suites for software displaying variable fonts. This should be welcome news to font developers and users, who have often struggled with incompatible implementations of earlier aspects of OpenType that were left to the interpretation of individual software companies.

Introducting Opentype Variable Fonts

The idea behind font variations is that you can have one font behave as if it was different fonts. For example, you can change the weight of the font-face at runtime and use the same font file to represent multiple values for the axis we’re changing without using a separate font file for each.

For browsers that support the technology and fonts that are built using the Opentype variable font specification, this will result in smaller font downloads because now we can bundle the most common weights and styles for fonts (regular, bold, italic and bold italic) together and use them as needed, just like if we’ve added each one individually.

The OpenType specification, pre-defines five common axes of variation as four-character tags:

  • weight: wght,
  • width: wdth,
  • italic: ital,
  • slant: slnt
  • and optical size opsz

These font variations can be enabled by the font-weight, font-stretch, and font-style properties.

CSS Fonts Level 4 adds new values for the properties to work with font variations:

font-weight takes any integer from 1–999 (not limited to multiples of 100 as in CSS3).

font-stretch takes a percentage number in a range where 100% is normal, 50% is ultra-condensed and 200% is ultra-expanded.

font-style takes an oblique angle value from oblique -90deg to oblique 90deg.

font-optical-sizing is a new property taking a value of auto or none which turns on optical sizing if it’s available as an axis in the variable font.

For more information see Font Resources in the CSS Fonts Level 4 specification.

So we have the new CSS 4 properties, we have the fonts, we just have to use them. From what I understand we need to make some changes to our @font-face declarations to enable the properties and still provide fallback fonts for browsers that don’t support them.

@font-face {
  font-family: 'Nicefont';
    src: url('nicefont_var.woff2') format('woff-variations');
    src: url('nicefont_regular.woff2') format('woff2');
    font-weight: normal;
    font-style: normal;

@font-face {
  font-family: 'Nicefont';
    src: url('nicefont_var.woff2') format('woff-variations');
    src: url('nicefont_black.woff2') format('woff2');
    font-weight: 800;
    font-style: normal;

Notice how both fonts with variation don’t require declarations for font-weight and font-style but the fallback fonts (the ones without -variations as part of the format name) do require font attributes as usual.

Using a syntax similar to font-feature-settings, custom axes as well as the predefined ones, are available through the low-level font-variation-settings property. For example, this would render text with a variation that is very wide, lightweight and optically sized for 48pt:

h2 {
  font-variation-settings: "wdth" 600, "wght" 200, "opsz" 48;

As with all powerful features, use it sparingly, if at all. The spec gives you other ways to control these attributes that doesn’t drop you down to bare Opentype attributes.

If you have a supported browser, Chrome Canary (version 62 or later) or Safari 11 (or Technical preview), you can use Axis-Praxis as a playground for variable fonts, the ones they make available and your own fonts uploaded to the site.

What do we need to do to test apps in browsers

I came across this question in Quora and prepared a detailed answer but the more I think about it the more I think it deserves a more elaborate answer because it starts from a false premise, that you must test in all versions of all the browsers available to them.

What is the fastest way to test a website on all browsers and browser version?


Now with context out of the way onto the answer

There are a few things to do before even considering what the fastest way to test is.

The first one is to acknowledge that it’s impossible to test across all browsers, versions and in all devices, your target audiences are likely to be using

The next aspect of this question is to identify your who’s your target audience? Are they browsing on desktop or mobile? what devices are they using to test(emerging markets tend to go for cheap and underpowered devices and this will affect performance during testing and in the real world)? Do you have access to the devices your target audience is likely to be using?

After you’ve answered these questions you’ll realize that, while it’s nice to do so, you can’t to test in all browsers, only the most likely ones for your market and audience.

Tools like StatCounter can help you research your target browsers to test with based on country, OS, browsers and other parameters.

Next is to consider the differences between mobile and desktop systems. An earlier answer indicated that all modern browsers worked the same so you could get away with testing in Chrome and Firefox. This is simply not true. The differences in performance between desktop and mobile processor performance can have a huge impact on how your application responds.

There are also Proxy Browsers like Opera Mini, Puffin and UC Browser that do server side rendering with only partial support for CSS and JS (Opera Mini servers will run your JS payload for 5 seconds and then stop). How will your site look on those browsers? Does your app work at all?

You might say that it doesn’t matter but it does… you never know where your users are coming from and if you’re targeting emerging markets proxy browsers are widely used to save money

The other part of this is that you’ll want a way to automate the tests so you don’t have to manually run tests on all your platforms.

Tools like Browserstack or Saucelabs can help you with the actual testing but to organize large scale test for all versions of all browsers is not only expensive but also unnecessary if you do your user analysis up front and refine it as your site gets traffic

It’s also important to point out that unless you build your own device lab with older hardware that supports the older browser you’ll never get all versions of all browsers (As far as I know most testing platforms will only go as far back as IE6 but not further than that… and even IE 6, 7, 8 and 9 are unsupported by Microsoft).