Skip to main content

πŸ‘¨β€πŸ’» Frontend

The frontend is a React 18 single-page app, written in TypeScript and built with Vite. Mantine provides the UI components, TanStack Router handles routing, and TanStack Query handles server state.

The full tech stack, the development commands (yarn start, yarn test, yarn build) and the code style conventions are documented in apps/frontend/README.md, which lives next to the code. Please read that first β€” this page only covers what it does not: debugging, and how the source tree is laid out.

✨ Code Standards​

We use ESLint and Prettier to keep our code tidy. Before you commit, run yarn lint:error to check your changes and yarn lint:error:fix to apply the automatic fixes β€” the ESLint config enforces Prettier through the prettier/prettier rule, so linting also flags unformatted code. The lint-frontend CI workflow runs the lint, test and build steps on every pull request that touches apps/frontend and fails on anything unclean, so nothing un-linted gets merged.

The repository ships a husky pre-commit hook (apps/frontend/.husky/pre-commit, which runs lint-staged), but it is currently inactive in the monorepo: yarn install runs the prepare script β€” husky install β€” with the working directory set to apps/frontend, which has no .git of its own, so husky exits without registering the hook. Don't rely on it; lint before you commit.

πŸ› Debugging​

React Debug Tool​

React provides a debug tool, which you can download here.

WDYR​

WDYR explains to you why a component re-rendered, by logging the changed props and hooks to the browser console. It is wired up in src/wdyr.ts and only runs in development builds.

Set VITE_APP_WDYR to the literal string true β€” any other value (True, 1, unset) leaves it off. Where you set it depends on how you run the frontend:

  • Local dev server (yarn start) β€” add VITE_APP_WDYR=true to apps/frontend/.env.development.

  • Docker dev stack β€” add VITE_APP_WDYR=true to deploy/compose/.env, then recreate the container so it picks up the new environment:

    docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d frontend

Either way the dev server has to be restarted. WDYR needs its own JSX transform, which vite.config.ts only selects when the variable is set at startup, so flipping it mid-session has no effect.

REST API​

Our REST API is documented with Swagger and ReDoc. Once your development stack is up, both are served from the running instance β€” see Development Installation for the URLs.

πŸ™οΈ Structure​

Everything below is relative to apps/frontend/src.

  • routes holds the pages. Routing is file-based: the path of a file determines its URL. Routes under _protected require a logged-in user, routes under public do not, and __root.tsx is the shell they all render into. routeTree.gen.ts is generated from this folder by the TanStack Router plugin β€” never edit it by hand.
  • Pages should be split up into React components, which you can find in components, grouped by feature.
  • api_client is the API layer. api.ts defines FetchClient, a small wrapper around fetch that attaches the access token and transparently refreshes it on a 401. Around it, one folder per domain (photos, albums, faces, …) exports the TanStack Query hooks the components actually call, named useFetch…Query and use…Mutation.
  • hooks and service contain cross-cutting hooks and helpers, such as authentication and notifications.
  • locales holds the translations, set up in i18n.ts. Translations are contributed through Weblate rather than edited directly.
  • In util you can find miscellaneous functions.