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