mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-28 00:24:19 +00:00
7efa0d9ddd
Operational guides the Claude Code CLI auto-loads. The root file covers the stack, repo map, hard rules (no // comments, the endpoints.ts registry, the openapigen StructAllow allowlist, i18n locales, migrations), Go and frontend conventions, and the make verify gate. frontend/CLAUDE.md covers the React + AntD 6 + Vite setup. Both link to CONTRIBUTING.md and frontend/README.md instead of duplicating them, and every claim was fact-checked against the source.
3.1 KiB
3.1 KiB
frontend/CLAUDE.md
Frontend agent guide. Full detail: frontend/README.md and the root
CONTRIBUTING.md ("Working on the frontend"). This is the short version.
What this is
React 19 + Ant Design 6 + Vite 8 + TypeScript. The Vite config is
vite.config.js (plain JS). Three bundles, each emitted into
internal/web/dist/ and embedded into the Go binary:
index.html— admin panel SPA (entrysrc/main.tsx; react-router under/panel, lazy routes).login.html— login + 2FA (src/entries/login.tsx).subpage.html— public subscription viewer (src/entries/subpage.tsx). The@import alias maps tosrc/.
Data flow
- Server state via TanStack Query (
src/api/, keys insrc/api/queryKeys.ts); invalidate on mutation. WebSocket pushes feed the cache (src/api/websocketBridge.ts). - Local UI state in the page (
useState); shared concerns viasrc/hooks/. Extend an existing hook before adding a global. - Zod (
src/schemas/) is the single source of truth for the xray config model. Infer types withz.infer. Go-side types are mirrored intosrc/generated/bynpm run gen:zod(go run ./tools/openapigen) — do not hand-edit that folder (every file is markedDO NOT EDIT). - xray domain logic (links, defaults, form<->wire adapters) is pure functions in
src/lib/xray/. HTTP goes throughHttpUtilinsrc/utils/index.ts.
Rules
- Ant Design 6 only; no Tailwind/shadcn (a migration was rolled back).
- Function components + hooks only; no class components.
- No
//line comments in committed TS/TSX. HTML comments are fine. - TS strict;
no-explicit-anyis an error. Validate form fields withantdRule(Schema.shape.field, t)from@/utils/zodForm, not inlinez.string(). - New
g.POST/g.GETroute => add it tosrc/pages/api-docs/endpoints.ts, thennpm run gen. - i18n strings live in
internal/web/translation/<locale>.json, NOT underfrontend/, and are shared with the Go backend. A new English key must be added to every locale. Interpolation here uses single braces{var}, not the i18next default{{var}}. - Persian/Arabic (RTL) users are first-class — isolate code identifiers on their own line when writing Persian text in labels/toasts.
- Vite is pinned to an exact version (no
^) — bump deliberately, then verifynpm run devANDnpm run build.
Adding a panel route
src/pages/<page>/<Page>.tsx(kebab folder, PascalCase component).- Register in
src/routes.tsxunder/panel(lazy import). - Add a sidebar link in
src/layouts/AppSidebar.tsxif it needs nav. Only standalone bundles (login/subpage) need a new.html+src/entries/*+rollupOptions.input(invite.config.js) + a Go controller route.
Commands
npm run dev(HMR on :5173, proxies to the Go panel on :2053 — start Go first).npm run typecheck/npm run lint/npm run test/npm run build.npm run gen=gen:zod(Go →src/generated/) +gen:api(build-openapi.mjs→public/openapi.json).- After
npm run build, RESTARTgo run .(see the XUI_DEBUG gotcha in root CLAUDE.md) before checking the panel.