# Component Replacement
You can replace some ABP components with your custom components.
The reason that you **can replace** but **cannot customize** default ABP components is disabling or changing a part of that component can cause problems. So we named those components as _Replaceable Components_.
## How to Replace a Component
Create a new component that you want to use instead of an ABP component. Add that component to `declarations` and `entryComponents` in the `AppModule`.
Then, open the `app.component.ts` and execute the `add` method of `ReplaceableComponentsService` to replace your component with an ABP component as shown below:
```js
import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum
//...
@Component(/* component metadata */)
export class AppComponent {
constructor(
private replaceableComponents: ReplaceableComponentsService, // injected the service
) {
this.replaceableComponents.add({
component: YourNewRoleComponent,
key: eIdentityComponents.Roles,
});
}
}
```

## How to Replace a Layout
Each ABP theme module has 3 layouts named `ApplicationLayoutComponent`, `AccountLayoutComponent`, `EmptyLayoutComponent`. These layouts can be replaced the same way.
> A layout component template should contain `` element.
The example below describes how to replace the `ApplicationLayoutComponent`:
Run the following command to generate a layout in `angular` folder:
```bash
yarn ng generate component my-application-layout
```
Add the following code in your layout template (`my-application-layout.component.html`) where you want the page to be loaded.
```html
```
Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js
import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents enum for component keys
import { MyApplicationLayoutComponent } from './my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(
private replaceableComponents: ReplaceableComponentsService, // injected the service
) {
this.replaceableComponents.add({
component: MyApplicationLayoutComponent,
key: eThemeBasicComponents.ApplicationLayout,
});
}
}
```
> If you like to replace a layout component at runtime (e.g: changing the layout by pressing a button), pass the second parameter of the `add` method of `ReplaceableComponentsService` as true. DynamicLayoutComponent loads content using a router-outlet. When the second parameter of the `add` method is true, the route will be refreshed, so use it with caution. Your component state will be gone and any initiation logic (including HTTP requests) will be repeated.
### Layout Components

#### How to Replace LogoComponent

Run the following command in `angular` folder to create a new component called `LogoComponent`.
```bash
yarn ng generate component logo --inlineTemplate --inlineStyle
```
Open the generated `logo.component.ts` in `src/app/logo` folder and replace its content with the following:
```js
import { Component } from '@angular/core';
@Component({
selector: 'app-logo',
template: `
`,
})
export class LogoComponent {}
```
Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js
import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { LogoComponent } from './logo/logo.component'; // imported LogoComponent
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents
//...
@Component(/* component metadata */)
export class AppComponent implements OnInit {
constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService
ngOnInit() {
//...
this.replaceableComponents.add({
component: LogoComponent,
key: eThemeBasicComponents.Logo,
});
}
}
```
The final UI looks like below:

#### How to Replace RoutesComponent

Run the following command in `angular` folder to create a new component called `RoutesComponent`.
```bash
yarn ng generate component routes
```
Open the generated `routes.component.ts` in `src/app/routes` folder and replace its content with the following:
```js
import { Component, HostBinding } from '@angular/core';
@Component({
selector: 'app-routes',
templateUrl: 'routes.component.html',
})
export class RoutesComponent {
@HostBinding('class.mx-auto')
marginAuto = true;
get smallScreen() {
return window.innerWidth < 992;
}
}
```
Import the `SharedModule` to the `imports` array of `AppModule`:
```js
// app.module.ts
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
//...
SharedModule
]
)}
```
Open the generated `routes.component.html` in `src/app/routes` folder and replace its content with the following:
```html
```
Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js
import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { RoutesComponent } from './routes/routes.component'; // imported RoutesComponent
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents
//...
@Component(/* component metadata */)
export class AppComponent implements OnInit {
constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService
ngOnInit() {
//...
this.replaceableComponents.add({
component: RoutesComponent,
key: eThemeBasicComponents.Routes,
});
}
}
```
The final UI looks like below:

#### How to Replace NavItemsComponent

Run the following command in `angular` folder to create a new component called `NavItemsComponent`.
```bash
yarn ng generate component nav-items
```
Open the generated `nav-items.component.ts` in `src/app/nav-items` folder and replace the content with the following:
```js
import {
AuthService,
ConfigStateService,
CurrentUserDto,
LanguageInfo,
NAVIGATE_TO_MANAGE_PROFILE,
SessionStateService,
} from '@abp/ng.core';
import { Component, Inject } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import snq from 'snq';
@Component({
selector: 'app-nav-items',
templateUrl: 'nav-items.component.html',
})
export class NavItemsComponent {
currentUser$: Observable = this.configState.getOne$('currentUser');
selectedTenant$ = this.sessionState.getTenant$();
languages$: Observable = this.configState.getDeep$('localization.languages');
get smallScreen(): boolean {
return window.innerWidth < 992;
}
get defaultLanguage$(): Observable {
return this.languages$.pipe(
map(
languages =>
snq(
() => languages.find(lang => lang.cultureName === this.selectedLangCulture).displayName
),
''
)
);
}
get dropdownLanguages$(): Observable {
return this.languages$.pipe(
map(
languages =>
snq(() => languages.filter(lang => lang.cultureName !== this.selectedLangCulture)),
[]
)
);
}
get selectedLangCulture(): string {
return this.sessionState.getLanguage();
}
constructor(
@Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile,
private configState: ConfigStateService,
private authService: AuthService,
private sessionState: SessionStateService
) {}
onChangeLang(cultureName: string) {
this.sessionState.setLanguage(cultureName);
}
navigateToLogin() {
this.authService.navigateToLogin();
}
logout() {
this.authService.logout().subscribe();
}
}
```
Import the `SharedModule` to the `imports` array of `AppModule`:
```js
// app.module.ts
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
//...
SharedModule
]
)}
```
Open the generated `nav-items.component.html` in `src/app/nav-items` folder and replace the content with the following:
```html
```
Open `app.component.ts` in `src/app` folder and modify it as shown below:
```js
import { ..., ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService
import { NavItemsComponent } from './nav-items/nav-items.component'; // imported NavItemsComponent
import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents
//...
@Component(/* component metadata */)
export class AppComponent implements OnInit {
constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService
ngOnInit() {
//...
this.replaceableComponents.add({
component: NavItemsComponent,
key: eThemeBasicComponents.NavItems,
});
}
}
```
The final UI looks like below:

## See Also
- [How Replaceable Components Work with Extensions](./How-Replaceable-Components-Work-with-Extensions.md)
- [How to Replace PermissionManagementComponent](./Permission-Management-Component-Replacement.md)