Persistent Data Reference

Use usePersistentItem as the app's database hook. It is the persistence layer for user data that should survive reloads, sync across devices, and remain private to each user. Browser storage APIs such as localStorage, cookies, and IndexedDB are blocked in the sandbox.

Each app stores data in a user-private key-value JSON document. usePersistentItem reads and writes one key in that document.

usePersistentItem

Import the hook from the persistent item module:

import { usePersistentItem } from "@/hooks/use-persistent-item";

function Controls() {
  const [, setCount] = usePersistentItem<number>("count", 0);

  return (
    <div className="flex gap-2">
      <button onClick={() => setCount((current) => current - 1)}>-</button>
      <button onClick={() => setCount((current) => current + 1)}>+</button>
    </div>
  );
}

export default function App() {
  const [count] = usePersistentItem<number>("count", 0);

  return (
    <div className="space-y-4">
      <h2 className="text-2xl font-semibold">{count}</h2>
      <Controls />
    </div>
  );
}

setValue updates the local UI immediately. Persistence is queued and saved in the background.

Best Practices

  • Choose stable, descriptive keys such as tasks, settings, or generationHistory.
  • Use updater functions when the next value depends on the previous value.
  • Store dates as UTC ISO strings and parse them when displaying.
  • Persist small JSON state. For files, media, and large generated assets, store uploaded or generated URLs instead of raw binary or base64 data.
  • Keep temporary form state in React.useState, then write to usePersistentItem on submit.
  • Update persistent data from event handlers after an awaited action, or from a job's onComplete and onError, instead of mirroring every render through useEffect.
  • Share keys across components intentionally. Accidental key reuse can make unrelated components overwrite each other.