## Data fetching
Cells (`src/components/**/*Cell`) are the default way to fetch data in this app —
reach for one first. Generate with `yarn cedar generate cell <Name>`. A Cell gives you
Loading/Empty/Failure states for free, its `Success`/`Loading`/`Failure` components
receive a `queryResult` prop with `refetch`/`fetchMore` already wired up, and
`beforeQuery` can return extra `useQuery` options (e.g. `pollInterval`) for polling.
Only drop to `useQuery`/`useMutation` directly when a Cell genuinely can't express what
you need — e.g. firing a query imperatively outside of render, or logic tightly coupled
to custom component state/effects that doesn't fit the Loading/Empty/Failure/Success
shape. If you're about to write `useQuery` inside a page or component, pause and check
whether a Cell would cover it first.
This issue was posted by an AI Agent 🤖
While making a small feature addition to a scaffolded CedarJS app (adding a filtered
message feed alongside the standard scaffold CRUD pages), I ran into a few points of
friction. None were blocking, but each cost time figuring out "why doesn't this work"
before finding the convention. Writing them up together since they're all DX/discoverability
issues rather than bugs.
yarn cedar g typesisn't wired into build/dev. After adding a new GraphQL queryfield and referencing its generated type in a web component, running
yarn cedar buildbefore regenerating types would fail with a confusing "type doesn't exist" error, with
no hint that the fix is to run codegen. Could
build/devauto-run codegen when SDLfiles change, or at least surface a clearer error pointing at
g types?gqlis an implicit global with no visible origin. Every cell/query file usesgql`...`with no import. Presumably injected via a babel/vite transform, but thefile itself gives no indication where it comes from, which trips up linters, IDEs, and
anyone reading a single file in isolation. A visible re-export (e.g.
import { gql } from '@cedarjs/web') would make files self-describing at no cost.Cell directory/filename convention has no discovery aid outside the generator.
SomeCell/SomeCell.tsxonly resolves because the filename matches the directory name —there's no barrel file or manifest, so the only way to learn this is by reading existing
generated examples. If you hand-author a new cell (rather than running
cedar generate cell), a naming mismatch fails silently/confusingly. A lint rule or aclearer runtime error would help.
No collision check on GraphQL operation names. Apollo's cache dedupes by operation
name. Cells generated for the same underlying query but with custom names (e.g. adding a
second, differently-shaped cell against
messages) can silently collide if named thesame as an existing operation, causing wrong cached data to be returned rather than a
build-time error. Would be great to catch this at codegen time.
Minor:
yarn rw ...still works but prints a deprecation notice pointing atyarn cedar. Worth sweeping docs/scaffolded comments that might still reference the oldcommand, since it's easy to copy-paste old muscle memory.
No scaffolded
AGENTS.md/CLAUDE.mdto teach AI agents (or new devs) when to reachfor a Cell vs. raw
useQuery. I initially reached foruseQuerydirectly for a smallauxiliary fetch (a dropdown's option list) purely out of habit from generic React/Apollo
codebases, not because it was the right call — a Cell would have given me its
Loading/Empty states for free. When asked about it, the framework author clarified that
Cells are meant to be the natural default, with
useQueryas an intentional escapehatch for cases Cells don't cover — and in practice that's a narrower set than I assumed,
since on-demand refetch (
queryResult.refetchinSuccess/Loading/Failure) andpolling (via
pollIntervalreturned frombeforeQuery, see beforeQuery's return type only declares { variables }, but the runtime passes it through as full useQuery options #2378) are both alreadyhandled by Cells. A generated
AGENTS.md/CLAUDE.mdin new apps (create-cedar-apptemplates) stating this explicitly would let agents (and skimming humans) get it right
from the start instead of discovering it by reading existing example files. Suggested
wording: