5 Because internet connections can be flakey or non-existent,
6 you need to consider
<em>offline first
</em>:
7 write your app as if it has no internet connection.
8 Once your app works offline,
9 add whatever network functionality you need
10 for your app to do more when it’s online.
11 Read on for tips on implementing your offline-enabled app.
14 <h2 id=
"overview"> Overview
</h2>
17 Chrome Apps get the following for free:
21 <li> Your app’s files
—all of its JavaScript,
22 CSS, and fonts, plus other resources it needs
23 (such as images)
—are
<b>already downloaded
</b>.
</li>
24 <li> Your app can
<b>save and optionally sync
</b>
25 small amounts of data using the
26 <a href=
"storage">Chrome Storage API
</a>.
</li>
27 <li> Your app can
<b>detect changes in connectivity
</b>
29 <a href=
"https://developer.mozilla.org/en/Online_and_offline_events">online and offline events
</a>.
</li>
33 But those abilities aren't enough to guarantee that your app
35 Your offline-enabled app should follow these rules:
39 <dt> Use local data whenever possible.
</dt>
40 <dd> When using resources from the internet,
41 use
<code>XMLHttpRequest
</code> to get it,
42 and then save the data locally.
43 You can use the Chrome Storage API,
45 Filesystem API to save data locally.
</dd>
47 <dt> Separate your app’s UI from its data.
</dt>
49 Separating the UI and data not only
50 improves your app's design and
51 eases the task of enabling offline usage,
52 but also lets you provide other views of the user's data.
53 An MVC framework can help you keep the UI and data separate.
56 <dt> Assume your app can be closed at any time.
</dt>
57 <dd> Save application state
58 (both locally and remotely, when possible)
59 so that users can pick up
60 wherever they left off.
</dd>
62 <dt> Test your app thoroughly.
</dt>
63 <dd> Make sure your app works well in both
64 <a href=
"#testing">common and tricky scenarios
</a>.
</dd>
68 <h2 id=
"possibilities"> Security restrictions
</h2>
71 Chrome Apps are limited
72 in where they can place their resources:
78 is visible on the user's machine
79 and can't be securely encrypted,
80 <b>sensitive data must stay on the server
</b>.
81 For example, don't store passwords or credit card numbers locally.
83 <li> All
<b>JavaScript
</b> that the app executes
84 must be in the app's package.
85 It
<b>cannot
</b> be inline.
88 <li> All
<b>CSS styles
</b>,
<b>images
</b>, and
<b>fonts
</b>
89 can be initially located
90 either in the app's package
92 If the resource is remote,
93 you can't specify it in your HTML.
94 Instead, get the data using
<code>XMLHttpRequest
</code>
95 (see
<a href=
"app_external#external">Referencing external resources
</a>).
96 Then either refer to the data with a blob URL
97 or (better yet) save and then load the data using the
98 <a href=
"app_storage">Filesystem API
</a>.
102 Styles can be inline or in separate
<code>.css
</code> files.
110 load large media resources such as videos and sounds
112 One reason for this exception to the rule
113 is that the
<video
> and
<audio
> elements
114 have good fallback behavior when an app
115 has limited or no connectivity.
116 Another reason is that fetching and serving media
117 with
<code>XMLHttpRequest
</code> and blob URLs
118 currently does not allow
119 streaming or partial buffering.
123 To provide a sandboxed iframe,
124 you can create an
<webview
> tag.
125 Its contents can be remote,
126 but it has no direct access to the Chrome app APIs
127 (see
<a href=
"app_external#webview">Embed external web pages
</a>).
131 Some of the restrictions on Chrome Apps are enforced by the
132 <a href=
"contentSecurityPolicy">Content Security Policy (CSP)
</a>
133 which is always the following and cannot be changed for Chrome Apps:
139 style-src 'self' blob: data: filesystem: 'unsafe-inline';
140 img-src 'self' blob: data: filesystem:;
141 frame-src 'self' blob: data: filesystem:;
142 font-src 'self' blob: data: filesystem:;
146 <h2 id=
"manifest"> Specifying offline_enabled
</h2>
149 It is assumed that your app behaves well offline. If it doesn't, you should
150 advertise that fact, so that its launch icon is dimmed when the user is offline.
151 To do so, set
<code>offline_enabled
</code> to
<code>false
</code> in the
152 <a href=
"manifest">app manifest file
</a>:
155 <pre data-filename=
"manifest.json">
159 <b>"offline_enabled": false,
</b>
164 <h2 id=
"saving-locally"> Saving data locally
</h2>
167 The following table shows your options for saving data locally
168 (see also
<a href=
"app_storage">Manage Data
</a>).
171 <table class=
"simple">
173 <th> API
</th> <th> Best use
</th> <th> Notes
</th>
176 <td> Chrome Storage API
</td>
177 <td> Small amounts of string data
</td>
178 <td> Great for settings and state.
179 Easy to sync remotely (but you don't have to).
180 Not good for larger amounts of data,
185 <td> IndexedDB API
</td>
186 <td> Structured data
</td>
187 <td> Enables fast searches on data.
189 <a href=
"declare_permissions">unlimitedStorage permission
</a>.
</td>
192 <td> Filesystem API
</td>
193 <td> Anything else
</td>
194 <td> Provides a sandboxed area where you can store files.
196 <a href=
"declare_permissions">unlimitedStorage permission
</a>.
</td>
202 Packaged apps cannot use Web SQL Database or localStorage.
203 The WebSQL specification has been deprecated for awhile now,
204 and localStorage handles data synchronously
205 (which means it can be slow).
206 The Storage API handles data asynchronously.
210 <h2 id=
"saving-remotely"> Saving data remotely
</h2>
213 In general, how you save data remotely is up to you,
214 but some frameworks and APIs can help
215 (see
<a href=
"app_frameworks">MVC Architecture
</a>).
216 If you use the Chrome Storage API,
217 then all syncable data
218 is automatically synced
219 whenever the app is online
220 and the user is signed in to Chrome.
221 If the user isn't signed in,
222 they'll be prompted to sign in.
223 However, note that the user's synced data
224 is deleted if the user uninstalls your app.
225 <span class=
"comment">
231 Consider saving users' data for at least
232 30 days after your app is uninstalled,
233 so that users will have a good experience
234 if they reinstall your app.
238 <h2 id=
"mvc"> Separating UI from data
</h2>
241 Using an MVC framework can help you design and implement your app
242 so that the data is completely separate from the app's
244 See
<a href=
"app_frameworks">MVC Architecture
</a>
245 for a list of MVC frameworks.
249 If your app talks to a custom server,
250 the server should give you data,
252 Think in terms of RESTful APIs.
256 Once your data is separate from your app,
257 it's much easier to provide alternate views of the data.
259 you might provide a website view of any public data.
260 Not only can a website view
261 be useful when your user is away from Chrome,
262 but it can enable search engines to find the data.
266 <h2 id=
"testing"> Testing
</h2>
269 Make sure your app works well under the following circumstances:
274 The app is installed, and then immediately goes offline.
275 In other words, the first use of the app is offline.
278 The app is installed on one computer
279 and then synced to another.
282 The app is uninstalled and then immediately installed again.
285 The app is running on two computers at the same time,
286 with the same profile.
287 The app must behave reasonably
288 when one computer goes offline,
289 the user does a bunch of stuff on that computer,
290 and then the computer comes online again.
293 The app has intermittent connectivity,
294 switching often between online and offline.
299 Also make sure that the app saves
<b>no sensitive user data
</b>
300 (such as passwords) on the user's machine.
303 <p class=
"backtotop"><a href=
"#top">Back to top
</a></p>