UNPKG

5.18 kBMarkdownView Raw
1# pwa-helpers
2
3[![Build Status](https://travis-ci.org/Polymer/pwa-helpers.svg?branch=master)](https://travis-ci.org/Polymer/pwa-helpers)
4[![Published on npm](https://img.shields.io/npm/v/pwa-helpers.svg)](https://www.npmjs.com/package/pwa-helpers)
5
6Small helper methods or mixins to help build a PWA,
7and reduce the boilerplate you might have to write. There are many different
8ways in which you could write these helpers; use these if you want a simple
9starting point.
10
11## Basic helpers
12These are vanilla JavaScript methods that can be used regardless of which
13frameworks or libraries your application is written in.
14
15### `router.js`
16Basic router that calls a callback whenever the location is updated.
17
18Example:
19
20```js
21import { installRouter } from 'pwa-helpers/router.js';
22
23installRouter((location) => handleNavigation(location));
24```
25
26For example, if you're using this router in a Redux-connected component,
27you could dispatch an action in the callback:
28
29```js
30import { installRouter } from 'pwa-helpers/router.js';
31import { navigate } from '../actions/app.js';
32
33installRouter((location) => store.dispatch(navigate(location)));
34```
35
36If you need to force a navigation to a new location programmatically, you can
37do so by pushing a new state using the History API, and then manually
38calling the callback with the new location:
39
40```js
41window.history.pushState({}, '', '/new-route');
42handleNavigation(window.location);
43```
44
45Optionally, you can use the second argument to read the event that caused the
46navigation. For example, you may want to scroll to top only after a link click.
47
48```js
49installRouter((location, event) => {
50 // Only scroll to top on link clicks, not popstate events.
51 if (event && event.type === 'click') {
52 window.scrollTo(0, 0);
53 }
54 handleNavigation(location);
55});
56```
57
58### `network.js`
59Utility method that calls a callback whenever the network connectivity of the app changes.
60The callback should take a boolean parameter (with `true` meaning
61the network is offline, and `false` meaning online)
62
63Example:
64
65```js
66import { installOfflineWatcher } from 'pwa-helpers/network.js';
67
68installOfflineWatcher((offline) => {
69 console.log('You are ' + offline ? ' offline' : 'online');
70});
71```
72
73### `metadata.js`
74Utility method that updates the page's open graph and Twitter card metadata.
75It takes an object as a parameter with the following properties:
76title | description | url | image.
77
78If the `url` is not specified, `window.location.href` will be used; for
79all other properties, if they aren't specified, then that metadata field will not
80be set.
81
82Example (in your top level element or document, or in the router callback):
83
84```js
85import { updateMetadata } from 'pwa-helpers/metadata.js';
86
87updateMetadata({
88 title: 'My App - view 1',
89 description: 'This is my sample app',
90 url: window.location.href,
91 image: '/assets/view1-hero.png'
92});
93```
94
95### `media-query.js`
96Utility method that calls a callback whenever a media-query matches in response
97to the viewport size changing. The callback should take a boolean parameter
98(with `true` meaning the media query is matched).
99
100Example:
101
102```js
103import { installMediaQueryWatcher } from 'pwa-helpers/media-query.js';
104
105installMediaQueryWatcher(`(min-width: 600px)`, (matches) => {
106 console.log(matches ? 'wide screen' : 'narrow sreen');
107});
108```
109
110## Test helpers
111Utility methods to be used inside of testing frameworks, to reduce some testing boilerplate.
112
113### `axe-report.js`
114This is an [axe-core](https://github.com/dequelabs/axe-core) reporter that returns an
115Error containing every a11y violation for an element. Use this if you want to
116include `axe-core` in automated Mocha tests, etc.
117
118Example (in a Mocha test):
119
120```js
121import 'axe-core/axe.min.js';
122import { axeReport } from 'pwa-helpers/axe-report.js';
123
124describe('button', function() {
125 it('is accessible', function() {
126 const button = document.createElement('button');
127 button.textContent = 'click this'; // Test should fail without this line.
128 return axeReport(button);
129 });
130});
131```
132
133## Redux helpers
134These utility methods are useful if your application is using Redux for state management.
135
136### `connect-mixin.js`
137This is a JavaScript mixin that you can use to connect a Custom Element base
138class to a Redux store. The `stateChanged(state)` method will be called when
139the state is updated.
140
141Example:
142
143```js
144import { connect } from 'pwa-helpers/connect-mixin.js';
145
146class MyElement extends connect(store)(HTMLElement) {
147 stateChanged(state) {
148 this.textContent = state.data.count.toString();
149 }
150}
151```
152
153### `lazy-reducer-enhancer.js`
154A Redux store enhancer that lets you lazy-install reducers after the store
155has booted up. Use this if your application lazy-loads routes that are connected
156to a Redux store.
157
158Example:
159
160```js
161import { combineReducers } from 'redux';
162import { lazyReducerEnhancer } from 'pwa-helpers/lazy-reducer-enhancer.js';
163import someReducer from './reducers/someReducer.js';
164
165export const store = createStore(
166 (state, action) => state,
167 compose(lazyReducerEnhancer(combineReducers))
168);
169```
170
171Then, in your page/element, you can lazy load a specific reducer with:
172
173```js
174store.addReducers({
175 someReducer
176});
177```