Open Closed

ABP Upgrade from 8 to 10 , Angular replaceAbpComponents method is stil working or not #10591


User avatar
0
DominaTang created

Our Angular app.component.ts has code call, but actually now we got a blank header and Abp's default footer. It seems the replacement not working anymore this.replaceableComponents.add({ component: BreadcrumbComponent, key: eThemeLeptonXComponents.Breadcrumb, }); ... this.replaceableComponents.add({ component: AppSettingsComponent, key: eThemeLeptonXComponents.Footer, });

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

12 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • replaceableComponents.add(...) is still the correct mechanism in ABP v10 Angular; it did not get removed.
    • What did change (and commonly breaks upgrades) is the LeptonX component keys for the Side Menu Layout. If you upgraded from v8 to v10 and now see a blank header / default footer, your replacements are most likely registered with old keys, so ABP can’t match them and falls back to theme defaults.
    1. Fix key changes for LeptonX Side Menu Layout
    • In newer LeptonX versions, these keys were swapped/renamed:
      • eThemeLeptonXComponents.Navbar changed to eThemeLeptonXComponents.Toolbar
      • eThemeLeptonXComponents.Sidebar changed to eThemeLeptonXComponents.Navbar

    So if your “header” customization was targeting the old Navbar key, it will no longer be used. Update your registration to the correct key(s) used by your layout.

    1. Keep using Footer/Breadcrumb replacement, but ensure you target the right layout/keys
    • Your examples:
    this.replaceableComponents.add({
        component: BreadcrumbComponent,
        key: eThemeLeptonXComponents.Breadcrumb,
      });
    
      this.replaceableComponents.add({
        component: AppSettingsComponent,
        key: eThemeLeptonXComponents.Footer,
      });
    

    are still conceptually correct, but after upgrading you must ensure:

    • you’re using the current eThemeLeptonXComponents enum from the LeptonX theme package version you’re on
    • the layout you actually run includes those replaceable slots (ApplicationLayout vs SideMenuLayout can differ)
    • you also updated any header-related registrations to the new Toolbar/Navbar keys as noted above
    1. Use the official LeptonX “Customization” map as the source of truth
    • Re-check the current list of replaceable component keys and which layout uses them, then align your key: values with that list.

    Links (validated):

    • https://abp.io/docs/latest/release-info/migration-guides/abp-7-0
    • https://docs.abp.io/en/commercial/latest/themes/lepton-x/angular#customization
    • https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi

    replaceableComponents.add() is still working in v10, the API hasn't changed.

    Since you're jumping from v8 to v10, there's a good chance the issue is related to the Angular 19 standalone migration rather than the replacement mechanism itself.

    Could you share your app.config.ts, full app.component.ts, and one of your custom components (e.g. BreadcrumbComponent)? Also check if there are any errors in the browser console.

    I'll try to reproduce the issue on my end once I see your setup.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    DominaTang created

    Somehow I made it working. It might because the upgraded component still depends some shared module? Not quite sure (too much code changes). I change it anyway.

    Now I am trying to customize the menu items when click the profile icon on top right corner, but click it nothing happens: import { NAVIGATE_TO_MANAGE_PROFILE } from '@abp/ng.core'; import { UserMenuService } from '@abp/ng.theme.shared'; import { inject, provideAppInitializer } from '@angular/core'; import { Router } from '@angular/router'; import { eUserMenuItems } from '@volosoft/abp.ng.theme.lepton-x';

    // This provider overwrites the right-side user menu when clicking the user profile icon. // ABP 10: The toolbar replacement via replaceableComponents breaks LeptonX rendering, // so we use this approach instead. export const OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS = [ provideAppInitializer(() => { configureUserMenu(); }), ];

    function configureUserMenu() { const userMenu = inject(UserMenuService); const router = inject(Router);

    const navigateToManageProfile = inject(NAVIGATE_TO_MANAGE_PROFILE); return () => { userMenu.removeItem(eUserMenuItems.LinkedAccounts); userMenu.removeItem(eUserMenuItems.SecurityLogs); userMenu.removeItem(eUserMenuItems.AuthorityDelegation); //userMenu.removeItem(eUserMenuItems.Logout); userMenu.removeItem(eUserMenuItems.MyAccount); userMenu.removeItem(eUserMenuItems.ExternalLogins); userMenu.removeItem(eUserMenuItems.Sessions);

    	userMenu.addItems([
    		{
    			id: eUserMenuItems.MyAccount,
    			order: 100,
    			textTemplate: {
    				icon: 'bi bi-sliders',
    				text: 'AbpAccount::MyAccount',
    			},
                action: () =>  router.navigate(['/account/manage']) 
    			//action: () => navigateToManageProfile(),
    		}
    	]);
    };
    

    }

    And in app.config.ts add OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS, to providers list;

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • In ABP v10, you can still customize the user dropdown items via UserMenuService (remove/add/patch).
    • If clicking the profile icon does nothing, it typically means the User Menu UI component isn’t rendering/initializing correctly, not that your addItems() code is wrong.

    Here’s the ABP/LeptonX-supported way to solve it without relying on “custom toolbar hacks”:

    1) Don’t remove and re-add MyAccount; patch it

    In LeptonX, the UI expects certain built-in items to exist. Removing + re-adding with the same id can lead to unexpected behavior depending on when LeptonX builds the dropdown.

    Use patchItem to change the action, and removeItem only for the items you truly want to hide:

    import { inject } from '@angular/core';
    import { Router } from '@angular/router';
    import { ConfigStateService } from '@abp/ng.core';
    import { UserMenuService } from '@abp/ng.theme.shared';
    import { eUserMenuItems } from '@volosoft/abp.ng.theme.lepton-x';
    
    export function configureUserMenu() {
      const userMenu = inject(UserMenuService);
      const router = inject(Router);
      const configState = inject(ConfigStateService);
    
      return () => {
        // Ensure it runs after authentication state exists
        configState.getOne$('currentUser').subscribe(currentUser => {
          if (!currentUser?.isAuthenticated) return;
    
          userMenu.removeItem(eUserMenuItems.LinkedAccounts);
          userMenu.removeItem(eUserMenuItems.SecurityLogs);
          userMenu.removeItem(eUserMenuItems.AuthorityDelegation);
          userMenu.removeItem(eUserMenuItems.ExternalLogins);
          userMenu.removeItem(eUserMenuItems.Sessions);
    
          userMenu.patchItem(eUserMenuItems.MyAccount, {
            action: () => router.navigate(['/account/manage']),
          });
        });
      };
    }
    

    Then register it via provideAppInitializer the way you already do.

    2) If the dropdown still doesn’t open: replace the correct UI slot (CurrentUser)

    LeptonX documents that the User Menu is part of the CurrentUser component area (toolbar, top-right). If that component is broken or not matching after upgrade, you should replace that slot (not Toolbar/NavItems etc.):

    this.replaceableComponents.add({
      component: YourNewCurrentUserComponent,
      key: eThemeLeptonXComponents.CurrentUser,
    });
    

    This is the official LeptonX Lite guidance and applies conceptually to LeptonX Angular customization as well.

    3) Keep the “Manage Profile” navigation override approach if needed

    If your goal is only changing where “My Account” goes, ABP also supports overriding the NAVIGATE_TO_MANAGE_PROFILE token instead of rewriting menu items (this avoids timing issues after login).

    Sources

    • https://abp.io/docs/latest/ui-themes/lepton-x-lite/angular
    • https://docs.abp.io/en/commercial/latest/themes/lepton-x/angular#customization
    • https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    DominaTang created

    I tried your code, when click the profile icon, it shows ABP 10's items:

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • What you’re seeing (all default ABP 10 items still present) means your UserMenuService modifications are not being applied at the right time (or they get reset/rebuilt after you apply them). This is a known timing issue especially around login/tenant context changes.

    Apply the customization when currentUser becomes authenticated (not only in an app initializer), and do it idempotently (so it can safely run multiple times):

    import { inject, Injectable } from '@angular/core';
    import { ConfigStateService } from '@abp/ng.core';
    import { UserMenuService } from '@abp/ng.theme.shared';
    import { eUserMenuItems } from '@volosoft/abp.ng.theme.lepton-x';
    import { Router } from '@angular/router';
    
    @Injectable({ providedIn: 'root' })
    export class UserMenuCustomizer {
      private applied = false;
    
      private configState = inject(ConfigStateService);
      private userMenu = inject(UserMenuService);
      private router = inject(Router);
    
      init() {
        this.configState.getOne$('currentUser').subscribe(u => {
          if (!u?.isAuthenticated) {
            this.applied = false;
            return;
          }
    
          if (this.applied) return;
          this.applied = true;
    
          [
            eUserMenuItems.LinkedAccounts,
            eUserMenuItems.SecurityLogs,
            eUserMenuItems.AuthorityDelegation,
            eUserMenuItems.ExternalLogins,
            eUserMenuItems.Sessions,
          ].forEach(i => this.userMenu.removeItem(i));
    
          this.userMenu.patchItem(eUserMenuItems.MyAccount, {
            action: () => this.router.navigate(['/account/manage']),
          });
        });
      }
    }
    

    Register it (your existing provideAppInitializer is fine, but call the service’s init() so it subscribes and runs at the right moment):

    import { provideAppInitializer, inject } from '@angular/core';
    import { UserMenuCustomizer } from './user-menu-customizer';
    
    export const OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS = [
      provideAppInitializer(() => {
        inject(UserMenuCustomizer).init();
      }),
    ];
    

    This avoids the “run too early” problem and ensures the changes are applied once right after login.

    Notes:

    • Prefer patchItem(eUserMenuItems.MyAccount, ...) over removing + re-adding MyAccount.
    • If you still see defaults, it’s because something is rebuilding the menu after your code runs; the subscription-based approach above is the most reliable way to re-apply after authentication.

    (Also: I can’t access ABP’s indexed GitHub repos right now due to an upstream Cloudflare tunnel error from the SourceBot code-search service, so I can’t provide verified source-code links for the internal rebuild timing. The official docs below cover UserMenuService usage.)

    Sources (validated)

    • https://abp.io/docs/10.0/framework/ui/angular/theming
    • https://docs.abp.io/en/commercial/latest/themes/lepton-x/angular#customization
    • https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    DominaTang created

    still the same.

    my app.config.ts

    provideRouter(APP_ROUTES), APP_ROUTE_PROVIDER, provideSideMenuLayout(), provideThemeLeptonX(), OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS, FOOTER_PROVIDER,

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • Your OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS is correctly placed in app.config.ts.
    • The reason you still see the default ABP v10 items is: with LeptonX Angular, the toolbar/user context menu is not driven only by UserMenuService in all cases. The LeptonX user dropdown (“context menu”) can be built from LeptonX’s own userActionGroups (coming from the LeptonX toolbar container / user profile service), so removing items via UserMenuService won’t affect what that LeptonX context menu renders.

    Fix (definitive): Replace the LeptonX user menu UI (CurrentUser/Toolbar) and render your own menu

    ABP’s own LeptonX Lite docs explicitly say the user menu is customizable by replacing the CurrentUser slot:

    this.replaceableComponents.add({
      component: YourNewCurrentUserComponent,
      key: eThemeLeptonXComponents.CurrentUser,
    });
    

    So the reliable solution in v10 is to replace the component that renders the dropdown, and inside it, you can show whatever items you want (only Logout, etc.). This bypasses the mismatch between UserMenuService and LeptonX context menu groups.

    If you want to keep LeptonX toolbar but customize the profile dropdown, ABP support guidance also uses Toolbar replacement (replace eThemeLeptonXComponents.Toolbar with a custom toolbar container that renders the context menu). That approach is consistent with what you already discovered (creating your own dropdown).

    What to do in your project

    1. Keep provideSideMenuLayout() + provideThemeLeptonX() as-is.
    2. Stop relying on UserMenuService.removeItem(...) for LeptonX’s profile dropdown.
    3. Implement a custom toolbar/current-user component (ng-bootstrap dropdown is fine) and register it using component replacement:
      • Prefer eThemeLeptonXComponents.CurrentUser if you only replace the user area.
      • Use eThemeLeptonXComponents.Toolbar if you need broader toolbar control.

    Sources

    • https://abp.io/docs/latest/ui-themes/lepton-x-lite/angular
    • https://docs.abp.io/en/commercial/latest/themes/lepton-x/angular#customization

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    DominaTang created

    We are using LeptonX, not LeptonX Lite. When we upgrade from 8 to 9, we found this: //ABP 9 Upgrade, this replacement doesn't work, use OVERRIDE_LEPTON_X_USER_MENU_PROVIDERS instead /** Right sidebar > user / / this.replaceableComponents.add({ component: AppToolbarContainerComponent, key: eThemeLeptonXComponents.Toolbar, }); */ not sure with ABP 10, replace Toolbar would work or not. Will have a try

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • Yes: in ABP 10 (LeptonX, not Lite), replacing the toolbar via ReplaceableComponentsService is still a supported approach. The replacement mechanism itself did not get removed; the key thing is using the correct replaceable key and providing a component that matches LeptonX’s toolbar/container expectations.
    • The reason your “override menu items via UserMenuService” approach didn’t reflect in the LeptonX profile dropdown is that LeptonX Pro’s profile dropdown is driven by LeptonX’s own user/profile context menu (action groups), not necessarily the same render path as UserMenuService items. In practice, the stable customization point is to replace the toolbar (or current user area) and render your own context menu, exactly like the workaround you described.

    Recommended approach for ABP 10 + LeptonX (Pro)

    1. Create a custom toolbar component (extend LeptonX ToolbarComponent) and adjust what’s shown / behavior.
    2. Create a toolbar container component (extend LeptonX ToolbarContainerComponent) that renders the profile context menu the way you want.
    3. Register it using component replacement:
    import { ReplaceableComponentsService } from '@abp/ng.core';
    import { eThemeLeptonXComponents } from '@volosoft/abp.ng.theme.lepton-x';
    import { MyToolbarContainerComponent } from './my-toolbar-container.component';
    
    constructor() {
      inject(ReplaceableComponentsService).add({
        key: eThemeLeptonXComponents.Toolbar,
        component: MyToolbarContainerComponent,
      });
    }
    

    This is the same pattern Volosoft has recommended in support answers for LeptonX Angular customization (toolbar replacement).

    If you want to customize from LeptonX source

    ABP supports pulling the theme package with source code into your Angular solution:

    abp add-package @volosoft/abp.ng.theme.lepton-x --with-source-code
    

    Then you can customize/override theme assets/components in your project while keeping the rest of ABP intact.

    Sources

    • https://docs.abp.io/en/commercial/latest/themes/lepton-x/angular#customization
    • https://abp.io/docs/latest/UI/Angular/Component-Replacement
    • https://abp.io/support/questions/10449 (shows the toolbar replacement approach for LeptonX Angular, including eThemeLeptonXComponents.Toolbar replacement and custom toolbar/container components)

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    sumeyye.kurtulus created
    Support Team Angular Expert

    Hello,

    After reviewing the issue with replacing the user menu items, it appears that the AI response may have led you in the wrong direction starting from this point:

    https://abp.io/qa/questions/10591/3a20a9c1-487c-9567-8f42-16c1e04f90a9

    Could you try the following approach instead:

    // user-menu.provider.ts
    import { ConfigStateService } from '@abp/ng.core';
    import { UserMenuService } from '@abp/ng.theme.shared';
    import { inject, provideAppInitializer } from '@angular/core';
    import { Router } from '@angular/router';
    import { eUserMenuItems } from '@volosoft/abp.ng.theme.lepton-x';
    
    export const USER_MENU_PROVIDER = [
      provideAppInitializer(async () => {
        configureUserMenu();
      }),
    ];
    export function configureUserMenu() {
      const userMenu = inject(UserMenuService);
      const router = inject(Router);
      const configState = inject(ConfigStateService);
    
      configState.getOne$('currentUser').subscribe(currentUser => {
        if (!currentUser?.isAuthenticated) return;
    
        userMenu.removeItem(eUserMenuItems.LinkedAccounts);
        userMenu.removeItem(eUserMenuItems.SecurityLogs);
        userMenu.removeItem(eUserMenuItems.AuthorityDelegation);
        userMenu.removeItem(eUserMenuItems.ExternalLogins);
        userMenu.removeItem(eUserMenuItems.Sessions);
    
        userMenu.patchItem(eUserMenuItems.MyAccount, {
          action: () => router.navigate(['/account/manage']),
        });
      });
    }
    
    // app.config.ts
    import { USER_MENU_PROVIDER } from './user-menu-provider';
    
    export const appConfig: ApplicationConfig = {
      providers: [
    		//...
        USER_MENU_PROVIDER,
      ],
    };
    

    You can let us know if you need further assistance. Thank you for your cooperation.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    DominaTang created

    thanks, finally we make it works

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.