Tags: ba

108

sparkline

Indie web events in Brighton

Homebrew Website Club is a regular gathering of people getting together to tinker on their own websites. It’s a play on the original Homebrew Computer Club from the ’70s. It shares a similar spirit of sharing and collaboration.

Homebrew Website Clubs happen at various locations: London, San Francisco, Portland, Nuremberg, and more. Usually there on every second Wednesday.

I started running Homebrew Website Club Brighton a while back. I tried the “every second Wednesday” thing, but it was tricky to make that work. People found it hard to keep track of which Wednesdays were Homebrew days and which weren’t. And if you missed one, then it would potentially be weeks between attending.

So I’ve made it a weekly gathering. On Thursdays. That’s mostly because Thursdays work for me: that’s one of the evenings when Jessica has her ballet class, so it’s the perfect time for me to spend a while in the company of fellow website owners.

If you’re in Brighton and you have your own website (or you want to have your own website), you should come along. It’s every Thursday from 6pm to 7:30pm ‘round at the Clearleft studio on 68 Middle Street. Add it to your calendar.

There might be a Thursday when I’m not around, but it’s highly likely that Homebrew Website Club Brighton will happen anyway because either Trys, Benjamin or Cassie will be here.

(I’m at Homebrew Website Club Brighton right now, writing this. Remy is here too, working on some very cool webmention stuff.)

There’s something else you should add to your calendar. We’re going to have an Indie Web Camp in Brighton on October 19th and 20th. I realise that’s quite a way off, but I’m giving you plenty of advance warning so you can block out that weekend (and plan travel if you’re coming from outside Brighton).

If you’ve never been to an Indie Web Camp before, you should definitely come! It’s indescribably fun and inspiring. The first day—Saturday—is a BarCamp-style day of discussions to really get the ideas flowing. Then the second day—Sunday—is all about designing, building, and making. The whole thing wraps up with demos.

It’s been a while since we’ve had an Indie Web Camp in Brighton. You can catch up on the Brighton Indie Web Camps we had in 2014, 2015, and 2016. Since then I’ve been to Indie Web Camps in Berlin, Nuremberg, and Düsseldorf, but it’s going to be really nice to bring it back home.

Indie Web Camp UK attendees Indie Web Camp Brighton group photo IndieWebCampBrighton2016

The event will be free to attend, but I’ll set up an official ticket page on Ti.to to keep track of who’s coming. I’ll let you know when that’s up and ready. In the meantime, you can register your interest in attending on the 2019 Indie Webcamp Brighton page on the Indie Web wiki.

Inlining SVG background images in CSS with custom properties

Here’s a tiny lesson that I picked up from Trys that I’d like to share with you…

I was working on some upcoming changes to the Clearleft site recently. One particular component needed some SVG background images. I decided I’d inline the SVGs in the CSS to avoid extra network requests. It’s pretty straightforward:

.myComponent {
    background-image: url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

You can basically paste your SVG in there, although you need to a little bit of URL encoding: I found that converting # to %23 to was enough for my needs.

But here’s the thing. My component had some variations. One of the variations had multiple background images. There was a second background image in addition to the first. There’s no way in CSS to add an additional background image without writing a whole background-image declaration:

.myComponent--variant {
    background-image: url('data:image/svg+xml;utf8,<svg> ... </svg>'), url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

So now I’ve got the same SVG source inlined in two places. That negates any performance benefits I was getting from inlining in the first place.

That’s where Trys comes in. He shared a nifty technique he uses in this exact situation: put the SVG source into a custom property!

:root {
    --firstSVG: url('data:image/svg+xml;utf8,<svg> ... </svg>');
    --secondSVG: url('data:image/svg+xml;utf8,<svg> ... </svg>');
}

Then you can reference those in your background-image declarations:

.myComponent {
    background-image: var(--firstSVG);
}
.myComponent--variant {
    background-image: var(--firstSVG), var(--secondSVG);
}

Brilliant! Not only does this remove any duplication of the SVG source, it also makes your CSS nice and readable: no more big blobs of SVG source code in the middle of your style sheet.

You might be wondering what will happen in older browsers that don’t support CSS custom properties (that would be Internet Explorer 11). Those browsers won’t get any background image. Which is fine. It’s a background image. Therefore it’s decoration. If it were an important image, it wouldn’t be in the background.

Progressive enhancement, innit?

Drag’n’drop revisited

I got a message from a screen-reader user of The Session recently, letting me know of a problem they were having. I love getting any kind of feedback around accessibility, so this was like gold dust to me.

They pointed out that the drag’n’drop interface for rearranging the order of tunes in a set was inaccessible.

Drag and drop

Of course! I slapped my forehead. How could I have missed this?

It had been a while since I had implemented that functionality, so before even looking at the existing code, I started to think about how I could improve the situation. Maybe I could capture keystroke events from the arrow keys and announce changes via ARIA values? That sounded a bit heavy-handed though: mess with people’s native keyboard functionality at your peril.

Then I looked at the code. That was when I realised that the fix was going to be much, much easier than I thought.

I documented my process of adding the drag’n’drop functionality back in 2016. Past me had his progressive enhancement hat on:

One of the interfaces needed for this feature was a form to re-order items in a list. So I thought to myself, “what’s the simplest technology to enable this functionality?” I came up with a series of select elements within a form.

Reordering

The problem was in my feature detection:

There’s a little bit of mustard-cutting going on: does the dragula object exist, and does the browser understand querySelector? If so, the select elements are hidden and the drag’n’drop is enabled.

The logic was fine, but the execution was flawed. I was being lazy and hiding the select elements with display: none. That hides them visually, but it also hides them from screen readers. I swapped out that style declaration for one that visually hides the elements, but keeps them accessible and focusable.

It was a very quick fix. I had the odd sensation of wanting to thank Past Me for making things easy for Present Me. But I don’t want to talk about time travel because if we start talking about it then we’re going to be here all day talking about it, making diagrams with straws.

I pushed the fix, told the screen-reader user who originally contacted me, and got a reply back saying that everything was working great now. Success!

Design sprint?

Our hack week at CERN to reproduce the WorldWideWeb browser was five days long. That’s also the length of a design sprint. So …was what we did a design sprint?

I’m going to say no.

On the surface, our project has all the hallmarks of a design sprint. A group of people who don’t normally work together were thrown into an instense week of problem-solving and building, culminating in a tangible testable output. But when you look closer, the journey itself was quite different. A design sprint is typical broken into five phases, each one mapped on to a day of work:

  1. Understand and Map
  2. Demos and Sketch
  3. Decide and Storyboard
  4. Prototype
  5. Test

Gathered at CERN, hunched over laptops.

There was certainly plenty of understanding, sketching, and prototyping involved in our hack week at CERN, but we knew going in what the output would be at the end of the week. That’s not the case with most design sprints: figuring out what you’re going to make is half the work. In our case, we knew what needed to be produced; we just had to figure out how. Our process looked more like this:

  1. Understand and Map
  2. Research and Sketch
  3. Build
  4. Build
  5. Build

Now you could say that it’s a kind of design sprint, but I think there’s value in reserving the term “design sprint” for the specific five-day process. As it is, there’s enough confusion between the term “sprint” in its agile sense and “design sprint”.

Timelines of the web

Recreating the original WorldWideWeb browser was an exercise in digital archeology. With a working NeXT machine in the room, Kimberly was able to examine the source code for the first every browser and discover a treasure trove within. Like this gem in HTUtils.h:

#define TCP_PORT 80 /* Allocated to http by Jon Postel/ISI 24-Jan-92 */

Sure enough, by June of 1992 port 80 was documented as being officially assigned to the World Wide Web (Gopher got port 70). Jean-François Groff—who worked on the World Wide Web project with Tim Berners-Lee—told us that this was a moment they were very pleased about. It felt like this project of theirs was going places.

Jean-François also told us that the WorldWideWeb browser/editor was kind of like an advanced prototype. The idea was to get something up and running as quickly as possible. Well, the NeXT operating system had a very robust Text Object, so the path of least resistance for Tim Berners-Lee was to take the existing word-processing software and build a hypertext component on top of it. Likewise, instead of creating a brand new format, he used the existing SGML format and added one new piece: linking with A tags.

So the WorldWideWeb application was kind of like a word processor and document viewer mashed up with hypertext. Ted Nelson complains to this day that the original sin of the web was that it borrowed this page-based metaphor. But Nelson’s Project Xanadu, originally proposed in 1974 wouldn’t become a working reality until 2014—a gap of forty years. Whereas Tim Berners-Lee proposed his system in March 1989 and had working code within a year. There’s something to be said for being pragmatic and working with what you’ve got.

The web was also a mashup of ideas. Hypertext existed long before the web—Ted Nelson coined the term in 1963. There were conferences and academic discussions devoted to hypertext and hypermedia. But almost all the existing hypertext systems—including Tim Berners-Lee’s own ENQUIRE system from the early 80s—were confined to a local machine. Meanwhile networked computers were changing everything. First there was the ARPANET, then the internet. Tim Berners-Lee’s ambitious plan was to mash up hypertext with networks.

Going into our recreation of WorldWideWeb at CERN, I knew I wanted to convey this historical context somehow.

The World Wide Web officially celebrates its 30th birthday in March of this year. It’s kind of an arbitrary date: it’s the anniversary of the publication of Information Management: A Proposal. Perhaps a more accurate date would be the day the first website—and first web server—went online. But still. Let’s roll with this date of March 12, 1989. I thought it would be interesting not only to look at what’s happened between 1989 and 2019, but also to look at what happened between 1959 and 1989.

So now I’ve got two time cones that converge in the middle: 1959 – 1989 and 1989 – 2019. For the first time period, I made categories of influences: formats, hypertext, networks, and computing. For the second time period, I catalogued notable results: browsers, servers, and the evolution of HTML.

I did a little bit of sketching and quickly realised that these converging timelines could be represented somewhat like particle collisions. Once I had that idea in my head, I knew how I would be spending my time during the hack week.

Rather than jumping straight into the collider visualisation, I took some time to make a solid foundation to build on. I wanted to be sure that the timeline itself would be understable even if it were, say, viewed in the first ever web browser.

Progressive enhancement. Marking up (and styling) an interactive timeline that looks good in a modern browser and still works in the first ever web browser.

I marked up each timeline as an ordered list of h-events:

<li class="h-event y1968">
  <a href="https://en.wikipedia.org/wiki/NLS_%28computer_system%29" class="u-url">
    <time class="dt-start" datetime="1968-12-09">1968</time>
    <abbr class="p-name" title="oN-Line System">NLS</abbr>
  </a>
</li>

With the markup in place, I could concentrate on making it look halfway decent. For small screens, the layout is very basic—just a series of lists. When the screen gets wide enough, I lay those lists out horzontally one on top of the other. In this view, you can more easily see when events coincide. For example, ENQUIRE, Usenet, and Smalltalk all happen in 1980. But the real beauty comes when the screen is wide enough to display everthing at once. You can see how an explosion of activity in the early 90s. In 1994 alone, we get the release of Netscape Navigator, the creation of HTTPS, and the launch of Amazon.com.

The whole thing is powered by CSS transforms and positioning. Each year on a timeline has its own class that gets moved to the correct chronological point using calc(). I wanted to use translateX() but I couldn’t get the maths to work for that, so I had use plain ol’ left and right:

.y1968 {
  left: calc((1968 - 1959) * (100%/30) - 5em);
}

For events before 1989, it’s the distance of the event from 1959. For events after 1989, it’s the distance of the event from 2019:

.y2014 {
  right: calc((2019 - 2014) * (100%/30) - 5em);
}

(Each h-event has a width of 5em so that’s where the extra bit at the end comes from.)

I had to do some tweaking for legibility: bunches of events happening around the same time period needed to be separated out so that they didn’t overlap too much.

As a finishing touch, I added a few little transitions when the page loaded so that the timeline fans out from its centre point.

Et voilà!

Progressive enhancement. Marking up (and styling) an interactive timeline that looks good in a modern browser and still works in the first ever web browser.

I fiddled with the content a bit after peppering Robert Cailliau with questions over lunch. And I got some very valuable feedback from Jean-François. Some examples he provided:

1971: Unix man pages, one of the first instances of writing documents with a markup language that is interpreted live by a parser before being presented to the user.

1980: Usenet News, because it was THE everyday discussion medium by the time we created the web technology, and the Web first embraced news as a built-in information resource, then various platforms built on the web rendered it obsolete.

1982: Literary Machines, Ted Nelson’s book which was on our desk at all times

I really, really enjoyed building this “collider” timeline. It was a chance for me to smash together my excitement for web history with my enjoyment of using the raw materials of the web; HTML and CSS in this case.

The timeline pales in comparison to the achievement of the rest of the team in recreating the WorldWideWeb application but I was just glad to be able to contribute a little something to the project.

Hello WorldWideWeb.

Ch-ch-ch-changes

It’s browser updatin’ time! Firefox 65 just dropped. So did Chrome 72. Safari 12.1 is shipping with iOS 12.2.

It’s interesting to compare the release notes for each browser and see the different priorities reflected in them (this is another reason why browser diversity is A Good Thing).

A lot of the Firefox changes are updates to dev tools; they just keep getting better and better. In fact, I’m not sure “dev tools” is the right word for them. With their focus on layout, typography, and accessibility, “design tools” might be a better term.

Oh, and Firefox is shipping support for some CSS properties that really help with print style sheets, so I’m disproportionately pleased about that.

In Safari’s changes, I’m pleased to see that the datalist element is finally getting implemented. I’ve been a fan of that element for many years now. (Am I a dork for having favourite HTML elements? Or am I a dork for even having to ask that question?)

And, of course, it wouldn’t be a Safari release without a new made up meta tag. From the people who brought you such hits as viewport and apple-mobile-web-app-capable, comes …supported-color-schemes (Apple likes to make up meta tags almost as much as Google likes to make up rel values).

There’ll be a whole bunch of improvements in how progressive web apps will behave once they’ve been added to the home screen. We’ll finally get some state persistence if you navigate away from the window!

Updated the behavior of websites saved to the home screen on iOS to pause in the background instead of relaunching each time.

Maximiliano Firtman has a detailed list of the good, the bad, and the “not sure yet if good” for progressive web apps on iOS 12.2 beta. Thomas Steiner has also written up the progress of progressive web apps in iOS 12.2 beta. Both are published on Ev’s blog.

At first glance, the release notes for Chrome 72 are somewhat paltry. The big news doesn’t even seem to be listed there. Maximiliano Firtman again:

Chrome 72 for Android shipped the long-awaited Trusted Web Activity feature, which means we can now distribute PWAs in the Google Play Store!

Very interesting indeed! I’m not sure if I’m ready to face the Kafkaesque process of trying to add something to the Google Play Store just yet, but it’s great to know that I can. Combined with the improvements coming in iOS 12.2, these are exciting times for progressive web apps!

Push without notifications

On the first day of Indie Web Camp Berlin, I led a session on going offline with service workers. This covered all the usual use-cases: pre-caching; custom offline pages; saving pages for offline reading.

But on the second day, Sebastiaan spent a fair bit of time investigating a more complex use of service workers with the Push API.

The Push API is what makes push notifications possible on the web. There are a lot of moving parts—browser, server, service worker—and, frankly, it’s way over my head. But I’m familiar with the general gist of how it works. Here’s a typical flow:

  1. A website prompts the user for permission to send push notifications.
  2. The user grants permission.
  3. A whole lot of complicated stuff happens behinds the scenes.
  4. Next time the website publishes something relevant, it fires a push message containing the details of the new URL.
  5. The user’s service worker receives the push message (even if the site isn’t open).
  6. The service worker creates a notification linking to the URL, interrupting the user, and generally adding to the weight of information overload.

Here’s what Sebastiaan wanted to investigate: what if that last step weren’t so intrusive? Here’s the alternate flow he wanted to test:

  1. A website prompts the user for permission to send push notifications.
  2. The user grants permission.
  3. A whole lot of complicated stuff happens behinds the scenes.
  4. Next time the website publishes something relevant, it fires a push message containing the details of the new URL.
  5. The user’s service worker receives the push message (even if the site isn’t open).
  6. The service worker fetches the contents of the URL provided in the push message and caches the page. Silently.

It worked.

I think this could be a real game-changer. I don’t know about you, but I’m very, very wary of granting websites the ability to send me push notifications. In fact, I don’t think I’ve ever given a website permission to interrupt me with push notifications.

You’ve seen the annoying permission dialogues, right?

In Firefox, it looks like this:

Will you allow name-of-website to send notifications?

[Not Now] [Allow Notifications]

In Chrome, it’s:

name-of-website wants to

Show notifications

[Block] [Allow]

But in actual fact, these dialogues are asking for permission to do two things:

  1. Receive messages pushed from the server.
  2. Display notifications based on those messages.

There’s no way to ask for permission just to do the first part. That’s a shame. While I’m very unwilling to grant permission to be interrupted by intrusive notifications, I’d be more than willing to grant permission to allow a website to silently cache timely content in the background. It would be a more calm technology.

Think of the use cases:

  • I grant push permission to a magazine. When the magazine publishes a new article, it’s cached on my device.
  • I grant push permission to a podcast. Whenever a new episode is published, it’s cached on my device.
  • I grant push permission to a blog. When there’s a new blog post, it’s cached on my device.

Then when I’m on a plane, or in the subway, or in any other situation without a network connection, I could still visit these websites and get content that’s fresh to me. It’s kind of like background sync in reverse.

There’s plenty of opportunity for abuse—the cache could get filled with content. But websites can already do that, and they don’t need to be granted any permissions to do so; just by visiting a website, it can add multiple files to a cache.

So it seems that the reason for the permissions dialogue is all about displaying notifications …not so much about receiving push messages from the server.

I wish there were a way to implement this background-caching pattern without requiring the user to grant permission to a dialogue that contains the word “notification.”

I wonder if the act of adding a site to the home screen could implicitly grant permission to allow use of the Push API without notifications?

In the meantime, the proposal for periodic synchronisation (using background sync) could achieve similar results, but in a less elegant way; periodically polling for new content instead of receiving a push message when new content is published. Also, it requires permission. But at least in this case, the permission dialogue should be more specific, and wouldn’t include the word “notification” anywhere.

Service workers and videos in Safari

Alright, so I’ve already talked about some gotchas when debugging service worker issues. But what if you don’t even realise the problem has anything to do with your service worker?

This is not a hypothetical situation. I encountered this very thing myself. Gather ‘round the campfire, children…

One of the latest case studies on the Clearleft site is a nice write-up by Luke of designing a mobile app for Virgin Holidays. The case study includes a lovely video that demonstrates the log-in flow. I implemented that using a video element (with a poster image). Nice and straightforward. Super easy. All good.

But I hadn’t done my due diligence in browser testing (I guess I didn’t even think of it in this case). Hana informed me that the video wasn’t working at all in Safari. The poster image appeared just fine, but when you clicked on it, the video didn’t load.

I ducked, ducked, and went, uncovering what appeared to be the root of the problem. It seems that Safari is fussy about having servers support something called “byte-range requests”.

I had put the video in question on an Amazon S3 server. I came to the conclusion that S3 mustn’t support these kinds of headers correctly, or something.

Now I had a diagnosis. The next step was figuring out a solution. I thought I might have to move the video off of S3 and onto a server that I could configure a bit more.

Luckily, I never got ‘round to even starting that process. That’s good. Because it turns out that my diagnosis was completely wrong.

I came across a recent post by Phil Nash called Service workers: beware Safari’s range request. The title immediately grabbed my attention. Safari: yes! Video: yes! But service workers …wait a minute!

There’s a section in Phil’s post entitled “Diagnosing the problem”, in which he says:

I first thought it could have something to do with the CDN I’m using. There were some false positives regarding streaming video through a CDN that resulted in some extra research that was ultimately fruitless.

That described my situation exactly. Except Phil went further and nailed down the real cause of the problem:

Nginx was serving correct responses to Range requests. So was the CDN. The only other problem? The service worker. And this broke the video in Safari.

Doh! I hadn’t even thought about service workers!

Phil came up with a solution, and he has kindly shared his code.

I decided to go for a dumber solution:

if ( request.url.match(/\.(mp4)$/) ) {
  return;
}

That tells the service worker to just step out of the way when it comes to video requests. Now the video plays just fine in Safari. It’s a bit of a shame, because I’m kind of penalising all browsers for Safari’s bug, but the Clearleft site isn’t using much video at all, and in any case, it might be good not to fill up the cache with large video files.

But what’s more important than any particular solution is correctly identifying the problem. I’m quite sure I never would’ve been able to fix this issue if Phil hadn’t gone to the trouble of sharing his experience. I’m very, very grateful that he did.

That’s the bigger lesson here: if you solve a problem—even if you think it’s hardly worth mentioning—please, please share your solution. It could make all the difference for someone out there.

Greater expectations

I got an intriguing email recently from someone who’s a member of The Session, the community website about Irish traditional music that I run. They said:

When I recently joined, I used my tablet to join. Somewhere I was able to download The Session app onto my tablet.

But there is no native app for The Session. Although, as it’s a site that I built, it is, a of course, progressive web app.

They went on to say:

I wanted to put the app on my phone but I can’t find the app to download it. Can I have the app on more than one device? If so, where is it available?

I replied saying that yes, you can absolutely have it on more than one device:

But you don’t find The Session app in the app store. Instead you go to the website https://thesession.org and then add it to your home screen from your browser.

My guess is that this person had added The Session to the home screen of their Android tablet, probably following the “add to home screen” prompt. I recently added some code to use the window.beforeinstallprompt event so that the “add to home screen” prompt would only be shown to visitors who sign up or log in to The Session—a good indicator of engagement, I reckon, and it should reduce the chance of the prompt being dismissed out of hand.

So this person added The Session to their home screen—probably as a result of being prompted—and then used it just like any other app. At some point, they didn’t even remember how the app got installed:

Success! I did it. Thanks. My problem was I was looking for an app to download.

On the one hand, this is kind of great: here’s an example where, in the user’s mind, there’s literally no difference between the experience of using a progressive web app and using a native app. Win!

But on the other hand, the expectation is still that apps are to be found in an app store, not on the web. This expectation is something I wrote about recently (and Justin wrote a response to that post). I finished by saying:

Perhaps the inertia we think we’re battling against isn’t such a problem as long as we give people a fast, reliable, engaging experience.

When this member of The Session said “My problem was I was looking for an app to download”, I responded by saying:

Well, I take that as a compliment—the fact that once the site is added to your home screen, it feels just like a native app. :-)

And they said:

Yes, it does!

Altering expectations

Luke has written up the selection process he went through when Clearleft was designing the Virgin Holidays app. When it comes to deploying on mobile, there were three options:

  1. Native apps
  2. A progressive web app
  3. A hybrid app

The Virgin Holidays team went with that third option.

Now, it will come as no surprise that I’m a big fan of the second option: building a progressive web app (or turning an existing site into a progressive web app). I think a progressive web app is a great solution for travel apps, and the use-case that Luke describes sounds perfect:

Easy access to resort staff and holiday details that could be viewed offline to help as many customers as possible travel without stress and enjoy a fantastic holiday

Luke explains why they choice not to go with a progressive web app.

The current level of support and leap in understanding meant we’d risk alienating many of our customers.

The issue of support is one that is largely fixed at this point. When Clearleft was working on the Virgin Holidays app, service workers hadn’t landed in iOS. Hence, the risk of alienating a lot of customers. But now that Mobile Safari has offline capabilities, that’s no longer a problem.

But it’s the second reason that’s trickier:

Simply put, customers already expected to find us in the App Store and are familiar with what apps can historically offer over websites.

I think this is the biggest challenge facing progressive web apps: battling expectations.

For over a decade, people have formed ideas about what to expect from the web and what to expect from native. From a technical perspective, native and web have become closer and closer in capabilities. But people’s expectations move slower than technological changes.

First of all, there’s the whole issue of discovery: will people understand that they can “install” a website and expect it to behave exactly like a native app? This is where install prompts and ambient badging come in. I think ambient badging is the way to go, but it’s still a tricky concept to explain to people.

But there’s another way of looking at the current situation. Instead of seeing people’s expectations as a negative factor, maybe it’s an opportunity. There’s an opportunity right now for companies to be as groundbreaking and trendsetting as Wired.com when it switched to CSS for layout, or The Boston Globe when it launched its responsive site.

It makes for a great story. Just look at the Pinterest progressive web app for an example (skip to the end to get to the numbers):

Weekly active users on mobile web have increased 103 percent year-over-year overall, with a 156 percent increase in Brazil and 312 percent increase in India. On the engagement side, session length increased by 296 percent, the number of Pins seen increased by 401 percent and people were 295 percent more likely to save a Pin to a board. Those are amazing in and of themselves, but the growth front is where things really shined. Logins increased by 370 percent and new signups increased by 843 percent year-over-year. Since we shipped the new experience, mobile web has become the top platform for new signups. And for fun, in less than 6 months since fully shipping, we already have 800 thousand weekly users using our PWA like a native app (from their homescreen).

Now admittedly their previous mobile web experience was a dreadful doorslam, but still, those are some amazing statistics!

Maybe we’re underestimating the malleability of people’s expectations when it comes to the web on mobile. Perhaps the inertia we think we’re battling against isn’t such a problem as long as we give people a fast, reliable, engaging experience.

If you build that, they will come.

Twitter and Instagram progressive web apps

Since support for service workers landed in Mobile Safari on iOS, I’ve been trying a little experiment. Can I replace some of the native apps I use with progressive web apps?

The two major candidates are Twitter and Instagram. I added them to my home screen, and banished the native apps off to a separate screen. I’ve been using both progressive web apps for a few months now, and I have to say, they’re pretty darn great.

There are a few limitations compared to the native apps. On Twitter, if you follow a link from a tweet, it pops open in Safari, which is fine, but when you return to Twitter, it loads anew. This isn’t any fault of Twitter—this is the way that web apps have worked on iOS ever since they introduced their weird web-app-capable meta element. I hope this behaviour will be fixed in a future update.

Also, until we get web notifications on iOS, I need to keep the Twitter native app around if I want to be notified of a direct message (the only notification I allow).

Apart from those two little issues though, Twitter Lite is on par with the native app.

Instagram is also pretty great. It too suffers from some navigation issues. If I click through to someone’s profile, and then return to the main feed, it also loads it anew, losing my place. It would be great if this could be fixed.

For some reason, the Instagram web app doesn’t allow uploading multiple photos …which is weird, because I can upload multiple photos on my own site by adding the multiple attribute to the input type="file" in my posting interface.

Apart from that, though, it works great. And as I never wanted notifications from Instagram anyway, the lack of web notifications doesn’t bother me at all. In fact, because the progressive web app doesn’t keep nagging me about enabling notifications, it’s a more pleasant experience overall.

Something else that was really annoying with the native app was the preponderance of advertisements. It was really getting out of hand.

Well …(looks around to make sure no one is listening)… don’t tell anyone, but the Instagram progressive web app—i.e. the website—doesn’t have any ads at all!

Here’s hoping it stays that way.

New tools for art direction on the web

I’m in Boston right now, getting ready to speak at An Event Apart. This will be my second (and last) Event Apart of the year—the other time was in Seattle back in April. After that event, I wrote about how inspired I was:

It was interesting to see repeating, overlapping themes. From a purely technical perspective, three technologies that were front and centre were:

  • CSS grid,
  • variable fonts, and
  • service workers.

From listening to other attendees, the overwhelming message received was “These technologies are here—they’ve arrived.”

I was itching to combine those technologies on a project. Coincidentally, it was around that time that I started planning to publish The Gęsiówka Story. I figured I could use that as an opportunity to tinker with those front-end technologies that I was so excited about.

But I was cautious. I didn’t want to use the latest exciting technology just for the sake of it. I was very aware of the gravity of the material I was dealing with. Documenting the story of Gęsiówka was what mattered. Any front-end technologies I used had to be in support of that.

First of all, there was the typesetting. I don’t know about you, but I find choosing the right typefaces to be overwhelming. Despite all the great tips and techniques out there for choosing and pairing typefaces, I still find myself agonising over the choice—what if there’s a better choice that I’m missing?

In this case, because I wanted to use a variable font, I had a constraint that helped reduce the possibility space. I started to comb through v-fonts.com to find a suitable typeface—I was fairly sure I wanted a serious serif.

I had one other constraint. The font file had to include English, Polish, and German glyphs. That pretty much sealed the deal for Source Serif. That only has one variable axis—weight—but I decided that this could also be an interesting constraint: how much could I wrangle out of a single typeface just using various weights?

I ended up using font weights of 75, 250, 315, 325, 340, 350, 400, and 525. Most of them were for headings or one-off uses, with a font-weight of 315 for the body copy.

(And can I just say once again how impressed I am that the founding fathers of CSS were far-sighted enough to keep those font weight ranges free for future use?)

Getting the typography right posed an interesting challenge. This was a fairly long piece of writing, so it really needed to be readable without getting tiring. But at the same time, I didn’t want it to be exactly pleasant to read—that wouldn’t do the subject matter justice. I wanted the reader to feel the seriousness of the story they were reading, without being fatigued by its weight.

Colour and type went a long way to communicating that feeling. The grid sealed the deal.

The Gęsiówka Story is mostly one single column of text, so on the face of it, there isn’t much opportunity to go crazy with CSS Grid. But I realised I could use a grid to create a winding effect for the text. I had to be careful though: I didn’t want it to become uncomfortable to read. I wanted to create a slightly unsettling effect.

Every section element is turned into a seven-column grid container:

section {
    display: grid;
    grid-column-gap: 2em;
    grid-template-columns: 2em repeat(5, 1fr) 2em;
}

The first and last columns are the same width as the gutters (2em), effectively creating “outer” gutters for the grid. Each paragraph within the section takes up six of the seven columns. I use nth-of-type to alternate which six columns are used (the first six or the last six). That creates the staggered indendation:

section > p {
    grid-column: 1/7;
}
section > p:nth-of-type(even) {
    grid-column: 2/8;
}

Staggered grid.

That might seem like overkill just to indent every second paragraph by 4em, but I then used the same grid dimensions to layout figure elements with images and captions.

section > figure {
    display: grid;
    grid-column-gap: 2em;
    grid-template-columns: 2em repeat(5, 1fr) 2em;
}

Then I can lay out differently proportioned images across different ranges of the grid:

section > figure.landscape > img {
    grid-column: 1/5;
}
section > figure.landscape > figcaption {
    grid-column: 5/8;
}
section > figure.portrait > img {
    grid-column: 1/4;
}
section > figure.portrait > figcaption {
    grid-column: 4/8;
}

Because they’re positioned on the same grid as the paragraphs, everything lines up nicely (and yes, if subgrid existed, I wouldn’t have to redeclare the grid dimensions for the figures).

Finally, I wanted to make sure that the whole thing could be read offline. After all, once you’ve visited the URL once, there’s really no reason to make any more requests to the server. Static documents—and books—are the perfect candidates for an “offline first” approach: always look in the cache, and only go to the network as a last resort.

In this case I used a variation of my minimal viable service worker script, and the result is a very short set of instructions. There’s a little bit of pre-caching going on: I grab the variable font and the HTML page itself (which includes the CSS inlined).

So there you have it: variable fonts, CSS grid, and service workers: three exciting front-end technologies, all of which can be applied as progressive enhancements on top of the core content.

Once again, I find that it’s personal projects that offer the most opportunities to try out new or interesting techniques. And The Gęsiówka Story is a very personal project indeed.

Clearleft.com is a progressive web app

What’s that old saying? The cobbler’s children have no shoes that work offline. Or something.

It’s been over a year since the Clearleft site relaunched and I listed some of the next steps I had planned:

Service worker. It’s a no-brainer. Now that the Clearleft site is (finally!) running on HTTPS, having a simple service worker to cache static assets like CSS, JavaScript and some images seems like the obvious next step.

You know how it is. Those no-brainer tasks are exactly the kind of thing that end up on a to-do list without ever quite getting to-done. Meanwhile I’ve been writing and speaking about how any website can be a progressive web app. I think Alanis Morissette used to sing about this sort of situation.

Enough is enough! Clearleft.com is now a progressive web app. It has a manifest file and a service worker script.

The service worker logic is fairly straightforward, and taken almost verbatim from Going Offline. As you navigate around the site, the service worker applies different logic depending on the kind of file you’re requesting:

  • Pages are served fresh from the network, falling back to the cache when there’s a problem.
  • Everything else is served from the cache where possible, resorting to the network only if there’s no match in the cache—quite the performance boost!

In both cases, if a page or a file is retrieved from the network, it’s gets put into a cache. I’ve got one cache for pages, and another for everything else. And even if a file is retrieved from that cache, I still fire off a fetch request to grab a fresh copy for the cache. So while there’s a chance that a stale file might be served up, it will only ever be slightly stale, and the next time it’s requested, it’ll be fresh.

In the worst-case scenario, when a page can’t be retrieved from the network or the cache, you end up seeing a custom offline page. There you can see a list of any pages that are cached (meaning you can revisit them even without an internet connection).

A custom offline page showing a list of URLs.

It’s not ideal—page titles would be friendlier than URLs—but it’s a start. I’m sure I’ll revisit it soon. Honest.

Oh, and after a year of procrastinating about doing this, guess how long it took? About half a day. Admittedly, this isn’t my first progressive web app, and the more you build ‘em, the easier it gets. Still, it’s a classic example of a small investment of time leading to a big improvement in performance and user experience.

If you think your company’s website could benefit from being a progressive web app (and believe me, it definitely could), you have a couple of options:

  1. Arm yourself with a copy of Going Offline and give it a go yourself. Or
  2. Get in touch with Clearleft. We can help you. (See, I can say that with a straight face now that we’re practicing what we preach.)

Either way, don’t dilly dally …like I did.

Document

A little while back, I showed Paul what I was working on with The Gęsiówka Story. I value his opinion and I really like the Bradshaw’s Guide project that he’s been working on. We’re both in complete agreement with Russell Davies’ call for an internet of unmonetisable enthusiasms. Call them side projects if you like, but for me, these are the things that the World Wide Web excels at.

These unomentisable enthusiasms/side projects are what got me hooked on the web in the first place. Fray.com—back when it was a website for personal stories—was what really made the web click for me. I had seen brochure sites, I had seen e-commerce sites, but it was seeing something built purely for the love of it that caused that lightbulb moment for me.

I told Paul about another site I remembered from that time (we’re talking about the mid-to-late nineties here). It was called Private Art. It was the work of one family, the children of Private Art Pranger who served in World War Two and wrote letters from the front. Without any expectations, I did a quick search, and amazingly, the site is still up!

Yes, it’s got tiled background images, and the framesetted content is in a pop-up window, but it works. The site hasn’t been updated for fifteen years but it works perfectly in a web browser today. That’s kind of amazing. We really shouldn’t take the longevity of our materials for granted. Could you imagine trying to open a word processing document from the late nineties on your computer today? You’d have a bad time.

Working on The Gęsiówka Story helped to remind me of some of the things that made me fall in love with the web in the first place. What I wrote about it is equally true of Private Art:

When we talk about documents on the web, we usually use the word “document” as a noun. But working on The Gęsiówka Story, I came to think of the word “document” as a verb.

The World Wide Web is a medium that’s works for quick, short-term lightweight bits of fun and also for long-term, deeper, slower, thoughtful archives of our collective culture.

The web is a many-splendoured thing.

Frustration

I had some problems with my bouzouki recently. Now, I know my bouzouki pretty well. I can navigate the strings and frets to make music. But this was a problem with the pickup under the saddle of the bouzouki’s bridge. So it wasn’t so much a musical problem as it was an electronics problem. I know nothing about electronics.

I found it incredibly frustrating. Not only did I have no idea how to fix the problem, but I also had no idea of the scope of the problem. Would it take five minutes or five days? Who knows? Not me.

My solution to a problem like this is to pay someone else to fix it. Even then I have to go through the process of having the problem explained to me by someone who understands and cares about electronics much more than me. I nod my head and try my best to look like I’m taking it all in, even though the truth is I have no particular desire to get to grips with the inner workings of pickups—I just want to make some music.

That feeling of frustration I get from having wiring issues with a musical instrument is the same feeling I get whenever something goes awry with my web server. I know just enough about servers to be dangerous. When something goes wrong, I feel very out of my depth, and again, I have no idea how long it will take the fix the problem: minutes, hours, days, or weeks.

I had a very bad day yesterday. I wanted to make a small change to the Clearleft website—one extra line of CSS. But the build process for the website is quite convoluted (and clever), automatically pulling in components from the site’s pattern library. Something somewhere in the pipeline went wrong—I still haven’t figured out what—and for a while there, the Clearleft website was down, thanks to me. (Luckily for me, Danielle saved the day …again. I’d be lost without her.)

I was feeling pretty down after that stressful day. I felt like an idiot for not knowing or understanding the wiring beneath the site.

But, on the other hand, considering I was only trying to edit a little bit of CSS, maybe the problem didn’t lie entirely with me.

There’s a principle underlying the architecture of the World Wide Web called The Rule of Least Power. It somewhat counterintuitively states that you should:

choose the least powerful language suitable for a given purpose.

Perhaps, given the relative simplicity of the task I was trying to accomplish, the plumbing was over-engineered. That complexity wouldn’t matter if I could circumvent it, but without the build process, there’s no way to change the markup, CSS, or JavaScript for the site.

Still, most of the time, the build process isn’t a hindrance, it’s a help: concatenation, minification, linting and all that good stuff. Most of my frustration when something in the wiring goes wrong is because of how it makes me feel …just like with the pickup in my bouzouki, or the server powering my website. It’s not just that I find this stuff hard, but that I also feel like it’s stuff I’m supposed to know, rather than stuff I want to know.

On that note…

Last week, Paul wrote about getting to grips with JavaScript. On the very same day, Brad wrote about his struggle to learn React.

I think it’s really, really, really great when people share their frustrations and struggles like this. It’s very reassuring for anyone else out there who’s feeling similarly frustrated who’s worried that the problem lies with them. Also, this kind of confessional feedback is absolute gold dust for anyone looking to write explanations or documentation for JavaScript or React while battling the curse of knowledge. As Paul says:

The challenge now is to remember the pain and anguish I endured, and bare that in mind when helping others find their own path through the knotted weeds of JavaScript.

HTTPS + service worker + web app manifest = progressive web app

I gave a quick talk at the Delta V conference in London last week called Any Site can be a Progressive Web App. I had ten minutes, but frankly I only needed enough time to say the title of the talk because, well, that was also the message.

There’s a common misconception that making a Progressive Web App means creating a Single Page App with an app-shell architecture. But the truth is that literally any website can benefit from the performance boost that results from the combination of HTTPS + Service Worker + Web App Manifest.

See how I define a progressive web app as being HTTPS + service worker + web app manifest? I’ve been doing that for a while. Here’s a post from last year called Progressing the web:

Literally any website can be a progressive web app:

That last step can be tricky if you’re new to service workers, but it’s not unsurmountable. It’s certainly a lot easier than completely rearchitecting your existing website to be a JavaScript-driven single page app.

Later I wrote a post called What is a Progressive Web App? where I compared the definition to responsive web design.

Regardless of the specifics of the name, what I like about Progressive Web Apps is that they have a clear definition. It reminds me of Responsive Web Design. Whatever you think of that name, it comes with a clear list of requirements:

  1. A fluid layout,
  2. Fluid images, and
  3. Media queries.

Likewise, Progressive Web Apps consist of:

  1. HTTPS,
  2. A service worker, and
  3. A Web App Manifest.

There’s more you can do in addition to that (just as there’s plenty more you can do on a responsive site), but the core definition is nice and clear.

But here’s the thing. Outside of the confines of my own website, it’s hard to find that definition anywhere.

On Google’s developer site, their definition uses adjectives like “reliable”, “fast”, and “engaging”. Those are all great adjectives, but more useful to a salesperson than a developer.

Over on the Mozilla Developer Network, their section on progressive web apps states:

Progressive web apps use modern web APIs along with traditional progressive enhancement strategy to create cross-platform web applications. These apps work everywhere and provide several features that give them the same user experience advantages as native apps. 

Hmm …I’m not so sure about that comparison to native apps (and I’m a little disturbed that the URL structure is /Apps/Progressive). So let’s click through to the introduction:

PWAs are web apps developed using a number of specific technologies and standard patterns to allow them to take advantage of both web and native app features.

Okay. Specific technologies. That’s good to hear. But instead of then listing those specific technologies, we’re given another list of adjectives (discoverable, installable, linkable, etc.). Again, like Google’s chosen adjectives, they’re very nice and desirable, but not exactly useful to someone who wants to get started making a progressive web app. That’s why I like to cut to the chase and say:

  • You need to be running on HTTPS,
  • Then you can add a service worker,
  • And don’t forget to add a web app manifest file.

If you do that, you’ve got a progressive web app. Now, to be fair, there’a lot that I’m leaving out. Your site should be fast. Your site should be responsive (it is, after all, on the web). There’s not much point mucking about with service workers if you haven’t sorted out the basics first. But those three things—HTTPS + service worker + web app manifest—are specifically what distinguishes a progressive web app. You can—and should—have a reliable, fast, engaging website before turning it into a progressive web app.

Jason has been thinking about progressive web apps a lot lately (he should write a book or something), and he said to me:

I agree with you on the three things that comprise a PWA, but as far as I can tell, you’re the first to declare it as such.

I was quite surprised by that. I always assumed that I was repeating the three ingredients of a progressive web app, not defining them. But looking through all the docs out there, Jason might be right. It’s surprising because I assumed it was obvious why those three things comprise a progressive web app—it’s because they’re testable.

Lighthouse, PWA Builder, Sonarwhal and other tools that evaluate your site will measure its progressive web app score based on the three defining factors (HTTPS, service worker, web app manifest). Then there’s Android’s Add to Home Screen prompt. Here finally we get a concrete description of what your site needs to do to pass muster:

  • Includes a web app manifest…
  • Served over HTTPS (required for service workers)
  • Has registered a service worker with a fetch event handler

(Although, as of this month, Chrome will no longer show the prompt automatically—you also have to write some JavaScript to handle the beforeinstallprompt  event).

Anyway, if you’re looking to turn your website into a progressive web app, here’s what you need to do (assuming it’s already performant and responsive):

  1. Switch over to HTTPS. Certbot can help you here.
  2. Add a web app manifest.
  3. Add a service worker to your site so that it responds even when there’s no network connection.

That last step might sound like an intimidating prospect, but help is at hand: I wrote Going Offline for exactly this situation.

Designing Progressive Web Apps by Jason Grigsby

It’s the afternoon of the second day of An Event Apart Seattle and Jason is talking about Designing Progressive Web Apps. These are my notes…

Jason wants to talk about a situation you might find yourself in. You’re in a room and in walks the boss, who says “We need a progressive web app.” Now everyone is asking themselves “What is a progressive web app?” Or maybe “How does the CEO even know about progressive web apps?”

Well, trade publications are covering progressive web apps. Lots of stats and case studies are being published. When executives see this kind of information, they don’t want to get left out. Jason keeps track of this stuff at PWA Stats.

Answering the question “What is a progressive web app?” is harder than it should be. The phrase was coined by Frances Berriman and Alex Russell. They listed ten characteristics that defined progressive web apps. The “linkable” and “progressive” characteristics are the really interesting and new characteristics. We’ve had technologies before (like Adobe Air) that tried to make app-like experiences, but they weren’t really of the web. Progressive web apps are different.

Despite this list of ten characteristics, even people who are shipping progressive web apps find it hard to define the damn thing. The definition on Google’s developer site keeps changing. They reduced the characteristics from ten to six. Then it became “reliable, fast, and engaging.” What does that mean? Craigslist is reliable, fast, and engaging—does that mean it’s a progressive web app.

The technical definition is useful (kudos to me, says Jason):

  1. HTTPS
  2. service worker
  3. manifest file

If you don’t have those three things, it’s not a progressive web app.

We should definitely use HTTPS if we want make life harder for the NSA. Also browser makers are making APIs available only under HTTPS. By July, Chrome will mark HTTP sites as insecure. Every site should be under HTTPS.

Service workers are where the power is. They act as a proxy. They allow us to say what we want to cache, what we want to go out to the network for; things that native apps have been able to do for a while. With progressive web apps we can cache the app shell and go to the network for content. Service workers can provide a real performance boost.

A manifest file is simply a JSON file. It’s short and clear. It lists information about the app: icons, colours, etc.

Once you provide those three things, you get benefits. Chrome and Opera on Android will prompt to add the app to the home screen.

So that’s what’s required for progressive web apps, but there’s more to them than that (in the same way there’s more to responsive web design than the three requirements in the baseline definition).

The hype around progressive web apps can be a bit of a turn-off. It certainly was for Jason. When he investigated the technologies, he wondered “What’s the big deal?” But then he was on a panel at a marketing conference, and everyone was talking about progressive web apps. People’s expectations of what you could do on the web really hadn’t caught up with what we can do now, and the phrase “progressive web app” gives us a way to encapsulate that. As Frances says, the name isn’t for us; it’s for our boss or marketer.

Jason references my post about using the right language for the right audience.

Should you have a progressive web app? Well, if you have a website, then the answer is almost certainly “Yes!” If you make money from that website, the answer is definitely “Yes!”

But there’s a lot of FUD around progressive web apps. It brings up the tired native vs. web battle. Remember though that not 100% of your users or customers have your app installed. And it’s getting harder to convince people to install apps. The average number of apps installed per month is zero. But your website is often a customer’s first interaction with your company. A better web experience can only benefit you.

Often, people say “The web can’t do…” but a lot of the time that information is out of date. There are articles out there with outdated information. One article said that progressive web apps couldn’t access the camera, location, or the fingerprint sensor. Yet look at Instagram’s progressive web app: it accesses the camera. And just about every website wants access to your location these days. And Jason knows you can use your fingerprint to buy things on the web because he accidentally bought socks when he was trying to take a screenshot of the J.Crew website on his iPhone. So the author of that article was just plain wrong. The web can do much more than we think it can.

Another common objection is “iOS doesn’t support progressive web apps”. Well, as of last week that is no longer true. But even when that was still true, people who had implemented progressive web apps were seeing increased conversion even on iOS. That’s probably because, if you’ve got the mindset for building a progressive web app, you’re thinking deeply about performance. In many ways, progressive web apps are a trojan horse for performance.

These are the things that people think about when it comes to progressive web apps:

  1. Making it feel like a app
  2. Installation and discovery
  3. Offline mode
  4. Push notifications
  5. Beyond progressive web app

Making it feel like a app

What is an app anyway? Nobody can define it. Once again, Jason references my posts on this topic (how “app” is like “obscenity” or “brunch”).

A lot of people think that “app-like” means making it look native. But that’s a trap. Which operating system will you choose to emulate? Also, those design systems change over time. You should define your own design. Make it an exceptional experience regardless of OS.

It makes more sense to talk in terms of goals…

Goal: a more immersive experience.

Possible solution: removing the browser chrome and going fullscreen?

You can define this in the manifest file. But as you remove the browser chrome, you start to lose things that people rely on: the back button, the address bar. Now you have to provide that functionality. If you move to a fullscreen application you need to implement sharing, printing, and the back button (and managing browser history is not simple). Remember that not every customer will add your progressive web app to their home screen. Some will have browser chrome; some won’t.

Goal: a fast fluid experience.

Possible solution: use an app shell model.

You want smooth pages that don’t jump around as the content loads in. The app shell makes things seem faster because something is available instantly—it’s perceived performance. Basically you’re building a single page application. That’s a major transition. But thankfully, you don’t have to do it! Progressive web apps don’t have to be single page apps.

Goal: an app with personality.

Possible solution: Animated transitions and other bits of UI polish.

Really, it’s all about delight.

Installation and discovery

In your manifest file you can declare a background colour for the startup screen. You can also declare a theme colour—it’s like you’re skinning the browser chrome.

You can examine the manifest files for a site in Chrome’s dev tools.

Once you’ve got a progressive web app, some mobile browsers will start prompting users to add it to their home screen. Firefox on Android displays a little explainer the first time you visit a progressive web app. Chrome and Opera have add-to-homescreen banners which are a bit more intrusive. The question of when they show up keeps changing. They use a heuristic to decide this. The heuristic has been changed a few times already. One thing you should consider is suppressing the banner until it’s an optimal time. Flipkart do this: they only allow it on the order confirmation page—the act of buying something makes it really likely that someone will add the progressive web app to their home screen.

What about app stores? We don’t need them for progressive web apps—they’re on the web. But Microsoft is going to start adding progressive web apps to their app store. They’ve built a site called PWA Builder to help you with your progressive web app.

On the Android side, there’s Trusted Web Activity which is kind of like PhoneGap—it allows you to get a progressive web app into the Android app store.

But remember, your progressive web app is your website so all the normal web marketing still applies.

Offline mode

A lot of organisations say they have no need for offline functionality. But everyone has a need for some offline capability. At the very least, you can provide a fallback page, like Trivago’s offline maze game.

You can cache content that has been recently viewed. This is what Jason does on the Cloud Four site. They didn’t want to make any assumptions about what people might want, so they only cache pages as people browse around the site.

If you display cached information, you might want to display how stale the information is e.g. for currency exchange rates.

Another option is to let people choose what they want to keep offline. The Financial Times does this. They also pre-cache the daily edition.

If you have an interactive application, you could queue tasks and then carry them out when there’s a connection.

Or, like Slack does, don’t let people write something if they’re offline. That’s better than letting someone write something and then losing it.

Workbox is a handy library for providing offline functionality.

Push notifications

The JavaScript for push notifications is relatively easy, says Jason. It’s the back-end stuff that’s hard. That’s because successful push notifications are personalised. But to do that means doing a lot more work on the back end. How do you integrate with preferences? Which events trigger notifications?

There are third-party push notification services that take care of a lot of this for you. Jason has used OneSignal.

Remember that people are really annoyed by push notifications. Don’t ask for permission immediately. Don’t ask someone to marry you on a first date. On Cloud Four’s blog, they only prompt after the user has read an article.

Twitter’s progressive web app does this really well. It’s so important that you do this well: if a user says “no” to your push notification permission request, you will never be able to ask them again. There used to be three options on Chrome: allow, block, or close. Now there are just two: allow or block.

Beyond progressive web apps

There are a lot of APIs that aren’t technically part of progressive web apps but get bundled in with them. Like the Credentials Management API or the Payment Request API (which is converging with ApplePay).

So how should you plan your progressive web app launch? Remember it’s progressive. You can keep adding features. Each step along the way, you’re providing value to people.

Start with some planning and definition. Get everyone in a room and get a common definition of what the ideal progressive web app would look like. Remember there’s a continuum of features for all five of the things that Jason has outlined here.

Benchmark your existing site. It will help you later on.

Assess your current website. Is the site reasonably fast? Is it responsive? Fix those usability issues first.

Next, do the baseline. Switch to HTTPS. Add a manifest file. Add a service worker. Apart from the HTTPS switch, this can all be done on the front end. Don’t wait for all three: ship each one when they’re ready.

Then do front-end additions: pre-caching pages, for example.

Finally, there are the larger initiatives (with more complex APIs). This is where your initial benchmarking really pays off. You can demonstrate the value of what you’re proposing.

Every step on the path to a progressive web app makes sense on its own. Figure out where you want to go and start that journey.

See also:

Navigating Team Friction by Lara Hogan

It’s day two of An Event Apart Seattle (Special Edition). Lara is here to tell us about Navigating Team Friction. These are my notes…

Lara started as a developer, and then moved into management. Now she consults with other organisations. So she’s worked with teams of all sizes, and her conclusion is that humans are amazing. She has seen teams bring a site down; she has seen teams ship amazing features; she has seen teams fall apart because they had to move desks. But it’s magical that people can come together and build something.

Bruce Tuckman carried out research into the theory of group dynamics. He published stages of group development. The four common stages are:

  1. Forming. The group is coming together. There is excitement.
  2. Storming. This is when we start to see some friction. This is necessary.
  3. Norming. Things start to iron themselves out.
  4. Performing. Now you’re in the flow state and you’re shipping.

So if your team is storming (experiencing friction), that’s absolutely normal. It might be because of disagreement about processes. But you need to move past the friction. Team friction impacts your co-workers, company, and users.

An example. Two engineers passively-aggressively commenting each other’s code reviews; they feign surprise at the other’s technology choices; one rewrites the others code; one ships to production with code review; a senior team member or manager has to step in. But it costs a surprising amount of time and energy before a manager even notices to step in.

Brains

The Hulk gets angry. This is human. We transform into different versions of ourselves when we are overcome by our emotions.

Lara has learned a lot about management by reading about how our brains work. We have a rational part of our brain, the pre-frontal cortex. It’s very different to our amygdala, a much more primal part of our brain. It categorises input into either threat or reward. If a threat is dangerous enough, the amygdala takes over. The pre-frontal cortex is too slow to handle dangerous situations. So when you have a Hulk moment, that was probably an amygdala hijack.

We have six core needs that are open to being threatened (leading to an amygdala hijacking):

  1. Belonging. Community, connection; the need to belong to a tribe. From an evolutionary perspective, this makes sense—we are social animals.
  2. Improvement/Progress. Progress towards purpose, improving the lives of others. We need to feel that we do matters, and that we are learning.
  3. Choice. Flexibility, autonomy, decision-making. The power to make decisions over your own work.
  4. Equality/Fairness. Access to resources and information; equal reciprocity. We have an inherent desire for fairness.
  5. Predictability. Resources, time, direction future challenges. We don’t like too many surprises …but we don’t like too much routine either. We want a balance.
  6. Significance. Status, visibility, recognition. We want to feel important. Being assigned to a project you think is useless feels awful.

Those core needs are B.I.C.E.P.S. Thinking back to your own Hulk moment, which of those needs was threatened?

We value those needs differently. Knowing your core needs is valuable.

Desk Moves

Lara has seen the largest displays of human emotion during something as small as moving desks. When you’re asked to move your desk, your core need of “Belonging” may be threatened. Or it may be a surprise that disrupts the core need of “Improvement/Progress.” If a desk move is dictated to you, it feels like “Choice” is threatened. The move may feel like it favours some people over others, threatening “Equality/Fairness.” The “Predictability” core need may be threatened by an unexpected desk move. If the desk move feels like a demotion, your core need of “Significance” will be threatened.

We are not mind readers, so we can’t see when someone’s amygdala takes over. But we can look out for the signs. Forms of resistance can be interpreted as data. The most common responses when a threat is detected are:

  1. Doubt. People double-down on the status quo; they question the decision.
  2. Avoidance. Avoiding the problem; too busy to help with the situation.
  3. Fighting. People create arguments against the decision. They’ll use any logic they can. Or they simply refuse.
  4. Bonding. Finding someone else who is also threatened and grouping together.
  5. Escape-route. Avoiding the threat by leaving the company.

All of these signals are data. Rather than getting frustrated with these behaviours, use them as valuable data. Try not to feel threatened yourself by any of these behaviours.

Open questions are powerful tool in your toolbox. Asked from a place of genuine honesty and curiosity, open questions help people feel less threatened. Closed questions are questions that can be answered with “yes” or “no”. When you spot resistance, get some one-on-one time and try to ask open questions:

  • What do you think folks are liking or disliking about this so far?
  • I wanted to get your take on X. What might go wrong? What do you think might be good about it?
  • What feels most upsetting about this?

You can use open questions like these to map resistance to threatened core needs. Then you can address those core needs.

This is a good time to loop in your manager. It can be very helpful to bounce your data off someone else and get their help. De-escalating resistance is a team effort.

Communication ✨

Listen with compassion, kindness, and awareness.

  • Reflect on the dynamics in the room. Maybe somebody thinks a topic is very important to them. Be aware of your medium. Your body language; your tone of voice; being efficient with words could be interpreted as a threat. Consider the room’s power dynamics. Be aware of how influential your words could be. Is this person in a position to take the action I’m suggesting?
  • Elevate the conversation. Meet transparency with responsibility.
  • Assume best intentions. Remember the prime directive. Practice empathy. Ask yourself what else is going on for this person in their life.
  • Listen to learn. Stay genuinely curious. This is really hard. Remember your goal is to understand, not make judgement. Prepare to be surprised when you walk into a room. Operate under the assumption that you don’t have the whole story. Be willing to have your mind changed …no, be excited to have your mind changed!

This tips are part of mindful communication. amy.tech has some great advice for mindful communication in code reviews.

Feedback

Mindful communication won’t solve all your problems. There are times when you’ll have to give actionable feedback. The problem is that humans are bad at giving feedback, and we’re really bad at receiving feedback. We actively avoid feedback. Sometimes we try to give constructive feedback in a compliment sandwich—don’t do that.

We can get better at giving and receiving feedback.

Ever had someone say, “Hey, you’re doing a great job!” It feels good for a few minutes, but what we crave is feedback that addresses our core needs.

GeneralSpecific and Actionable
Positive Feedback
Negative Feedback

The feedback equation starts with an observation (“You’re emails are often short”)—it’s not how you feel about the behaviour. Next, describe the impact of the behaviour (“The terseness of your emails makes me confused”). Then pose a question or request (“Can you explain why you write your emails that way?”).

observation + impact + question/request

Ask people about their preferred feedback medium. Some people prefer to receive feedback right away. Others prefer to digest it. Ask people if it’s a good time to give them feedback. Pro tip: when you give feedback, ask people how they’d like to receive feedback in the future.

Prepare your brain to receive feedback. It takes six seconds for your amygdala to chill out. Take six seconds before responding. If you can’t de-escalate your amygdala, ask the person giving feedback to come back later.

Think about one piece of feedback you’ll ask for back at work. Write it down. When your back at work, ask about it.

You’ll start to notice when your amygdala or pre-frontal cortex is taking over.

Prevention

Talking one-on-one is the best way to avoid team friction.

Retrospectives are a great way of normalising of talking about Hard Things and team friction.

It can be helpful to have a living document that states team processes and expectations (how code reviews are done; how much time is expected for mentoring). Having it written down makes it a North star you can reference.

Mapping out roles and responsibilities is helpful. There will be overlaps in that Venn diagram. The edges will be fuzzy.

What if you disagree with what management says? The absence of trust is at the centre of most friction.

DisgreeAgree
CommitMature and TransparentEasiest
Don’t CommitAcceptable but ToughBad Things

Practice finding other ways to address B.I.C.E.P.S. You might not to be able to fix the problem directly—the desk move still has to happen.

But no matter how empathic or mindful you are, sometimes it will be necessary to bring in leadership or HR. Loop them in. Restate the observation + impact. State what’s been tried, and what you think could help now. Throughout this process, take care of yourself.

Remember, storming is natural. You are now well-equipped to weather that storm.

See also:

An associative trail

Every now and then, I like to revisit Vannevar Bush’s classic article from the July 1945 edition of the Atlantic Monthly called As We May Think in which he describes a theoretical machine called the memex.

A memex is a device in which an individual stores all his books, records, and communications, and which is mechanized so that it may be consulted with exceeding speed and flexibility. It is an enlarged intimate supplement to his memory.

It consists of a desk, and while it can presumably be operated from a distance, it is primarily the piece of furniture at which he works. On the top are slanting translucent screens, on which material can be projected for convenient reading. There is a keyboard, and sets of buttons and levers. Otherwise it looks like an ordinary desk.

1945! Apart from its analogue rather than digital nature, it’s a remarkably prescient vision. In particular, there’s the idea of “associative trails”:

Wholly new forms of encyclopedias will appear, ready made with a mesh of associative trails running through them, ready to be dropped into the memex and there amplified. The lawyer has at his touch the associated opinions and decisions of his whole experience, and of the experience of friends and authorities.

Many decades later, Anne Washington ponders what a legal memex might look like:

My legal Memex builds a network of the people and laws available in the public records of politicians and organizations. The infrastructure for this vision relies on open data, free access to law, and instantaneously availability.

As John Sheridan from the UK’s National Archives points out, hypertext is the perfect medium for laws:

Despite the drafter’s best efforts to create a narrative structure that tells a story through the flow of provisions, legislation is intrinsically non-linear content. It positively lends itself to a hypertext based approach. The need for legislation to escape the confines of the printed form predates the all major innovators and innovations in hypertext, from Vannevar Bush’s vision in ” As We May Think“, to Ted Nelson’s coining of the term “hypertext”, through to and Berners-Lee’s breakthrough world wide web. I like to think that Nelson’s concept of transclusion was foreshadowed several decades earlier by the textual amendment (where one Act explicitly alters – inserts, omits or amends – the text of another Act, an approach introduced to UK legislation at the beginning of the 20th century).

That’s from a piece called Deeply Intertwingled Laws. The verb “to intertwingle” was another one of Ted Nelson’s neologisms.

There’s an associative trail from Vannevar Bush to Ted Nelson that takes some other interesting turns…

Picture a new American naval recruit in 1945, getting ready to ship out to the pacific to fight against the Japanese. Just as the ship as leaving the harbour, word comes through that the war is over. And so instead of fighting across the islands of the pacific, this young man finds himself in a hut on the Philippines, reading whatever is to hand. There’s a copy of The Atlantic Monthly, the one with an article called As We May Think. The sailor was Douglas Engelbart, and a few years later when he was deciding how he wanted to spend the rest of his life, that article led him to pursue the goal of augmenting human intellect. He gave the mother of all demos, featuring NLS, a working hypermedia system.

Later, thanks to Bill Atkinson, we’d get another system called Hypercard. It was advertised with the motto Freedom to Associate, in an advertising campaign that directly referenced Vannevar Bush.

And now I’m using the World Wide Web, a hypermedia system that takes in the whole planet, to create an associative trail. In this post, I’m linking (without asking anyone for permission) to six different sources, and in doing so, I’m creating a unique associative trail. And because this post has a URL (that won’t change), you are free to take it and make it part of your own associative trail on your digital memex.

What is a Progressive Web App?

It seems like any new field goes through an inevitable growth spurt that involves “defining the damn thing.” For the first few years of the IA Summit, every second presentation seemed to be about defining what Information Architecture actually is. See also: UX. See also: Content Strategy.

Now it seems to be happening with Progressive Web Apps …which is odd, considering the damn thing is defined damn well.

I’ve written before about the naming of Progressive Web Apps. On the whole, I think it’s a pretty good term, especially if you’re trying to convince the marketing team.

Regardless of the specifics of the name, what I like about Progressive Web Apps is that they have a clear definition. It reminds me of Responsive Web Design. Whatever you think of that name, it comes with a clear list of requirements:

  1. A fluid layout,
  2. Fluid images, and
  3. Media queries.

Likewise, Progressive Web Apps consist of:

  1. HTTPS,
  2. A service worker, and
  3. A Web App Manifest.

There’s more you can do in addition to that (just as there’s plenty more you can do on a responsive site), but the core definition is nice and clear.

Except, for some reason, that clarity is being lost.

Here’s a post by Ben Halpern called What the heck is a “Progressive Web App”? Seriously.

I have a really hard time describing what a progressive web app actually is.

He points to Google’s intro to Progressive Web Apps:

Progressive Web Apps are user experiences that have the reach of the web, and are:

  • Reliable - Load instantly and never show the downasaur, even in uncertain network conditions.
  • Fast - Respond quickly to user interactions with silky smooth animations and no janky scrolling.
  • Engaging - Feel like a natural app on the device, with an immersive user experience.

Those are great descriptions of the benefits of Progressive Web Apps. Perfect material for convincing your clients or your boss. But that appears on developers.google.com …surely it would be more beneficial for that audience to know the technologies that comprise Progressive Web Apps?

Ben Halpern again:

Google’s continued use of the term “quality” in describing things leaves me with a ton of confusion. It really seems like they want PWA to be a general term that doesn’t imply any particular implementation, and have it be focused around the user experience, but all I see over the web is confusion as to what they mean by these things. My website is already “engaging” and “immersive”, does that mean it’s a PWA?

I think it’s important to use the right language for the right audience.

If you’re talking to the business people, tell them about the return on investment you get from Progressive Web Apps.

If you’re talking to the marketing people, tell them about the experiential benefits of Progressive Web Apps.

But if you’re talking to developers, tell them that a Progressive Web App is a website served over HTTPS with a service worker and manifest file.