How to build a dashboard in Angular
Building a dashboard in Angular requires a layout with a sidebar, header, and content area, plus lazy-loaded feature modules so the initial bundle stays small. As the creator of CoreUI — an open-source UI framework used by over 500,000 developers — I designed the Angular dashboard template structure that powers thousands of production admin panels worldwide. The key architectural decisions are: a shell component for the layout, lazy-loaded routes for each feature section, and CoreUI Angular components for the UI elements. This structure scales from a simple analytics dashboard to a complex enterprise admin application.
Install CoreUI Angular and set up the project.
ng new my-dashboard --routing --style=scss --standalone
cd my-dashboard
npm install @coreui/angular @coreui/icons-angular
Configure CoreUI providers in app.config.ts:
// app.config.ts
import { ApplicationConfig } from '@angular/core'
import { provideRouter } from '@angular/router'
import { provideAnimations } from '@angular/platform-browser/animations'
import { IconSetService } from '@coreui/icons-angular'
import { routes } from './app.routes'
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideAnimations(),
IconSetService
]
}
Dashboard Layout Component
Create a shell layout with sidebar and header.
// layouts/default-layout/default-layout.component.ts
import { Component } from '@angular/core'
import { RouterOutlet } from '@angular/router'
import {
SidebarModule,
HeaderModule,
ContainerComponent
} from '@coreui/angular'
@Component({
selector: 'app-default-layout',
standalone: true,
imports: [RouterOutlet, SidebarModule, HeaderModule, ContainerComponent],
template: `
<c-sidebar colorScheme="dark" position="fixed">
<c-sidebar-brand routerLink="/">
My Dashboard
</c-sidebar-brand>
<c-sidebar-nav [navItems]="navItems"></c-sidebar-nav>
</c-sidebar>
<div class="wrapper d-flex flex-column min-vh-100">
<app-default-header></app-default-header>
<div class="body flex-grow-1 px-3">
<c-container breakpoint="lg" class="h-auto">
<router-outlet />
</c-container>
</div>
</div>
`
})
export class DefaultLayoutComponent {
navItems = [
{ title: true, name: 'Main' },
{ name: 'Dashboard', url: '/dashboard', iconComponent: { name: 'cil-speedometer' } },
{ name: 'Users', url: '/users', iconComponent: { name: 'cil-user' } },
{ name: 'Analytics', url: '/analytics', iconComponent: { name: 'cil-chart' } },
{ divider: true },
{ name: 'Settings', url: '/settings', iconComponent: { name: 'cil-settings' } }
]
}
CoreUI’s c-sidebar and c-sidebar-nav components render a fully functional collapsible sidebar from the navItems array. No manual HTML needed for the navigation structure.
Lazy-Loaded Routes
Configure routes with lazy loading for each dashboard section.
// app.routes.ts
import { Routes } from '@angular/router'
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component'
import { authGuard } from './guards/auth.guard'
export const routes: Routes = [
{
path: '',
component: DefaultLayoutComponent,
canActivate: [authGuard],
children: [
{
path: 'dashboard',
loadComponent: () => import('./views/dashboard/dashboard.component')
.then(m => m.DashboardComponent)
},
{
path: 'users',
loadChildren: () => import('./views/users/routes')
.then(m => m.USERS_ROUTES)
},
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
}
]
},
{
path: 'login',
loadComponent: () => import('./views/login/login.component')
.then(m => m.LoginComponent)
}
]
loadComponent for single-page views and loadChildren for multi-route feature areas keep each section in its own bundle, dramatically reducing initial load time for large dashboards.
Stats Cards Component
Display KPI metrics with CoreUI cards.
// views/dashboard/dashboard.component.ts
import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { CardModule, GridModule, ProgressModule } from '@coreui/angular'
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [CommonModule, CardModule, GridModule, ProgressModule],
template: `
<c-row>
<c-col *ngFor="let stat of stats" sm="6" xl="3">
<c-card class="mb-4">
<c-card-body>
<div class="fs-4 fw-semibold">{{ stat.value }}</div>
<div>{{ stat.label }}</div>
<c-progress class="mt-3" [value]="stat.progress"></c-progress>
</c-card-body>
</c-card>
</c-col>
</c-row>
`
})
export class DashboardComponent {
stats = [
{ label: 'Users', value: '9,828', progress: 75 },
{ label: 'Income', value: '$6,200', progress: 60 },
{ label: 'Orders', value: '2,371', progress: 43 },
{ label: 'Growth', value: '18%', progress: 18 }
]
}
Best Practice Note
This is the exact architecture used in CoreUI’s Angular Admin Template, which provides a complete production-ready starting point with authentication, routing, and a rich component library already wired together. For teams building enterprise dashboards, starting from the CoreUI template saves weeks of setup. See how to integrate Angular with REST API to connect your dashboard to real data.



