UI & Pages
The Tailwind + shadcn/ui stack, routing, command palette, and page inventory.
The app is a desktop shell, not a SaaS dashboard kit. React 19 uses Tailwind CSS
v4, shadcn/ui primitives in src/components/ui/, cmdk for the command palette,
and Sonner for toasts. components.json is the starting point when you add a
shadcn component.
Routes and layout
src/App.tsx is a HashRouter with lazy route imports. Hash routing means a
packaged desktop build does not require a web server to rewrite paths. AppShell
owns the custom titlebar, sidebar, command palette, offline banner, and route
fallback; login, registration, password recovery, and /error use
ShellLessLayout instead.
The Showcase block is registered only while showcaseConfig.enabled is true.
/update is registered only while features.autoUpdate is true. Billing's
route exists, but the sidebar and palette entry are hidden until billing is
enabled. Use the existing light/dark/system preference and accent color rather
than adding component-local color modes; see Theming.
Sidebar and command palette
src/components/layout/sidebar-items.ts defines three sidebar groups:
Workspace (Home), a flag-gated Template zone (Showcase and Components),
and Application (Billing when enabled, Logs, Help, Settings, About).
Cmd/Ctrl+K opens the in-window command palette. Its command-source
pattern in src/components/command-palette/command-sources.ts supplies routes,
searchable settings, recent files, and—while enabled—the Showcase catalog. Add
product actions with registerCommandSource(), which returns an unregister
function for the lifetime of that feature.
Page inventory
| Page | Route | What it provides |
|---|---|---|
| Home | /home | Starting surface, quick actions, and Showcase-derived sections while the demo is enabled. |
| Help | /help | Homepage, feedback mailto using SUPPORT_EMAIL, GitHub bug report using REPO_URL, and a Logs shortcut. |
| About | /about | App and system details plus a redacted diagnostics copy action. |
| Update | /update | Manual update check, download, and install; flag-gated. |
| Logs | /logs | The redacted native log surface. |
| Settings | /settings | Searchable, tabbed application preferences. |
| Account | /account | Profile and avatar for an authenticated user. |
| Billing | /billing | Optional Creem plans and entitlement. |
| Error / Not Found | /error, * | Themed recovery and route-fallback pages. |
OnboardingGate runs after the router on first use. Leave EULA_URL empty in
shared/constants.ts to omit a EULA; when it is set, EULA_VERSION determines
whether an existing installation must accept the revised agreement again.
Add a product page
Add a lazy import and route in src/App.tsx. Place it under AppShell
unless it genuinely needs the shell-less layout.
Add a sidebar item to src/components/layout/sidebar-items.ts. Add a
command source or extend an existing one when the page should be searchable.
Add EN and ZH translation keys in the appropriate locale namespace. Keep menu, sidebar, and command labels as keys instead of literal strings.
If external input may open it, add its exact path to NAVIGATION_ROUTES in
src/lib/intents/routes.ts. The allow-list protects deep links,
second-instance arguments, and native menu/tray navigation.
