Step 4: Pin the world
A pinboard is a list of ids in your own state, pointing at documents you don't own.
A pinboard doesn't need new documents — it needs a list of ids pointing at documents that already exist, plus a way to open one. Add a second field to the same shared state, and read the world alongside it:
const { data, actions } = useCollabState({
headline: field.value<string>("Welcome — make this place yours."),
pinnedIds: field.list<string>(),
})
const docs = useWorldQuery("documents")useWorldQuery("documents") is live — it re-renders as the world's catalog changes on
any client, the same way useCollabState is live for the headline. Reading it takes one
declaration: needs: ["world"] on the tool, because needs is your consent
surface — refs and nav are
always present, but reading the world must be asked for.
Pin "Aria of the North" with actions.list("pinnedIds").push(id); open it by resolving
its id through the refs capability and handing the result to nav:
Edit and the example re-runs. Tab indents; press Escape to leave the editor.
You should see: every document in the world listed under the headline, each with a star. Click "Aria of the North" — it fills in and stays filled after you click elsewhere. Click it again to unpin.
A reference, never a copy
pinnedIds holds ids, not documents. Pin "Aria of the North" and you've written one string
into your app's own state — the card itself still lives where it always did, still owned by
whoever owns it, still visible to whoever could see it before. Rename the card in the
editor and the pinned chip's label follows, because it's reading the same row useWorldQuery
already gave you.