Frontend Development

Setup

Requires Node.js and Yarn — see frontend/package.json’s engines field (enforced by .yarnrc’s engine-strict) and the supported runtime matrix for the minimum and why. The app is built with Vite (dev server, bundler) and tested with Vitest + Playwright.

cd frontend
cp .env.example .env  # set VITE_API_URL if backend isn't on localhost:8080
yarn install

Running Locally

yarn start  # Vite dev server on port 7300

Hot reload is enabled. The dev server proxies nothing so requests go directly to VITE_API_URL.

Adding a New Page

  1. Create src/pages/FooPage.tsx.
  2. Add a route in the router (typically in App.tsx).
  3. Add a custom hook in src/hooks/useFoo.ts for data fetching (see pattern below).
  4. Add an API module in src/api/foo.ts if needed.

API Client

All requests go through src/api/client.ts. It handles:

  • httpOnly cookie auth (credentials: 'include', no Authorization header)
  • Configurable timeout via VITE_REQUEST_TIMEOUT (default 30s)
  • Automatic redirect to /login on 401
  • Structured ApiError with code and details fields

Call the client from API modules, not directly from components.

Custom Hooks

Hooks in src/hooks/ encapsulate data fetching. Hooks own their loading/error state. Components call refetch() after mutations.

Components

Reusable components live in src/components/. They are MUI-based and receive data via props and do not fetch data themselves. Dialog components manage their own open/close state when passed an open prop and onClose callback.

Translations

All user-facing strings must be translated. Add keys to both src/i18n/locales/en.json and de.json. Do not hardcode English strings in components.

Testing

The frontend has two test layers: vitest unit/component tests co-located in src/ (mocked network, no browser) and Playwright E2E tests against a running application in e2e/. Which layer a test belongs to is decided in Testing — the explicit test pyramid.

Performance budgets

Client performance budgets (bundle size, network-graph render ceiling, list at scale, search debounce) are defined in Web performance budgets (issue #556). Deterministic metrics are hard CI gates; wall-clock is a trend. The bundle-size budget runs per-PR (yarn build && yarn budget); the seeded/large Playwright specs are tagged @perf-heavy and run in the nightly e2e-tests.yml schedule only (RUN_PERF_HEAVY=1).


Back to top

Mycorrhizal CRM - Self-hosted personal contact management

This site uses Just the Docs, a documentation theme for Jekyll.