@ngx-meta/core
Version:
Dynamic page title & meta tags utility for Angular (w/server-side rendering)
363 lines (291 loc) • 11.6 kB
Markdown
# @ngx-meta/core [](https://www.npmjs.com/package/@ngx-meta/core) [](https://www.npmjs.com/package/@ngx-meta/core)
Dynamic page title & meta tags generator for **Angular**
[](https://circleci.com/gh/fulls1z3/ngx-meta)
[](https://codecov.io/gh/fulls1z3/ngx-meta)
[](https://github.com/facebook/jest)
[](https://conventionalcommits.org)
[](https://angular.io/styleguide)
> Please support this project by simply putting a Github star. Share this library with friends on Twitter and everywhere else you can.
**`@ngx-meta/core`** updates the **page title** and **meta tags** every time the route changes, based on **Angular** app's
route configuration.
- When the **Angular** app uses **server-side** rendering, the meta tags and page titles generated by **`@ngx-meta/core`**
successfully appear on HTML source, due to its platform-free workflow. This allows the SPA to be **crawled and rendered**
by the search engines, as well as **sharing** the website **link** on social networks (facebook, twitter, etc).
- It also supports resolving values [using a `callback` function](#using-a-callback-function) to use a custom logic on the
meta tag contents (`http-get`, [@ngx-translate/core]).
## Table of contents:
- [Getting started](#getting-started)
- [Installation](#installation) - [Examples](#examples) - [Recommended packages](#recommended-packages) - [Adding `@ngx-meta/core` to your project (SystemJS)](#adding-systemjs) - [Route configuration](#route-config)
- [app.module configuration](#appmodule-config)
- [Settings](#settings) - [Setting up `MetaModule` to use `MetaStaticLoader`](#setting-up-staticloader) - [Using a `callback` function](#using-a-callback-function)
- [Set meta tags programmatically](#set-meta-tags-programmatically)
- [Credits](#credits)
- [License](#license)
## <a name="getting-started"> Getting started
### <a name="installation"> Installation
You can install **`@ngx-meta/core`** using `npm`
```
npm install @ngx-meta/core --save
```
### <a name="examples"></a> Examples
- [ng-seed/universal] and [fulls1z3/example-app] are officially maintained projects, showcasing common patterns and best
practices for **`@ngx-meta/core`**.
### <a name="recommended-packages"></a> Recommended packages
The following package(s) have no dependency for **`@ngx-meta/core`**, however may provide supplementary/shorthand functionality:
- [@ngx-config/core]: provides meta settings from the application settings loaded during application initialization
- [@ngx-translate/core]: provides internationalization (i18n) features to retrieve the translated meta settings
### <a name="adding-systemjs"></a> Adding `@ngx-meta/core` to your project (SystemJS)
Add `map` for **`@ngx-meta/core`** in your `systemjs.config`
```javascript
'@ngx-meta/core': 'node_modules/@ngx-meta/core/bundles/core.umd.min.js'
```
### <a name="route-config"></a> Route configuration
Import `MetaGuard` using the mapping `'@ngx-meta/core'` and append `canActivate: [MetaGuard]` or `canActivateChild: [MetaGuard]`
properties to the route definitions at **app.routes** (_considering the app.routes is the route definitions in Angular application_).
Then, add `meta` settings inside the `data` property of routes.
**Note:** meta properties such as `title`, `description`, `author` and `publisher` will be duplicated as `og:title`, `og:description`,
`og:author` and `og:publisher`, so there's no need to declare them again in this context.
#### app.routes.ts
```TypeScript
...
import { MetaGuard } from '@ngx-meta/core';
...
export const routes: Routes = [
{
path: '',
canActivateChild: [MetaGuard],
children: [
{
path: 'home',
component: HomeComponent,
data: {
meta: {
title: 'Sweet home',
description: 'Home, home sweet home... and what?'
}
}
},
{
path: 'duck',
component: DuckComponent,
data: {
meta: {
title: 'Rubber duckie',
description: 'Have you seen my rubber duckie?'
}
}
},
{
path: 'toothpaste',
component: ToothpasteComponent,
data: {
meta: {
title: 'Toothpaste',
override: true, // prevents appending/prepending the application name to the title attribute
description: 'Eating toothpaste is considered to be too healthy!'
}
}
}
]
}
...
];
```
### <a name="appmodule-config"></a> app.module configuration
Import `MetaModule` using the mapping `'@ngx-meta/core'` and append `MetaModule.forRoot({...})` within the imports property
of **app.module** (_considering the app.module is the core module in Angular application_).
#### app.module.ts
```TypeScript
...
import { MetaModule } from '@ngx-meta/core';
...
@NgModule({
declarations: [
AppComponent,
...
],
...
imports: [
...
RouterModule.forRoot(routes),
MetaModule.forRoot()
],
...
bootstrap: [AppComponent]
})
```
## <a name="settings"></a> Settings
You can call the [forRoot] static method using the `MetaStaticLoader`. By default, it is configured to **prepend page titles**
after the **application name** (_if any set_). These **default meta settings** are used when a route doesn't contain any
`meta` settings in its `data` property.
> You can customize this behavior (_and ofc other settings_) by supplying **meta settings** to `MetaStaticLoader`.
The following example shows the use of an exported function (_instead of an inline function_) for [AoT compilation].
### <a name="setting-up-staticloader"></a> Setting up `MetaModule` to use `MetaStaticLoader`
#### app.module.ts
```TypeScript
...
import { MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core';
...
export function metaFactory(): MetaLoader {
return new MetaStaticLoader({
pageTitlePositioning: PageTitlePositioning.PrependPageTitle,
pageTitleSeparator: ' - ',
applicationName: 'Tour of (lazy/busy) heroes',
defaults: {
title: 'Mighty mighty mouse',
description: 'Mighty Mouse is an animated superhero mouse character',
'og:image': 'https://upload.wikimedia.org/wikipedia/commons/f/f8/superraton.jpg',
'og:type': 'website',
'og:locale': 'en_US',
'og:locale:alternate': 'en_US,nl_NL,tr_TR'
}
});
}
...
@NgModule({
declarations: [
AppComponent,
...
],
...
imports: [
...
RouterModule.forRoot(routes),
MetaModule.forRoot({
provide: MetaLoader,
useFactory: (metaFactory)
})
],
...
bootstrap: [AppComponent]
})
```
`MetaStaticLoader` has one parameter:
- **providedSettings**: `MetaSettings` : meta settings (_by default, prepend page titles_)
> :+1: Holy cow! **`@ngx-meta/core`** will update the **page title** and **meta tags** every time the route changes.
### <a name="using-a-callback-function"></a> Using a `callback` function
The `MetaStaticLoader` accepts a **`callback`** function to use a custom logic on the meta tag contents (_http-get, [@ngx-translate/core],
etc._).
> Return type of the **`callback`** function must be **`string`**, **`Observable<string>`** or **`Promise<string>`**.
When a **`callback`** function is supplied, the `MetaService` will try to **retrieve contents** of meta tags (_except `og:locale`
and `og:locale:alternate`_) using the specified **`callback`**. You can customize the behavior for missing/empty values,
directly from the **`callback`** function itself.
#### app.module.ts
```TypeScript
...
import { MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning } from '@ngx-meta/core';
import { TranslateService } from '@ngx-translate/core';
...
export function metaFactory(translate: TranslateService): MetaLoader {
return new MetaStaticLoader({
callback: (key: string) => translate.get(key),
pageTitlePositioning: PageTitlePositioning.PrependPageTitle,
pageTitleSeparator: ' - ',
applicationName: 'APP_NAME',
defaults: {
title: 'DEFAULT_TITLE',
description: 'DEFAULT_DESC',
'og:image': 'https://upload.wikimedia.org/wikipedia/commons/f/f8/superraton.jpg',
'og:type': 'website',
'og:locale': 'en_US',
'og:locale:alternate': 'en_US,nl_NL,tr_TR'
}
});
}
...
@NgModule({
declarations: [
AppComponent,
...
],
...
imports: [
...
RouterModule.forRoot(routes),
MetaModule.forRoot({
provide: MetaLoader,
useFactory: (metaFactory),
deps: [TranslateService]
})
],
...
bootstrap: [AppComponent]
})
```
#### app.component.ts
```TypeScript
...
import { MetaService } from '@ngx-meta/core';
...
@Component({
...
})
export class AppComponent implements OnInit {
...
constructor(private readonly translate: TranslateService,
private readonly meta: MetaService) { }
ngOnInit(): void {
// add available languages & set default language
this.translate.addLangs(['en', 'tr']);
this.translate.setDefaultLang(defaultLanguage.code);
this.translate.use('en').subscribe(() => {
this.meta.setTag('og:locale', 'en-US');
});
}
...
}
```
#### home.routes.ts
```TypeScript
import { Routes } from '@angular/router';
import { HomeComponent } from './home.component';
export const routes: Routes = [
{
path: '',
component: HomeComponent,
data: {
meta: {
title: 'PUBLIC.HOME.PAGE_TITLE',
description: 'PUBLIC.HOME.META_DESC'
}
}
}
];
```
You can find out in-depth examples about the use of **`callback`** function on [ng-seed/universal] and on [fulls1z3/example-app],
which are officially maintained seed projects showcasing common patterns and best practices.
## <a name="set-meta-tags-programmatically"></a> Set meta tags programmatically
```TypeScript
...
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MetaService } from '@ngx-meta/core';
...
@Component({
...
})
export class ItemComponent implements OnInit, OnDestroy {
...
constructor(private readonly meta: MetaService) { }
...
ngOnInit() {
this.item = //HTTP GET for "item" in the repository
this.meta.setTitle(`Page for ${this.item.name}`);
this.meta.setTag('og:image', this.item.imageUrl);
}
ngOnDestroy() {
this.meta.removeTag('property="og:type"');
}
}
```
## <a name="credits"></a> Credits
- [ng2-meta](https://github.com/vinaygopinath/ng2-meta): Dynamic meta tags and SEO in Angular2
## <a name="license"></a> License
The MIT License (MIT)
Copyright (c) 2019 [Burak Tasci]
[@ngx-translate/core]: https://github.com/ngx-translate/core
[ng-seed/universal]: https://github.com/ng-seed/universal
[fulls1z3/example-app]: https://github.com/fulls1z3/example-app
[@ngx-config/core]: https://github.com/fulls1z3/ngx-config/tree/master/packages/@ngx-config/core
[forroot]: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#core-for-root
[aot compilation]: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
[burak tasci]: https://github.com/fulls1z3