Advanced hooks
Lower-level hooks for use cases the default surface doesn't cover. Import from the /advanced subpath.
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.
const { docApi, error, reload } = useGristReady({ requiredAccess: "read table" })
useEffect(() => {
if (!docApi) return
void docApi.listTables().then(setTables)
}, [docApi])Returns:
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.
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.
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.
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:
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.