Skip to content

RelationshipFieldCell

RelationshipFieldCell<TData>(props): string | number | bigint | boolean | Element | Iterable<ReactNode, any, any> | Promise<AwaitedReactNode> | null | undefined

Defined in: packages/react/src/fields/relationship/Cell.tsx:43

Relationship field cell for the collection list-view data table.

Reads row.original[fieldKey] which is either:

  • TDocument[] — populated docs when the list query was run with depth: 1.
  • string[] — raw Convex IDs when the query was not depth-populated (fallback).

Rendering rules:

  • 0 docs → em-dash placeholder.
  • 1 doc → resolved preview component (resolveRelationshipPreview precedence: field-level override > target collection’s preview > default). The default renders doc[useAsTitle] ?? doc._id as plain text.
  • 1 docs → "{count} {pluralLabel}" using targetCollection.labels.plural.

  • Unpopulated IDs → "{count} item(s)" fallback.

No hydration gate: renders the same output on the server and on every client render — row.original[fieldKey] comes from useVexListQuery’s TanStack Query result, seeded by the server’s own initialData under the identical query key (CollectionListView.serverParity.test.tsx pins this parity). An earlier isMounted gate here (always rendering — until after mount) was removed: it caused the exact layout shift/visible swap it was meant to avoid, and the SSR-parity infrastructure it predated already guarantees the first client render matches the server’s markup.

TData extends TDocument = TDocument

CellComponentProps<RelationshipField<string, { }, string, ComponentHKT>, TData>

Standard cell component props.

string | number | bigint | boolean | Element | Iterable<ReactNode, any, any> | Promise<AwaitedReactNode> | null | undefined

The resolved preview, an item count, or an em-dash for an empty relationship — identical on server and client.