UNPKG

@ngx-meta/core

Version:

Dynamic page title & meta tags utility for Angular (w/server-side rendering)

363 lines (291 loc) 11.6 kB
# @ngx-meta/core [![npm version](https://badge.fury.io/js/%40ngx-meta%2Fcore.svg)](https://www.npmjs.com/package/@ngx-meta/core) [![npm downloads](https://img.shields.io/npm/dm/%40ngx-meta%2Fcore.svg)](https://www.npmjs.com/package/@ngx-meta/core) Dynamic page title &amp; meta tags generator for **Angular** [![CircleCI](https://circleci.com/gh/fulls1z3/ngx-meta.svg?style=shield)](https://circleci.com/gh/fulls1z3/ngx-meta) [![coverage](https://codecov.io/github/fulls1z3/ngx-meta/coverage.svg?branch=master)](https://codecov.io/gh/fulls1z3/ngx-meta) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) [![Angular Style Guide](https://mgechev.github.io/angular2-style-guide/images/badge.svg)](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