Frontend Development Guide
Status: Current
Last reviewed: 2026-05-13
This guide records frontend rules for nexus-frontend. It is intended for human review and AI-assisted edits.
Stack
- Next.js App Router.
- Tailwind CSS.
- shadcn/ui source components under
src/components/ui. - Lucide icons through
lucide-react. - Local i18n JSON under
src/i18n. - API helpers under
src/lib/api.ts.
Use existing project components and helper functions before adding new patterns.
Layout Rules
- Dashboard pages use the existing sidebar/header shell.
- Page content should fit inside the existing max-width container.
- Prefer dense operational layouts over marketing-style sections.
- Avoid nested cards. Use cards for repeated objects, dialogs, and framed tools only.
- Dialogs need accessible titles and should keep action footers fixed when the form body scrolls.
- Use semantic tokens such as
text-muted-foreground,bg-card,border-border, andtext-foreground.
Table Rules
All data tables should follow one visual system.
Status Column
- Status cells use a single
size-2rounded color dot. - Do not render status text in ordinary table status cells.
- Provide text through
titlefor simple tables such as L3, L4, and upstreams. - On pages that already use a tooltip, such as nodes, the tooltip can provide the status text.
Example:
tsx
<span
title={enabled ? t("common.enabled") : t("common.disabled")}
className={cn(
"block size-2 rounded-full",
enabled ? "bg-emerald-500" : "bg-muted-foreground/40"
)}
/>Name Column
- Do not use
font-mediumin table name cells. - Use default
text-foregroundfor the primary name. - Use
text-muted-foregroundfor secondary metadata columns so hierarchy comes from contrast, not font weight.
Example:
tsx
<TableCell className="text-foreground">{name}</TableCell>Badge Cleanup
Avoid Badge for plain table metadata.
- L4 chains protocol column uses plain
font-mono text-xs. - L4 chains topology column uses plain
font-mono text-xstext. - TLS expiration date uses text, not Badge.
- User status uses text, not Badge.
- Audit action uses text, not Badge.
Use Badge only when the value is truly a label/chip, not routine table text.
Font Size
- Do not use
text-[10px]ortext-[11px]inside tables. - Use
text-xsfor compact table metadata. - Use
text-smonly when a table cell intentionally follows body sizing.
Endpoint Text
L4 upstream endpoint values are not decorated code blocks.
Use:
tsx
<TableCell className="font-mono text-xs text-muted-foreground">
{endpoint}
</TableCell>Do not use <code> with gray background, padding, or rounded block styling for endpoint cells.
Actions
- Use icon buttons for row actions.
- Provide
aria-labelfor icon-only buttons. - Keep destructive actions muted until hover, then use destructive color.
- For multi-action overflow, use
DropdownMenuwith grouped items.
Forms
- Keep labels concise and stable.
- Use
Input,Select,Switch,Tabs,Dialog, andButtonfrom existing UI components. - Preserve required markers for required fields.
- Validate in the frontend when it prevents a known backend error, but keep backend validation authoritative.
- Use
toast.success,toast.warning, ortoast.errorfor submit outcomes.
Copyable Secrets
- Node control PSKs are one-time values. Display them in the creation/reset dialog only.
- Provide copy buttons for secrets, environment blocks, and fingerprints.
- Do not log secret values.
- Make the UI copy block wrap and scroll safely on narrow screens.
i18n
- Add user-facing strings to
src/i18n/en.jsonandzh-CN.jsonwhen touching localized pages. - Prefer existing keys such as
common.create,common.save, andcommon.delete. - Fallback helper functions are acceptable for incomplete translations, but new features should add proper keys.
API Usage
- Use
src/lib/api.tshelpers when available. - Use
getErrorMessagefor toast errors from Axios responses. - Use
unwrapApiDatafor API envelopes when a page needs thedatafield. - Paginated pages should use
usePaginatedApiand the sharedPaginationcomponent.
Accessibility
- Icon-only buttons require
aria-label. - Dialogs require
DialogTitle. - Inputs need labels with
htmlForwhere practical. - Status dots need
titleor tooltip text. - Do not rely on color alone when the state is part of a critical workflow; provide tooltip/title or surrounding context.
Review Checklist
Before merging frontend UI changes:
- Tables follow the status, name, Badge, font-size, and endpoint rules above.
- No table cell uses
text-[10px]ortext-[11px]. - No table name cell uses
font-medium. - Routine metadata is not rendered as Badge.
- Icon buttons have accessible labels.
- New strings are localized.
- Mutating actions show success or error feedback.