Skip to main content

Angular Integration Guide

Primus SaaS UI Components

@primus/ui-core is the zero-dependency base design system. All HTML elements β€” buttons, forms, tables, badges, cards β€” are styled automatically when the CSS is loaded. No classes required for most elements.

@primus/ui-core full reference β†’

Complete guide to integrating Primus UI modules into a new or existing Angular project.

Primus UI Scaffolding (Angular)​

The fastest way to get started is using the Primus CLI to scaffold a new Angular project with everything pre-configured:

npx create-primus-app my-app --template angular
cd my-app
npm install
npm start

This creates a ready-to-use Angular project with Primus UI modules already integrated.

Manual Integration​

If you're adding Primus UI to an existing Angular project, follow these steps:

Requirements​

For Angular 21+:

  • Angular 21.x
  • RxJS 7.x or 8.x
  • TypeScript 5.x+

For Angular 16-20:

  • Angular 16-20
  • RxJS 7.x or 8.x
  • TypeScript 4.x or 5.x

Installation​

Angular 21+:

npm install primus-angular-ui

Angular 16-20:

npm install primus-angular-ui-legacy

Module Setup (NgModule-based)​

For traditional Angular applications using NgModules:

1. Configure main.ts​

Your main.ts file should bootstrap the AppModule:

src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));

2. Set up app.module.ts​

Import and configure PrimusUiModule in your app module:

For Angular 21+ (primus-angular-ui):

src/app/app.module.ts
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { PrimusUiModule } from 'primus-angular-ui';
import { AppComponent } from './app.component';

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
PrimusUiModule.forRoot({
apiBaseUrl: 'http://localhost:5267/api'
})
],
bootstrap: [AppComponent]
})
export class AppModule {}

For Angular 16-20 (primus-angular-ui-legacy):

src/app/app.module.ts
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { PrimusUiModule } from 'primus-angular-ui-legacy';
import { AppComponent } from './app.component';

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
PrimusUiModule.forRoot({
apiBaseUrl: 'http://localhost:5267/api'
})
],
bootstrap: [AppComponent]
})
export class AppModule {}

3. Configure app.component.ts​

Set up your root component to handle Primus module events:

For Angular 21+ (primus-angular-ui):

src/app/app.component.ts
import { Component } from '@angular/core';
import { PrimusAuthResponse } from 'primus-angular-ui';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
statusMessage = 'Connect your Primus backend to see live data.';

onLogin(response: PrimusAuthResponse): void {
this.statusMessage = response?.email
? `Signed in as ${response.email}`
: 'Signed in. You can now load modules.';
}
}

For Angular 16-20 (primus-angular-ui-legacy):

src/app/app.component.ts
import { Component } from '@angular/core';
import { PrimusAuthResponse } from 'primus-angular-ui-legacy';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
statusMessage = 'Connect your Primus backend to see live data.';

onLogin(response: PrimusAuthResponse): void {
this.statusMessage = response?.email
? `Signed in as ${response.email}`
: 'Signed in. You can now load modules.';
}
}

4. Use Primus Components​

Now you can use any Primus component in your templates:

src/app/app.component.html
<primus-login
[socialProviders]="['azure', 'auth0', 'google']"
authEndpoint="/api/auth"
[showEmailLogin]="true"
(onLogin)="onLogin($event)">
</primus-login>

[!NOTE] If you are using the Identity Broker (BFF cookie-based auth), you do not store JWTs in the browser. The broker issues an HttpOnly session cookie. Make sure your frontend uses withCredentials for API calls, and seed the CSRF cookie by calling GET /api/auth/providers before posting to /api/auth/login.

Standalone Setup​

For Angular standalone components (Angular 14+):

1. Configure main.ts​

Use bootstrapApplication with Primus providers:

For Angular 21+ (primus-angular-ui):

src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { providePrimus, providePrimusTheme } from 'primus-angular-ui';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(),
providePrimus({ apiBaseUrl: 'http://localhost:5267/api' }),
providePrimusTheme({ defaultTheme: 'light' })
]
}).catch(err => console.error(err));

For Angular 16-20 (primus-angular-ui-legacy):

src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { providePrimus, providePrimusTheme } from 'primus-angular-ui-legacy';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(),
providePrimus({ apiBaseUrl: 'http://localhost:5267/api' }),
providePrimusTheme({ defaultTheme: 'light' })
]
}).catch(err => console.error(err));

2. Import Components​

Import Primus components directly in your standalone components:

For Angular 21+ (primus-angular-ui):

src/app/app.component.ts
import { Component } from '@angular/core';
import { PrimusLoginComponent } from 'primus-angular-ui';

@Component({
selector: 'app-root',
standalone: true,
imports: [PrimusLoginComponent],
template: `
<primus-login
[socialProviders]="['azure', 'auth0', 'google']"
authEndpoint="/api/auth"
[showEmailLogin]="true">
</primus-login>
`
})
export class AppComponent {}

For Angular 16-20 (primus-angular-ui-legacy):

src/app/app.component.ts
import { Component } from '@angular/core';
import { PrimusLoginComponent } from 'primus-angular-ui-legacy';

@Component({
selector: 'app-root',
standalone: true,
imports: [PrimusLoginComponent],
template: `
<primus-login
[socialProviders]="['azure', 'auth0', 'google']"
authEndpoint="/api/auth"
[showEmailLogin]="true">
</primus-login>
`
})
export class AppComponent {}

Configuration Options​

The PrimusUiModule.forRoot() and providePrimus() functions accept the following configuration:

OptionTypeRequiredDescription
apiBaseUrlstringYesBase URL for your Primus backend API
authToken() => string | nullNoOptional token accessor for non‑BFF JWT flows only

Build a dashboard (Angular)​

This walkthrough works with primus-angular-ui (Angular 21+) or primus-angular-ui-legacy (Angular 16-20). If you are on Angular 16-20, swap the import paths and package name.

[!TIP] Charts use Chart.js. Install it alongside the UI package: npm install chart.js.

1. Define dashboard data​

src/app/app.component.ts
import { Component } from '@angular/core';
import { PrimusChartSeries, PrimusColumn } from 'primus-angular-ui';

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
navItems = [
{ id: 'overview', label: 'Overview', href: '/dashboard' },
{ id: 'transactions', label: 'Transactions', href: '/transactions' }
];
activeNavId = 'overview';

stats = [
{ label: 'Revenue', value: '$98k', delta: '+12%', trend: 'up' },
{ label: 'Active Users', value: '12.4k', delta: '+4%', trend: 'up' },
{ label: 'Churn', value: '2.1%', delta: '-0.3%', trend: 'down' }
];

chartLabels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
chartSeries: PrimusChartSeries[] = [
{ name: 'Revenue', data: [12, 18, 14, 22, 26, 24], color: '#2563eb', fill: true }
];

columns: PrimusColumn[] = [
{ key: 'id', header: 'ID', sortable: true },
{ key: 'status', header: 'Status', sortable: true },
{ key: 'amount', header: 'Amount', sortable: true }
];

rows = [
{ id: 'TX-1001', status: 'completed', amount: '$120.00' },
{ id: 'TX-1002', status: 'pending', amount: '$89.00' },
{ id: 'TX-1003', status: 'failed', amount: '$42.00' }
];
}

2. Compose the layout​

src/app/app.component.html
<primus-layout [sidebar]="true" [header]="true">
<primus-header [title]="'Operations'" [breadcrumbs]="[{ label: 'Home' }, { label: 'Dashboard' }]"></primus-header>
<primus-sidebar [items]="navItems" [activeId]="activeNavId"></primus-sidebar>

<primus-dashboard title="Overview" subtitle="Last 30 days" layout="sidebar-content" [stats]="stats">
<div dashboard-actions>
<primus-button variant="outline">Export</primus-button>
</div>
<div dashboard-sidebar>
<primus-section title="Filters">
<primus-select label="Status" [options]="[{ label: 'All', value: 'all' }, { label: 'Failed', value: 'failed' }]"></primus-select>
</primus-section>
</div>
<div dashboard-content>
<primus-dashboard-grid [columns]="2" [gap]="24">
<primus-line-chart [labels]="chartLabels" [series]="chartSeries"></primus-line-chart>
<primus-activity-feed [items]="[]"></primus-activity-feed>
</primus-dashboard-grid>

<primus-section title="Recent Transactions">
<primus-data-table [columns]="columns" [data]="rows" [selectable]="true" [searchable]="true"></primus-data-table>
</primus-section>
</div>
</primus-dashboard>
</primus-layout>

Next Steps​

Troubleshooting​

Module Not Found Errors​

If you encounter module resolution errors, ensure you have the correct package installed for your Angular version:

  • Angular 21+: primus-angular-ui
  • Angular 16-20: primus-angular-ui-legacy

Component Not Rendering​

Make sure you've:

  1. Imported PrimusUiModule.forRoot() in your app module (NgModule setup)
  2. Or provided providePrimus() in your bootstrap config (Standalone setup)
  3. Imported the Primus components you use into each standalone component (or imported PrimusUiModule)
  4. Imported HttpClientModule or provideHttpClient()

Broker login fails (401/CSRF)​

  • Call GET /api/auth/providers once on app startup to receive the XSRF-TOKEN cookie.
  • Ensure your HTTP client sends cookies (withCredentials: true) and mirrors the token in the X-Primus-CSRF header.