What are Progressive Web Apps? Simply put, they are web applications that deliver mobile app-like experiences. For example, open web technologies are now making it possible for browser-based web apps to be:
- installable - add web apps to the Home Screen of a mobile device easily
- more reliable - provide a user experience when the device is offline or network responsiveness has degraded; sync user requests in the background when network capability is restored
- more engaging - notify users of activity even when they're not using the site
Sound good? Let's get started.
Your first Progressive Web App on Rails
Eric Elliot recently posted a thorough overview of Progessive Web App requirements that's worth a read. Here's summary of what's needed:
- HTTPS - any page that uses Progressive Web App technology needs to be served over SSL/TLS so "HTTPS everywhere" is recommended
- Web App Manifest - a text file with application metadata to support home screen installation
Set up HTTPS
To enable HTTPS on our website, we'll need to decide for ourselves how to set up our web server depending on our hosting provider and deployment needs. Tutorials for setting up Heroku and Digital Ocean may be a good place to start.
We'll also want to force SSL settings in our Rails application
configuration for our remote environments, i.e.,
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
We should be sure to test out this behavior on a secondary remote environment before going live in production as we'll want to be aware of hiccups like mixed content warnings and hard-coded non-HTTPS urls in our application.
Add a manifest and Service Worker
For this next step, we'll assume we're using the Rails asset pipeline. This is both helpful and presents a problem:
Service worker and manifest assets must play by different rules. Service workers may only be active from within the scope from which they are served. So if you try to register a service worker from a Rails asset pipeline path, like
/assets/serviceworker-abcd1234.js, it will only be able to interact with requests and responses within
/assets/**. This is not what we want.
To address this issue, I created the
serviceworker-rails gem (source). This Rails
plugin makes it easier to set up your app to serve service worker
scripts and web app manifests at canonical urls while taking advantage of the transpilation and
interpolation features the asset pipeline provides.
To get started with
serviceworker-rails, we'll bundle it with our Rails app.
Add the gem to the
Bundle the app:
$ rails g serviceworker:install
The generator will create the following files:
config/initializers/serviceworker.rb- for configuring your Rails app
public/offline.html- a starter offline page
It will also make the following modifications to existing files:
- Adds a sprockets directive to
manifest.jsonto the list of compiled assets in
- Injects tags into the
app/views/layouts/application.html.erbfor linking to the web app manifest
Of course, we could do this set up manually, but it may be helpful to run the
automated install for our first attempt. If going manual, consult the
README and my previous blog
post on configuring the gem for more help during setup.
At this point, we've got all the boilerplate in place in our Rails app to begin adding Progessive Web App functionality. The great part is, we can pick and choose which features we want to add.
Here are few things you can try:
- Adding an offline page for your Rails app - by @rossta
- Sending Web Push notifications from Rails - by @rossta
- Instant loading Web Apps with a Service Worker application shell architecture - by Addy Osmani *
For more on grasping Service Worker fundamentals and developing offline solutions for the web, I highly recommend this free Udacity course:
- Offline Web Applications by Google
You'll want to understand the Service Worker life cycle, which Jake Archibald treats in great detail:
For some open-source abstractions for implementing Service Worker fetching and caching strategies, checkout out SW-Toolbox and SW-Precache from the Google Chrome team.
Of course, we've only covered the getting started part of our journey with Progressive Web Apps. I've left out a lot of fun parts like decided how to implement caching strategies or send push notifications. Here are some resources to check out to take your PWA skills to the next level:
- ServiceWorke.rs - a set of Service Worker recipes and demos from Mozilla
- Offline Cookbook - a great rundown of Service Worker snippets, including a number of caching strategies, by Jake Archibald
- Service Worker on Rails Sandbox - a demo Progressive Web App on Rails using the
serviceworker-railsgem by @rossta
- Awesome Progressive Web Apps - kitchen sink of PWA resources
- Awesome Service Workers - kitchen sink of Service Worker resources
Rails 💜 PWA
In the coming years, I believe it will become increasingly important to adopt PWA features to keep up with demand as more and more site visits will shift to mobile web.