Frontend Development
Guide to developing the Patrimoine frontend — a React 19 SPA built with Vite, Tailwind CSS v4, TanStack Query, and react-intl for i18n.
Prerequisites
Section titled “Prerequisites”- Node.js 24
cd frontendnpm ciDev Server
Section titled “Dev Server”npm run devRuns on port 5173. The predev script generates src/generated/version.json
before starting Vite.
Linting
Section titled “Linting”npx oxlint0 warnings and 0 errors must be maintained.
Type Checking
Section titled “Type Checking”npx tsc -b --noEmitTypeScript strict mode is enabled with noUnusedLocals and
noUnusedParameters. See Code Style & Linting
for details.
Testing
Section titled “Testing”npx vitest runOr in watch mode:
npx vitestThe suite contains about 5,000 tests across 372 files. See Testing for setup and helper details.
Building
Section titled “Building”npm run buildThis runs tsc -b && vite build. The prebuild script generates
src/generated/version.json before the build.
Bundle Size
Section titled “Bundle Size”npx size-limitLimits (gzip):
| Chunk | Limit |
|---|---|
| Main bundle (app code + small deps) | 350 KB |
| React vendor (react, react-dom, react-router) | 200 KB |
| Recharts (lazy-loaded with ChartsPage) | 450 KB |
Adding a New Page
Section titled “Adding a New Page”- Create
src/pages/ThingPage.tsx. - Add a lazy import in
App.tsxwrapped in<Suspense>. - Add a route with an
errorElementfallback. - Add the route to the
routePrefetchmap insrc/routePrefetch.ts. - Add the page to
NAV_GROUPS(orEXTRA_PAGES) insrc/components/layout/navItems.ts; the sidebar and the command palette read it, andpaletteCommands.test.tsfails if a route has no command. Add the bottom-nav entry inBottomNav.tsxif it is a primary destination.
Adding a New Hook
Section titled “Adding a New Hook”- Create
src/hooks/useThing.ts. - Follow the TanStack Query pattern used by existing hooks:
- Define a
queryKeyarray. - Use
apiFetchfor the API call. - Set an appropriate
staleTime.
- Define a
- Export the query keys so other components can invalidate the cache.
Adding a New Component
Section titled “Adding a New Component”- Create the component in the appropriate
src/components/subdirectory. - Use the
cn()helper for className merging. - Add a test file in a
__tests__/directory alongside the component.
Internationalization (i18n)
Section titled “Internationalization (i18n)”Add translation keys to all five locale files:
src/locales/fr.jsonsrc/locales/en.jsonsrc/locales/es.jsonsrc/locales/de.jsonsrc/locales/it.json
Use <FormattedMessage id="key" /> in JSX, or useIntl().formatMessage()
in logic.