How to do a Progressive Web App with Gatsby
2020-02-18
Gatsby challenge to set you website in a true PWA
This 7th Challenge is about turning our Gatsby site in a RealProgressive Web APP.
“Progressive web app” (PWA) is both a general term for a new philosophy toward building websites and a specific term with an established set of three explicit, testable, baseline requirements.
A PWA must be responsive, accessible, connectivity independent so it would work offline and really quick, App-like UI and interactions, safe (https is a must), installable to the home screen, engaging through the OS push notifications, identifiable as “applications” thanks to W3C Manifests and Service Worker registration scope, always up-to-date thanks to service workers, SEO optimized, easy to share (linkable).
In the practice, how it is the whole flow in action?
- The site begins life as a regular tab but it is built using Progressive App features including TLS, Service Workers, Manifests, and Responsive Design.
- The second time a user visits the page, a prompt is shown by the browser so one can add it the home screen.
- Launching from the home screen, the app is full-screen, and works offline after step 1.
So as Alex Russell says,
they’re just websites that took all the right vitamins.
Ok, so how a Gatsby site works as PWA?
It has to satisfy three points:
- It must run under HTTPS.
- It must include a Web App Manifest, which is a JSON file that provides the browser with information about your web app (name, icons, start_url, background-color, etc), and makes it possible for users to save to their home screen.
- Implement a service worker that provides support for an offline experience and makes your site more resilient to bad network connections. It’s a script that runs separately in the background, supporting features like push notifications and background sync.
How to set up these points in your Gtasby site?
For the 2nd point: Web App Manifest, Gatsby provides an official manifest plugin.
1npm install --save gatsby-plugin-manifest
And then, in gatsby-config.js:
1module.exports = { 2 plugins: [ 3 { 4 resolve: `gatsby-plugin-manifest`, 5 options: { 6 name: `Alberto Fortes, Senior Front-end developer`, 7 short_name: `Alberto Fortes`, 8 start_url: `/`, 9 background_color: `#0e2439`, 10 theme_color: `#0e2439`, 11 display: `standalone`, 12 icon: `src/images/icon-48x48.png`, // This path is relative to the root of the site. 13 icons: [ // manually, so they go to static folder: 14 { 15 src: `/static/icons/android-icon-48x48.png`, 16 sizes: `48x48`, 17 type: `image/png`, 18 }, 19 { 20 src: `/static/icons/android-icon-72x72.png`, 21 sizes: `72x72`, 22 type: `image/png`, 23 }, 24 { 25 src: `/static/icons/android-icon-96x96.png`, 26 sizes: `96x96`, 27 type: `image/png`, 28 }, 29 { 30 src: `/static/icons/android-icon-144x144.png`, 31 sizes: `144x144`, 32 type: `image/png`, 33 }, 34 { 35 src: `/static/icons/android-icon-192x192.png`, 36 sizes: `192x192`, 37 type: `image/png`, 38 }, 39 { 40 src: `/static/icons/ms-icon-310x310.png`, 41 sizes: `310x310`, 42 type: `image/png`, 43 } 44 ] 45 } 46 }, 47 ], 48}
For the 3rd point: Service workers, Gatsby also provides a plugin interface to create and load a service worker into your site.
1npm install --save gatsby-plugin-offline
And then, in gatsby-config.js:
1plugins: [`gatsby-plugin-offline`]
It is important that this plugin should be listed before the offline plugin so that it can cache the created manifest.webmanifest.
We need to install both, and don’t forget to list the offline plugin after the manifest plugin so that the manifest file can be included in the service worker.
Extra ball: Do you have an issue while building?
I had this issue:
A page component must export a React component for it to be valid. Please make sure this file exports a React component: ...node_modules/gatsby-plugin-offline/app-shell.js
This is due to a know issue with the latest gatsby-plugin-offline 2.2.10, so meanwhile they solve it this is the quick fix:
- Do a clean:
1gatsby clean
- Uninstall old version of the package:
1npm uninstall gatsby-plugin-offline
- Now reinstall a new fresh version:
1npm install gatsby-plugin-offline
This moved mine from 2.2.10 to 3.0.35
It should work, but if still is not working, explore your Components and be sure all them are in the format:
1const ComponentName = ({ children }) => {} 2[...] 3export default ComponentName
and none is auto-exporting:
1export default ({ data }) => {}