useCollection
Direct MongoDB CRUD for built-app data — the primary, reactive data hook for tables, forms, cards, and persistence.
import { useCollection } from 'flowstack-sdk'The primary data hook — use it for all tables, forms, cards, and data persistence. The agent is NOT involved in data operations. Collection names are auto-prefixed with the site_id by the backend, so pass SHORT names only (e.g. 'transactions', not 'site_abc__transactions'). Reads are reactive: they auto-fetch on mount and re-fetch after mutations; every useCollection instance for the same collection auto-refreshes after a successful write.
Signature
const { documents, count, total, isLoading, error, refresh, insert, update, remove } = useCollection<T>(name, options?)Parameters
| Param | Type | Notes | Description |
|---|---|---|---|
name | string | required | Short collection name (auto-prefixed with site_id by the backend). |
options.filter | Filter<T> | — | MongoDB query filter. |
options.sort | Record<string, 1 | -1> | — | Sort spec, e.g. { date: -1 }. |
options.limit | number | default 50 | Max documents to return (max 500). |
options.skip | number | default 0 | Pagination offset. |
options.layer | 'user' | 'shared' | 'auto' | default 'auto' | Namespace: 'user' is a physically isolated per-user database (already scoped — don't filter by a user key; no other user can read it); 'shared' is one pool every signed-in user can read (app can't insert directly unless the collection is agent_writable) — it is NOT access-controlled per user; 'auto' resolves from the collection's data model. See two-layer-data-model. |
options.refreshOnAgentComplete | boolean | since 0.2.1 | Auto-refresh after an agent write tool (insert_documents/update_documents/insert_app_data/etc.) completes — the reactive bridge for the Reason→Write→Read pattern. |
Returns
| Field | Type | Description |
|---|---|---|
documents | T[] | The fetched documents. |
count | number | Documents returned (≤ limit). |
total | number | Total matching documents (for pagination). |
isLoading | boolean | Fetch in flight. |
error | string | null | Last error message. |
refresh | () => Promise<void> | Manual re-fetch. |
insert | (doc: T | T[]) => Promise<{ inserted_ids: string[] }> | Insert one or many documents. |
update | (filter, update, opts?) => Promise<{ modified_count: number }> | Update matching documents. |
remove | (filter) => Promise<{ deleted_count: number }> | Delete matching documents. |
Examples
Reactive query
function TransactionTable() {
const { documents, isLoading } = useCollection<Transaction>('transactions', {
sort: { date: -1 }, limit: 50, refreshOnAgentComplete: true,
});
if (isLoading) return <div>Loading...</div>;
return (
<table>
<tbody>
{documents.map(row => (
<tr key={row._id}><td>{row.date}</td><td>${row.amount}</td></tr>
))}
</tbody>
</table>
);
}Insert on form submit
const { insert } = useCollection('transactions');
await insert({ ...form, amount: Number(form.amount), created_at: new Date().toISOString() });
// All useCollection('transactions') instances auto-refreshUpdate and delete
const { update, remove } = useCollection('transactions');
await update({ _id: docId }, { $set: { category: 'Food' } });
await remove({ _id: docId });CriticalThe app reads all data with
useCollection (tables, forms, cards, CRUD) — never parse the agent's chat text or messages[] for data, and never use useToolInvocation. Writes happen either via deterministic user actions (insert/update/remove) or via the agent's data_access tools followed by a useCollection read (Reason → Write → Read).Critical`layer: 'shared'` is world-readable. Every signed-in user can read every row; the
_flowstack.user_id field is a filter, not an ACL. Put anything one user must not see from another in layer: 'user' (a physically isolated DB). And note you cannot write into another user's per-user partition — there's no cross-user delivery primitive (no private DMs/notifications today). See two-layer-data-model.See also
usePublicCollection · useAgent · useDatasets · useQuery · two-layer-data-model
Source: README.md#usecollection · Also available in llms-full.txt and registry.json.