Skip to content

Advanced hooks ​

Lower-level hooks for use cases the default surface doesn't cover. Import from the /advanced subpath.

ts
import {
  useGristReady,
  useGristAvailability,
  useGristRowsFromTable,
  useGristWidgetOptions,
} from "grist-widget-sdk/advanced"

useGristReady(options?) ​

Runs the grist.ready handshake manually. Useful when you don't want <GristWidgetProvider> — e.g. in a tiny library that just needs docApi.

ts
const { docApi, error, reload } = useGristReady({ requiredAccess: "read table" })

useEffect(() => {
  if (!docApi) return
  void docApi.listTables().then(setTables)
}, [docApi])

Returns:

ts
type UseGristReadyResult = {
  docApi: GristDocApi | null
  error: string | null
  reload: () => Promise<void>
}

Concurrent useGristReady calls coalesce a single grist.ready invocation, but you should still aim for one call per app.

useGristAvailability(options?) ​

Polls for the global grist object until it appears or maxAttempts is reached.

ts
const isAvailable = useGristAvailability({
  maxAttempts: 30,
  intervalMs: 200,
  logWhenNotEmbedded: false,
})

Returns boolean. SSR-safe (returns false outside the browser).

Use this when writing a custom <GristBoundary> replacement.

useGristRowsFromTable<T>(options) ​

Polls a non-section table for changes.

ts
const { rows, refresh, loading, error } = useGristRowsFromTable<MyRow>({
  tableId: "Reports",
  pollIntervalMs: 10_000,
  filter: (row) => row.Status === "open",
  order: "grist",
  columns: schema.columns,        // for decoding
  safeParse: true,                // optional
})

The hook:

  • Reads the table on mount and at every interval.
  • Skips empty intervals when the tab is hidden.
  • Always returns a stable array reference until the underlying data changes.

useGristWidgetOptions<T>(options?) ​

Typed widget options with debounced writes.

ts
const { options, patchOptions, setOptions, reset, loading, error } =
  useGristWidgetOptions<MySettings>({
    defaults: { theme: "light", autoRefresh: false },
    debounceMs: 200,
    namespace: "ui",  // optional: writes to grist.setOption("ui", value) only
  })

Returns:

ts
type UseGristWidgetOptionsResult<T> = {
  options: T
  patchOptions: (patch: Partial<T>) => void
  setOptions: (next: T) => void
  reset: () => void
  loading: boolean
  error: string | null
}

The debounced writer collapses bursts of patchOptions(...) into one Grist call.

When to escape to plain plugin API ​

If you've truly outgrown the SDK, useGrist() exposes docApi and you can call any grist.* method directly. Don't try to recreate the subscription / write paths the SDK already runs — wire your custom call in as a sibling, not a replacement.

Released under the ISC License.