diff --git a/docs/en/UI/Angular/Title-Strategy-Service.md b/docs/en/UI/Angular/Title-Strategy-Service.md
new file mode 100644
index 0000000000..64e94b3e17
--- /dev/null
+++ b/docs/en/UI/Angular/Title-Strategy-Service.md
@@ -0,0 +1,59 @@
+# Title Strategy For Angular
+
+## **ABP has a default title strategy for Angular UI**.
+
+This strategy is based on the title property. Provide a title property when setting a new route.
+
+**Example**
+
+```ts
+{
+ path: 'customers',
+ component: CustomersComponent,
+ title: 'AbpCustomers::Roles'
+},
+```
+
+- It is better to use localized text in the title property. It will be translated by **LocalizationService**.
+- The **`title`** property is already set in **ABP internal packages**.
+
+## How it looks
+
+When you create a new route and provide a **`title`** property, it will look like this **`
| `**
+
+### What is `projectName` and How to Customize
+
+- **`projectName`** is the name of your application. By default, ABP sets a [**`projectName`**](https://github.com/abpframework/abp/blob/f48f78618a326644843c01424b093f0d79448769/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/en.json#L4) for your application. This localization text is added for customization and can be changed for different languages.
+
+### Disable `projectName`
+
+- If you don't want to show **`projectName`** in the title, you can disable it.
+
+**app.module.ts**
+
+```ts
+import { DISABLE_PROJECT_NAME } from '@abp/ng.core';
+
+providers: [
+ ...,
+ { provide: DISABLE_PROJECT_NAME, useValue: true}
+],
+```
+
+- Now only title will be shown.
+
+## Override ABP's Default Title Strategy
+
+**app.module.ts**
+
+```ts
+import { TitleStrategy } from '@angular/router';
+import { YourCustomStrategy } from './title-strategy.service.ts';
+
+providers: [
+ ...,
+ { provide: TitleStrategy, useExisting: YourCustomStrategy },
+],
+```
+
+- You can check [Angular Documentation](https://angular.io/api/router/TitleStrategy) to write a custom **`TitleStrategy`**.
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 8abc246509..d30322e277 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -1188,6 +1188,10 @@
{
"text": "Abp Window Service",
"path": "UI/Angular/Abp-Window-Service.md"
+ },
+ {
+ "text": "Title Strategy",
+ "path": "UI/Angular/Title-Strategy-Service.md"
}
]
},
diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts
index eb475074ce..b77849d44c 100644
--- a/npm/ng-packs/packages/core/src/lib/core.module.ts
+++ b/npm/ng-packs/packages/core/src/lib/core.module.ts
@@ -24,7 +24,7 @@ import { ToInjectorPipe } from './pipes/to-injector.pipe';
import { CookieLanguageProvider } from './providers/cookie-language.provider';
import { LocaleProvider } from './providers/locale.provider';
import { LocalizationService } from './services/localization.service';
-import { OTHERS_GROUP } from './tokens';
+import { DISABLE_PROJECT_NAME, OTHERS_GROUP } from './tokens';
import { localizationContributor, LOCALIZATIONS } from './tokens/localization.token';
import { CORE_OPTIONS, coreOptionsFactory } from './tokens/options.token';
import { TENANT_KEY } from './tokens/tenant-key.token';
@@ -40,12 +40,11 @@ import { DefaultQueueManager } from './utils/queue';
import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider';
import { SORT_COMPARE_FUNC, compareFuncFactory } from './tokens/compare-func.token';
import { AuthErrorFilterService } from './abstracts';
-import { DYNAMIC_LAYOUTS_TOKEN } from "./tokens/dynamic-layout.token";
-import { DEFAULT_DYNAMIC_LAYOUTS } from "./constants";
+import { DYNAMIC_LAYOUTS_TOKEN } from './tokens/dynamic-layout.token';
+import { DEFAULT_DYNAMIC_LAYOUTS } from './constants';
import { AbpTitleStrategy } from './services/title-strategy.service';
import { LocalStorageListenerService } from './services/local-storage-listener.service';
-
const standaloneDirectives = [
AutofocusDirective,
InputEventDebounceDirective,
@@ -201,12 +200,16 @@ export class CoreModule {
IncludeLocalizationResourcesProvider,
{
provide: DYNAMIC_LAYOUTS_TOKEN,
- useValue: options.dynamicLayouts || DEFAULT_DYNAMIC_LAYOUTS
+ useValue: options.dynamicLayouts || DEFAULT_DYNAMIC_LAYOUTS,
},
{
provide: TitleStrategy,
- useExisting: AbpTitleStrategy
- }
+ useExisting: AbpTitleStrategy,
+ },
+ {
+ provide: DISABLE_PROJECT_NAME,
+ useValue: options.disableProjectNameInTitle || false,
+ },
],
};
}
diff --git a/npm/ng-packs/packages/core/src/lib/models/common.ts b/npm/ng-packs/packages/core/src/lib/models/common.ts
index 714f2422c2..704fde958a 100644
--- a/npm/ng-packs/packages/core/src/lib/models/common.ts
+++ b/npm/ng-packs/packages/core/src/lib/models/common.ts
@@ -15,6 +15,7 @@ export namespace ABP {
localizations?: Localization[];
othersGroup?: string;
dynamicLayouts?: Map;
+ disableProjectNameInTitle?: boolean;
}
export interface Child {
diff --git a/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts b/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts
index 4cb351918d..af961794f8 100644
--- a/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts
+++ b/npm/ng-packs/packages/core/src/lib/services/title-strategy.service.ts
@@ -2,21 +2,18 @@ import { Injectable, effect, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { TitleStrategy, RouterStateSnapshot } from '@angular/router';
import { Title } from '@angular/platform-browser';
-import { ConfigStateService } from './config-state.service';
import { LocalizationService } from './localization.service';
+import { DISABLE_PROJECT_NAME } from '../tokens';
@Injectable({
providedIn: 'root',
})
export class AbpTitleStrategy extends TitleStrategy {
protected readonly title = inject(Title);
- protected readonly configState = inject(ConfigStateService);
protected readonly localizationService = inject(LocalizationService);
+ protected readonly disableProjectName = inject(DISABLE_PROJECT_NAME, { optional: true });
protected routerState: RouterStateSnapshot;
- projectName = toSignal(this.configState.getDeep$('localization.defaultResourceName'), {
- initialValue: 'MyProjectName',
- });
langugageChange = toSignal(this.localizationService.languageChange$);
constructor() {
@@ -30,14 +27,22 @@ export class AbpTitleStrategy extends TitleStrategy {
override updateTitle(routerState: RouterStateSnapshot) {
this.routerState = routerState;
- let title = this.buildTitle(routerState);
+ const title = this.buildTitle(routerState);
+
+ const projectName = this.localizationService.instant({
+ key: '::AppName',
+ defaultValue: 'MyProjectName',
+ });
if (!title) {
- this.title.setTitle(this.projectName());
- return;
+ return this.title.setTitle(projectName);
+ }
+
+ let localizedText = this.localizationService.instant({ key: title, defaultValue: title });
+ if (!this.disableProjectName) {
+ localizedText += ` | ${projectName}`;
}
- const localizedTitle = this.localizationService.instant({ key: title, defaultValue: title });
- this.title.setTitle(`${localizedTitle} | ${this.projectName()}`);
+ this.title.setTitle(localizedText);
}
}
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts
index 7d0422ad7d..3e5cecd9ca 100644
--- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts
+++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts
@@ -14,4 +14,5 @@ export * from './check-authentication-state';
export * from './http-context.token';
export * from './others-group.token';
export * from './tenant-not-found-by-name';
-export * from './compare-func.token'
+export * from './compare-func.token';
+export * from './title-strategy-disable-project-name.token';
diff --git a/npm/ng-packs/packages/core/src/lib/tokens/title-strategy-disable-project-name.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/title-strategy-disable-project-name.token.ts
new file mode 100644
index 0000000000..afbee19528
--- /dev/null
+++ b/npm/ng-packs/packages/core/src/lib/tokens/title-strategy-disable-project-name.token.ts
@@ -0,0 +1,3 @@
+import { InjectionToken } from '@angular/core';
+
+export const DISABLE_PROJECT_NAME = new InjectionToken('DISABLE_APP_NAME');
diff --git a/templates/module/angular/projects/dev-app/src/index.html b/templates/module/angular/projects/dev-app/src/index.html
index 067936da71..88a791e8e4 100644
--- a/templates/module/angular/projects/dev-app/src/index.html
+++ b/templates/module/angular/projects/dev-app/src/index.html
@@ -1,13 +1,13 @@
-
+
-
-
- DevApp
-
-
-
-
-
-
-
+
+
+ MyProjectName
+
+
+
+
+
+
+