Migrate OneCX App from Angular 18 to Angular 19

Overview

This guide provides comprehensive step-by-step instructions for migrating OneCX applications from Angular 18 to Angular 19. As part of upgrading to Angular 19, you must update your OneCX UI libraries to version 6. This library update is not a standalone migration but a required part of the Angular version upgrade process, as OneCX v6 libraries provide Angular 19 compatibility and include necessary breaking changes.

Prerequisites

Before starting this migration:

  • Your OneCX application is currently running on Angular 18

  • You have OneCX UI libraries v5.x installed

  • You have a working development environment

Migration Steps before upgrading to Angular 19

To simplify the migration process, it is recommended to complete the following steps before upgrading to Angular 19:

Remove @onecx/keycloak-auth

In v6 of libs, the @onecx/keycloak-auth package has been removed and replaced with @onecx/angular-auth.

Update the packages

  1. Uninstall the deprecated package:

    npm uninstall --save @onecx/keycloak-auth
  2. Install the @onecx/angular-auth package (if not already installed):

    ng add @onecx/angular-auth

Update module imports

  • Replace all imports of KeycloakAuthModule from '@onecx/keycloak-auth' with AngularAuthModule from @onecx/angular-auth.

  • Replace KeycloakAuthModule with AngularAuthModule.

Example:

Before
import { KeycloakAuthModule } from '@onecx/keycloak-auth';

@NgModule({
  imports: [
    KeycloakAuthModule
  ]
})
export class AppModule {}
After
import { AngularAuthModule } from '@onecx/angular-auth';

@NgModule({
  imports: [
    AngularAuthModule
  ]
})
export class AppModule {}

Remove @onecx/portal-layout-styles

In libs version 6, the @onecx/portal-layout-styles package is no longer available and global portal styles are no longer provided.

1. Uninstall the deprecated package:

npm uninstall --save @onecx/portal-layout-styles

2. Update style imports and references:

  • Remove all references to @onecx/portal-layout-styles from your application

  • Implement replacement styles in your component or global styles

Example:

Removed References (in styles.scss)
@import '@onecx/portal-layout-styles/src/styles/shell/shell.scss';
@import '@onecx/portal-layout-styles/src/styles/primeng/theme-light.scss';

3. Expose styles.css if required:

If your application needs to share styles between components, update your build configuration to expose styles.css at the application root. The shell expects this file to be accessible as styles.css at the top level of your deployed application.

For NX Application Styles:

It is recommended to modify the project.json file to include the following styles configuration:

project.json
"styles": [
  {
    "input": "./src/styles.scss",
    "bundleName": "styles",
    "inject": true
  }
]

Setting the inject property to true may result in a hashed filename, such as styles.HASH.css, where HASH is generated during the build. If your application requires a predictable filename, ensure the exposed file does not include the hash.

To avoid hashed filenames, you can update the package.json:

package.json
"scripts": {
  "build": "nx build && cp dist/name-of-your-ui/styles.*.css dist/name-of-your-ui/styles.css"
}

Build the project and verify that styles.css is present in the dist folder without a hash in its name.

For Angular CLI Application Styles:

It is recommended to modify the package.json file to include the following styles configuration (my-project-name should be replaced with your modified project):

package.json
{
  "scripts": {
      "postbuild": "mv \"$(find dist/my-project-name -maxdepth 1 -type f -name 'styles.*.css' | head -n 1)\" dist/my-project-name/styles.css",
  }
}

Update FilterType Value

In OneCX v6, two FilterType enum values were renamed.

Update values:

  • FilterType.EQUALFilterType.EQUALS

  • FilterType.TRUTHYFilterType.IS_NOT_EMPTY

Example:

Before
columns: [
  {
    id: 'amount',
    columnType: ColumnType.NUMBER,
    nameKey: 'FEATURE_SEARCH.RESULTS.AMOUNT',
    filterable: true,
    filterType: FilterType.EQUAL,
  }
  {
    id: 'available',
    columnType: ColumnType.STRING,
    nameKey: 'FEATURE_SEARCH.RESULTS.AVAILABLE',
    filterable: true,
    filterType: FilterType.TRUTHY,
  },
]
After
columns: [
  {
    id: 'amount',
    columnType: ColumnType.NUMBER,
    nameKey: 'FEATURE_SEARCH.RESULTS.AMOUNT',
    filterable: true,
    filterType: FilterType.EQUALS,
  }
  {
    id: 'available',
    columnType: ColumnType.STRING,
    nameKey: 'FEATURE_SEARCH.RESULTS.AVAILABLE',
    filterable: true,
    filterType: FilterType.IS_NOT_EMPTY,
  },
]

Migration Steps after upgrading to Angular 19

Once you have completed the previous steps, you can continue with the Angular 19 upgrade and follow the remaining steps:

Required Package Updates

If the following packages are used in your project, update them to ensure compatibility with Angular 19:

Package Required Version Notes

@ngx-translate/core

^16.0.0

Updated for Angular 19 compatibility

@ngx-translate/http-loader

^8.0.0

Compatible with @ngx-translate/core v16

ngx-build-plus

^19.0.0

Angular 19 compatible version

Installation Commands

Run these commands to update the supporting packages:

# Update translation packages
npm install @ngx-translate/core@^16.0.0
npm install @ngx-translate/http-loader@^8.0.0

# Update build tools
npm install ngx-build-plus@^19.0.0

Remove PortalCoreModule

In OneCX v6, PortalCoreModule has been replaced with AngularAcceleratorModule.

Update imports:

  • Replace all imports of PortalCoreModule from '@onecx/portal-integration-angular' with AngularAcceleratorModule from @onecx/angular-accelerator.

  • Replace PortalCoreModule (also PortalCoreModule.forRoot(), PortalCoreModule.forMicroFrontend()) with AngularAcceleratorModule.

Example:

Before
import { PortalCoreModule } from "@onecx/portal-integration-angular";

@Component({
  standalone: true,
  imports: [PortalCoreModule]
})
After
import { AngularAcceleratorModule } from "@onecx/angular-accelerator";

@Component({
  standalone: true,
  imports: [AngularAcceleratorModule]
})

Replace BASE_URL injection token

In OneCX v6, BASE_URL injection token has been removed and replaced by REMOTE_COMPONENT_CONFIG. Additionally the type of injection token has changed from string to RemoteComponentConfig for REMOTE_COMPONENT_CONFIG token. RemoteComponentConfig type contains the base url.

Update imports:

  • For each remote component replace BASE_URL import from @onecx/angular-remote-components with REMOTE_COMPONENT_CONFIG import from @onecx/angular-utils

  • For each remote component update import REMOTE_COMPONENT_CONFIG from @onecx/angular-remote-components to @onecx/angular-utils

  • For each remote component update import for RemoteComponentConfig from @onecx/angular-remote-components to @onecx/angular-utils

Update component code:

  • Replace BASE_URL in component’s providers array to REMOTE_COMPONENT_CONFIG

  • Replace BASE_URL in component’s constructor injection to REMOTE_COMPONENT_CONFIG

  • Replace BASE_URL type ReplaySubject<string> to REMOTE_COMPONENT_CONFIG type ReplaySubject<RemoteComponentConfig>

Example:

Before
import { BASE_URL } from "@onecx/angular-remote-components";

@Component({
  providers: [
    {
      provide: BASE_URL,
      useValue: new ReplaySubject<string>(1)
    }
  ]
})
export class Example {
  constructor(
    @Inject(BASE_URL) private readonly baseUrl: ReplaySubject<string>
  )
}
After
import { REMOTE_COMPONENT_CONFIG, RemoteComponentConfig } from "@onecx/angular-utils";

@Component({
  providers: [
    {
      provide: REMOTE_COMPONENT_CONFIG,
      useValue: new ReplaySubject<RemoteComponentConfig>(1)
    }
  ]
})
export class Example {
  constructor(
    @Inject(REMOTE_COMPONENT_CONFIG) private readonly remoteComponentConfig: ReplaySubject<RemoteComponentConfig>
  )
}