Skip to content

Back to essay

Offline Ethics

Original slide content, adapted from the source deck into static cards.

  1. 01

    Offline Ethics

    Using React.js to Deliver Ethical Offline UX

  2. 02

    The Question

    Sometimes when a user sees a loading spinner, nothing is actually loading.

    Are we being candid about failure, or are we optimistically assuming the connection will come back soon?

  3. 03

    Why This Matters

    • We build applications for other people.
    • People move through stable, degraded, and missing connectivity.
    • Native apps often handle this better than web applications.
    • Browsers already give us tools to respond honestly.
  4. 04

    Ethical Offline UX

    An ethical offline experience is transparent about the point of failure, does not punish the user's intent, and restores confidence in their workflow.

  5. 05

    Part I

    Let's get ethical.

  6. 06

    Does This Pose an Ethical Question?

    • Is offline support a personal conviction or a trade standard?
    • Is a loading spinner disingenuous when we know there is no connection?
    • Is disabling form fields the only expectation users can have?
    • What do we owe someone who gave us their time, attention, work, or money?
  7. 07

    Hallmarks of an Ethical Offline Experience

    • Users should know they have gone offline.
    • Do not impede the workflow; curtail it only as necessary.
    • Let users resume their context when the connection returns.
  8. 08

    Users Should Know They Have Gone Offline

    A small banner, message, or state change can give the user truthful information about their current context.

  9. 09

    Do Not Prevent; Batch and Dispose

    If the application cannot send a `POST` or `PUT` request, hold the intended work locally, make the status visible, and dispose of the local copy after the server accepts it.

  10. 10

    Picking Up Where They Left Off Is Paramount

    If someone is sending a message, can they retry it? If they composed a draft, can they recover it? If they were reading a thread, can they return to the last useful state?

  11. 11

    Part II

    Case study.

  12. 12

    What Does This Look Like in Production?

    Facebook Messenger and Spectrum both showed pieces of this contract: they made connection failure visible, preserved some workflow, and gave the user a way back.

  13. 13

    Messenger

    • Shows the no-connection error.
    • Allows the user to keep writing.
    • Attempts to send.
    • Shows failure.
    • Lets the user retry.
  14. 14

    Spectrum

    • Loads the application shell.
    • Lets the user page through available posts.
    • Makes discussion-fetch failure explicit.
    • Asks the user to try again rather than pretending everything is fine.
  15. 15

    Part III

    Actual JavaScript that might help.

  16. 16

    Demo Shape

    A small budgeting application:

    • read budget data
    • add new expenses while offline
    • mark local items as not yet pushed
    • send queued data when the connection resumes
  17. 17

    Context Can Carry Offline State

    
    									import React, { Component, createContext } from "react";
    
    export const OfflineContext = createContext();
    
    export default class OfflineListener extends Component {
    	state = { offline: false };
    
    	componentDidMount() {
    		window.addEventListener("offline", this.handleChange);
    		window.addEventListener("online", this.handleChange);
    	}
    
    	handleChange = (event) => {
    		this.setState({
    			offline: !event.currentTarget.navigator.onLine,
    		});
    	};
    }
    
    								
  18. 18

    Publish Local State Downward

    
    									render() {
    	return (
    		<OfflineContext.Provider value={this.state}>
    			{this.props.children}
    		</OfflineContext.Provider>
    	);
    }
    
    								
  19. 19

    A Queued Item Can Become Its Own UI State

    
    									const ItemStatus = (props) => (
    	<OfflineContext.Consumer>
    		{({ offline }) => (
    			<>
    				<ListItem {...props} />
    				{offline ? <RetryButton {...props} /> : null}
    			</>
    		)}
    	</OfflineContext.Consumer>
    );
    
    								
  20. 20

    Small Pieces Beat Giant Checklists

    Offline work can start with incremental components:

    • connection state
    • local drafts
    • retry affordances
    • stale data messages
    • service worker caching
  21. 21

    The Pitch

    Talking about PWAs can be too broad. Talking about small pieces of the user experience makes the work easier to explain, scope, and ship.

  22. 22

    The Point

    Tell users what happened. Preserve their work. Let them continue when the connection returns.