Anvil apps can function offline. In other words, an app’s client-side code will continue to work if the device loses its internet connection.
When an app is offline, client-side code (Forms and Modules) will continue to work.
However, any code that tries to communicate with the server will fail with an
This includes accessing the Users Service, working with Data Tables or any use of
This section explores some offline strategies to handle code that communicates with the server.
Anvil apps are progressive web apps (PWAs) and can be installed almost like native apps.
Specific instructions for installing an Anvil app depends on the platform. On Chrome desktop, the option is available next to the address bar. In Chrome for Android or Safari for iPhone, there is an option to ‘Add to home screen’.
Installing an Anvil app isn’t necessary for an app to work offline. If you visit an Anvil app in a browser and lose connection, the app will continue to run as described above.
There are two ways to check if an app is online. The first is using
If this returns
False, subsequent communications to the server will fail.
if anvil.server.is_app_online(): user = anvil.users.login_with_form() else: # we can't use the Users Service since we're offline alert('It looks like you're offline')
It is worth noting that
anvil.server.is_app_online() is a heuristic for checking the app’s online status based on the browser’s implementation.
anvil.server.is_app_online() is reliable at determining when an app is offline. However, it is a known issue that some browsers may give a false positive, i.e. the browser determines the app is online when it is offline. Be prepared to act offline in this situation. Consider providing users with an offline mode. An offline mode will provide users with a stable network option. Useful when the network jumps from offline to online in areas of unstable connection.
Alternatively, wrapping code that communicates with the server in a
try/except block will allow you to catch and handle an
try: anvil.server.call('save_data', data) except anvil.server.AppOfflineError: ... # save the data in the browser
anvil.server.AppOfflineError is raised anytime an offline app attempts to communicate with the server.
In the above example, we use the
try/except strategy. First, we
try and save data using
If we find the app is offline, the code inside the
except block runs.
We would then need to consider strategies for storing (caching) data in the browser inside the
Later, when the app comes back online, we can make the server call using the cached data.
If your app needs data and you want it to run offline, you’ll have to store (cache) that data in the browser to interact with it. Likewise, if a user makes changes while offline, you’ll need to store those changes until you can save them on the server.
A simple storage mechanism for browsers is the
It can be used to store JSON data and can be accessed using
from anvil.js.window import localStorage import json if anvil.server.is_app_online(): anvil.server.call('save_data', data) else: localStorage.setItem('unsaved_data', json.dumps(data))
from anvil_extras.storage import local_storage if anvil.server.is_app_online(): anvil.server.call('save_data', data) else: local_storage['unsaved_data'] = data
Note that the persistence of
localStorage depends on the browser. After several days of inactivity, a browser may clear the
localStorage is best suited for JSONable data. For more advanced offline data storage consider the browser’s
IndexedDB is a low level client-side database that is suitable for storing simple data types such as strings and floats, as well as more complex data types such as bytes and lists. Working with
IndexedDB in a more user friendly API.
In the following Todo app, we explore some strategies for working with data offline. Launching the app offline is possible since it caches user data from the previous sessions. If the app goes offline during a session, attempts to save data on the server are also cached.