Skip to main content
Version: 2.4.0

v0.9.0

Release Date: January 2026

Breaking Changes

@abpjs/core

throwErr renamed to skipHandleError

The Rest.Config.throwErr option has been renamed to skipHandleError for clarity.

Before (v0.8.0):

restService.request({ url: '/api/test', method: 'GET' }, { throwErr: true });

After (v0.9.0):

restService.request({ url: '/api/test', method: 'GET' }, { skipHandleError: true });

@abpjs/identity

IDENTITY_ROUTES format changed

The routes constant now returns an object with a routes property instead of an array directly.

Before (v0.8.0):

import { IDENTITY_ROUTES } from '@abpjs/identity';
// IDENTITY_ROUTES was ABP.FullRoute[]
const routes = IDENTITY_ROUTES;

After (v0.9.0):

import { IDENTITY_ROUTES } from '@abpjs/identity';
// IDENTITY_ROUTES is now { routes: ABP.FullRoute[] }
const routes = IDENTITY_ROUTES.routes;

@abpjs/account

ACCOUNT_ROUTES format changed

Same as identity - now returns { routes: ABP.FullRoute[] }.

// Before: const routes = ACCOUNT_ROUTES;
// After:
const routes = ACCOUNT_ROUTES.routes;

What's New

Settings Layout Type

New eLayoutType.setting value for dedicated settings pages:

import { eLayoutType } from '@abpjs/core';

const route = {
path: '/settings',
layout: eLayoutType.setting,
};

Application Configuration

Configure your application name and logo in the environment config:

import { Config } from '@abpjs/core';

const environment: Config.Environment = {
application: {
name: 'My App',
logoUrl: '/assets/logo.png',
},
production: false,
// ... other config
};

Access via the new selector:

import { selectApplicationInfo } from '@abpjs/core';
import { useSelector } from 'react-redux';

function Header() {
const appInfo = useSelector(selectApplicationInfo);

return (
<header>
{appInfo?.logoUrl && <img src={appInfo.logoUrl} alt={appInfo?.name} />}
<h1>{appInfo?.name}</h1>
</header>
);
}

Tenant Session Management

Session state now includes tenant information with new actions and selectors:

import { setTenant, selectTenant } from '@abpjs/core';
import { useDispatch, useSelector } from 'react-redux';

function TenantSwitcher() {
const dispatch = useDispatch();
const currentTenant = useSelector(selectTenant);

const switchTenant = (tenant: { id: string; name: string }) => {
dispatch(setTenant(tenant));
};

return (
<div>
Current: {currentTenant?.name || 'Host'}
<button onClick={() => switchTenant({ id: '123', name: 'Acme Corp' })}>
Switch
</button>
</div>
);
}

Tenant information is automatically persisted to session storage.


Route Selector

Find routes by path or name with the new selectRoute selector. This is useful for checking route existence or getting route metadata:

import { selectRoute } from '@abpjs/core';
import { useSelector } from 'react-redux';

// Find by path
const usersRoute = useSelector(selectRoute('/admin/users'));

// Find by name
const identityRoute = useSelector(selectRoute(undefined, 'AbpIdentity.Users'));

// Check if route exists
if (usersRoute) {
console.log('Users route found:', usersRoute.name);
}

The selector searches recursively through nested route children.


LocalizationService Enhancement

New currentLang property for quick access to the current language:

const lang = localizationService.currentLang;
// e.g., 'en', 'tr', 'ar'

ProfileService Enhancement

The changePassword method now accepts an optional skipHandleError parameter for custom error handling:

import { ProfileService } from '@abpjs/core';

try {
await profileService.changePassword(
{ currentPassword: 'old', newPassword: 'new' },
true // Skip default error handling
);
} catch (error) {
// Handle error manually (e.g., show "incorrect password" message)
}

The Modal component in @abpjs/theme-shared has new props:

import { Modal } from '@abpjs/theme-shared';

<Modal
visible={visible}
onVisibleChange={setVisible}
busy={isSaving} // Prevents closing while busy
height={500} // Fixed height
minHeight="300px" // Minimum height
onInit={() => loadData()} // Called when modal opens
>
{content}
</Modal>
New PropTypeDescription
busybooleanLoading state - prevents closing when true
heightnumber | stringFixed height for the modal
minHeightnumber | stringMinimum height for the modal
onInit() => voidCalled when modal opens

See @abpjs/theme-shared release notes for full details.


New Package: @abpjs/setting-management

New package for managing application settings with a tabbed interface:

import { SettingLayout, useSettingManagement } from '@abpjs/setting-management';

function SettingsPage() {
const { addSettings } = useSettingManagement();

useEffect(() => {
addSettings([
{ name: 'Account', order: 1, url: '/settings/account' },
{ name: 'Appearance', order: 2, url: '/settings/appearance' },
]);
}, [addSettings]);

return (
<SettingLayout>
<Outlet />
</SettingLayout>
);
}

See @abpjs/setting-management documentation for full details.


New Models in @abpjs/theme-shared

SettingTab - Interface for settings management tabs:

import { SettingTab } from '@abpjs/theme-shared';

const tab: SettingTab = {
name: 'General',
order: 1,
requiredPolicy: 'Settings.General',
url: '/settings/general',
};

Statistics - Models for statistics API:

import { Statistics } from '@abpjs/theme-shared';

const filter: Statistics.Filter = {
startDate: '2026-01-01',
endDate: '2026-01-31',
};

Deprecations

@abpjs/theme-basic

ChangePassword and Profile Components Moved

The ChangePassword and Profile components have been moved to @abpjs/theme-shared.

Before (deprecated):

import { ChangePassword, Profile } from '@abpjs/theme-basic';

After (recommended):

import { ChangePassword, Profile } from '@abpjs/theme-shared';

The old imports will continue to work but are deprecated and will be removed in a future version.


Packages

PackageVersion
@abpjs/core0.9.0
@abpjs/account0.9.0
@abpjs/identity0.9.0
@abpjs/feature-management0.9.0
@abpjs/permission-management0.9.0
@abpjs/setting-management0.9.0 (new)
@abpjs/tenant-management0.9.0
@abpjs/theme-basic0.9.0
@abpjs/theme-shared0.9.0

Upgrade

npm update @abpjs/core @abpjs/account @abpjs/feature-management @abpjs/identity @abpjs/permission-management @abpjs/setting-management @abpjs/tenant-management @abpjs/theme-basic @abpjs/theme-shared

Migration Guide

  1. Update throwErr to skipHandleError: Search for throwErr in your codebase and rename to skipHandleError.

  2. Update route constants usage: IDENTITY_ROUTES, ACCOUNT_ROUTES, and TENANT_MANAGEMENT_ROUTES now use { routes: ABP.FullRoute[] } format. Access routes via .routes property.

  3. Update ChangePassword and Profile imports (recommended): Change imports from @abpjs/theme-basic to @abpjs/theme-shared.