5.9 KiB
//[doc-seo]
{
"Description": "Learn how to customize ABP React UI applications, including pages, themes, sidebar navigation, and the user menu."
}
Customization
The React app generated by ABP is fully owned by your solution. All source code is available, so you can change pages, components, routes, themes, menus, API calls, and layout behavior just like in any other React application.
This page focuses on the main developer-owned React app. The same general approach applies to the public-web React app if your solution includes one. The Admin Console is an ABP-managed administration surface; see Admin Console for details.
General Customization
Application pages live under src/pages/. The template includes practical references:
- Users page: a simple page that lists users and links to the Admin Console for full user and role management.
- Books page: a full CRUD sample when the sample CRUD option is selected during solution creation. It demonstrates TanStack Query, forms, Zod validation, dialogs, tables, permissions, and toast notifications.
Shared UI and infrastructure live under:
src/
├── components/
│ ├── layout/
│ └── ui/
├── lib/
│ ├── api/
│ ├── auth/
│ ├── i18n/
│ ├── routing/
│ └── theme/
└── pages/
Adding a Page
Create a page under src/pages/:
export function ReportsPage() {
return (
<div className="space-y-6">
<h1 className="text-3xl font-bold tracking-tight">Reports</h1>
</div>
)
}
Register it with TanStack Router in src/routes/router.tsx:
const reportsRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/reports',
component: ReportsPage,
beforeLoad: createPermissionGuard('MyProjectName.Reports'),
})
const routeTree = rootRoute.addChildren([
indexRoute,
reportsRoute,
])
Use authGuard for pages that only require authentication and createPermissionGuard for pages that require a permission.
Theming
The React template uses shadcn/ui-style components, Radix UI primitives, Tailwind CSS, and CSS variables.
Theme tokens are defined in src/styles/globals.css:
:root {
--background: oklch(0.978 0.003 264);
--foreground: oklch(0.205 0.008 264);
--primary: oklch(0.48 0.10 278);
--radius: 0.5rem;
}
.dark {
--background: oklch(0.16 0.004 264);
--foreground: oklch(0.92 0.005 264);
--primary: oklch(0.62 0.12 278);
}
ABP Studio's modern wizard can generate different shadcn theme color presets and light/dark/system theme behavior.
Changing Theme Colors
To make a quick theme change, edit the CSS variables in src/styles/globals.css:
:root {
--primary: oklch(0.623 0.188 259.6);
--primary-foreground: oklch(1 0 0);
}
Because the generated shadcn/ui components consume these variables through Tailwind tokens, the change applies across buttons, links, active sidebar entries, focus rings, and other components that use the primary color.
Theme Mode Switcher
Theme mode is handled by src/lib/theme/ThemeProvider.tsx. It supports:
lightdarksystem
The header cycles through the allowed modes:
const THEME_CYCLE: Theme[] = ['light', 'dark', 'system']
function ThemeToggle() {
const { theme, resolvedTheme, setTheme } = useTheme()
function cycleTheme() {
const currentIndex = THEME_CYCLE.indexOf(theme)
const nextIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % THEME_CYCLE.length
setTheme(THEME_CYCLE[nextIndex])
}
return <Button variant="ghost" size="icon" onClick={cycleTheme}>...</Button>
}
To remove the switcher or replace it with a dropdown, edit src/components/layout/Header.tsx.
Modifying the Sidebar Menu
Sidebar navigation is defined in src/lib/routing/route-config.ts.
Add a menu item:
import { BarChart3 } from 'lucide-react'
export const routeConfig: RouteConfigItem[] = [
{
path: '/reports',
nameKey: 'Menu:Reports',
icon: BarChart3,
order: 10,
requiredPolicy: 'MyProjectName.Reports',
},
]
Then add the localization key to src/locales/en.json:
{
"Menu:Reports": "Reports"
}
Use these properties depending on the menu item:
| Property | Use |
|---|---|
path |
Internal route path or logical path for an external item. |
nameKey |
Localization key shown in the sidebar. |
icon |
Optional Lucide icon. |
order |
Sorting order. |
requiredPolicy |
Hide the item unless the permission is granted. |
requiresAuth |
Hide the item unless the user is authenticated. |
externalHref |
Open an external URL or another app, such as the Admin Console. |
children |
Add nested sidebar items. |
Sidebar vs User Menu
Use the sidebar navigation for application pages and module entry points.
Use the user menu for account-specific actions, profile links, sessions, security logs, linked accounts, and logout. The user menu is implemented in src/components/layout/UserMenu.tsx.
Example user menu item:
<DropdownMenuItem asChild className="cursor-pointer">
<a href="/account/preferences">
<Settings className="size-4" />
{t('MyAccount::Preferences')}
</a>
</DropdownMenuItem>
Customizing UI Components
shadcn/ui components are copied into your project under src/components/ui/. They are not black-box components from a package. You can edit them directly.
For example:
- Change button variants in
src/components/ui/button.tsx. - Change dialog structure in
src/components/ui/dialog.tsx. - Add a new reusable component under
src/components/ui/. - Add feature-specific components under
src/components/<feature>/.
Keep generic primitives in components/ui and business-specific components close to the feature or page that owns them.