offline

Keep showing loaded data with no connection, and send queued changes when the network comes back.

Data fetchingClientBuilt onTanStack Query

What it is

@kitr/offline saves the query cache to the device and restores it at boot, so the app shows data with no connection. Changes made offline queue up and run when the network is back. useOffline() drives a status line.

Runs in the browser and in native shells. It keeps data offline, not the app itself: for that, use the web platform's PWA option too.

Install

kitr add offline

First time? Run npm i -g @kitr/kitr once. Inside a project, the global kitr runs your project's own version.

Adds @kitr/offline, its provider, config/offline.ts and VITE_APP_VERSION in .env.example. Every change.

Quick start

Nothing changes in your queries. A query that loaded once is restored before the page renders:

// app/pages/orders.tsx
import { queryFrom, useQuery } from '@kitr/query'

interface Order {
  id: string
  customer: string
  total: number
}

export const ordersQuery = queryFrom({
  key: () => ['orders', 'list'],
  fetch: async (_input, { signal }): Promise<Order[]> => {
    const res = await fetch('https://api.acme.com/orders', { signal })
    return (await res.json()) as Order[]
  },
})

export default function OrdersPage() {
  const { data: orders, isPending, fetchStatus } = useQuery(ordersQuery.options())
  if (isPending) return <p>Loading orders…</p>
  return (
    <>
      {fetchStatus === 'paused' && <p>Offline. Showing the last orders loaded.</p>}
      <ul>
        {orders?.map((order) => (
          <li key={order.id}>
            {order.customer}: ${order.total}
          </li>
        ))}
      </ul>
    </>
  )
}

Load /orders online, go offline, reopen the app. The list shows at once with "Offline. Showing the last orders loaded." When the network returns, it refreshes. Next in the guide: Show cached data with no connection.

Built on

kitr adds the throttled save, the restore at boot, versioned snapshots, mutation replay after a reload and useOffline().

Problems it solves

Further reading