mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-29 11:18:46 -04:00
3.5 KiB
3.5 KiB
web
Next.js 16 + React 19 + Tailwind frontend. Runs on http://localhost:3000 (yarn dev from root).
Deployed to Vercel.
See README.md for setup, env vars, and Vercel deployment. Cross-package context lives in the root CLAUDE.md.
Layout
web/
├── pages/ Next.js pages (file-based routing). API routes in pages/api/
├── components/ Grouped by feature (profile/, chat/, filters/, ...); generic ones in widgets/
├── hooks/ Custom React hooks (use-*.ts)
├── lib/
│ ├── api.ts Typed API client (calls backend/api)
│ ├── firebase/ Firebase auth + storage SDK config
│ ├── supabase/db.ts Supabase JS client (PostgREST wrapper)
│ ├── locale/ useT() + locale loading
│ └── service/ Analytics, push notifications
├── styles/ Global CSS; everything else is Tailwind utility classes
└── types/ web-only ambient types
Conventions
- Components: many small components over a few large ones. Name the component the same as the file
(
profile-card.tsx→ProfileCard); export it at the top. - Data fetching:
- Server:
api('endpoint', props)insidegetStaticProps/getServerSideProps. - Client:
useAPIGetter('endpoint', props)→{data, refresh}, in-memory cached. - Live updates:
useApiSubscription({topics, onBroadcast}). Topics come frombackend/shared/src/websockets/helpers.ts.
- Server:
- State that should survive navigation: use
usePersistentInMemoryState/usePersistentLocalStateinstead ofuseState. localStorage stores strings — convert back toDateon load. - Styling: Tailwind utilities. Use the design tokens (
bg-canvas-50,text-ink-900, ...) — don't hardcode colors. - i18n:
const t = useT()fromweb/lib/locale, thent('key', 'English fallback'). Translation JSON lives incommon/messages/(de.json,fr.json). English is the inline fallback. - Lodash over hand-rolled loops/Sets (
keyBy,uniq,uniqBy, ...). - Logging:
debug()fromcommon/logger, neverconsole.log. For API failures uselogApiError. - Accessibility primitives already in the codebase:
ErrorBoundary,useLiveRegion(announce(...)),SkipLink/MainContent. Use them rather than rolling your own.
Adding things
- Page: create
pages/<route>.tsx, wrap content in<Page>fromcomponents/page-base. - Component: place under the feature folder (
components/profile/) orcomponents/widgets/if generic. - Hook:
hooks/use-<thing>.ts. Reuse existing hooks before adding new ones. - Translation key: add to
common/messages/{de,fr}.json— see../docs/internationalization.md. - API endpoint: see cross-package recipe in the root CLAUDE.md.
Build / test
yarn --cwd=web serve # next dev on :3000 (yarn dev from root runs this + API)
yarn --cwd=web build # next build
yarn --cwd=web typecheck
yarn --cwd=web lint[-fix]
yarn --cwd=web test [-t "name"]
E2E (Playwright) runs from the root: yarn test:e2e. See ../docs/testing.md.
Related docs
../docs/next-js.md— Next.js patterns we use../docs/react.md— React/TS fundamentals../docs/filters.md— search/filter UI../docs/performance-optimization.md../docs/troubleshooting.md