Динамически добавлять мета-описание на основе маршрута в Angular
Я использую Angular 5 для создания небольшого веб-сайта типа брошюры. Пока что у меня настроены маршруты, и заголовок страницы динамически меняется в зависимости от активированного маршрута. Я получил эту работу, используя инструкции в этом блоге: https://toddmotto.com/dynamic-page-titles-angular-2-router-events
В настоящее время я храню свои маршруты и заголовки в app.module.ts как таковой:
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
data: {
title: 'Home'
}
},
{
path: 'about',
component: AboutComponent,
data: {
title: 'About'
}
},
{
path: 'products-and-services',
component: ProductsServicesComponent,
data: {
title: 'Products & Services'
}
},
{
path: 'world-class-laundry',
component: LaundryComponent,
data: {
title: 'World Class Laundry'
}
},
{
path: 'contact',
component: ContactComponent,
data: {
title: 'Contact'
}
},
{
path: '**',
component: NotFoundComponent,
data: {
title: 'Page Not Found'
}
}
])
],
Я хотел бы также хранить там свои метаописания, если добавить их в data:
это будет достаточно просто.
Я извлекаю данные заголовка с помощью следующего кода, который указан в ссылке на блог выше:
ngOnInit() {
this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
})
.filter((route) => route.outlet === 'primary')
.mergeMap((route) => route.data)
.subscribe((event) => {
this.titleService.setTitle(event['title']);
});
}
Итак, мой вопрос, есть ли способ динамически установить мета-описание, используя тот же метод? Если есть способ объединить заголовок страницы и функцию мета-описания, это было бы идеально.
У меня очень ограниченная угловая тренировка, так что это может быть нубийским вопросом. Я больше похож на парня дизайнер /CSS/HTML.
Ответы
Ответ 1
Сначала создайте SEOService или что-то вроде ниже:
import {Injectable} from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
@Injectable()
export class SEOService {
constructor(private title: Title, private meta: Meta) { }
updateTitle(title: string) {
this.title.setTitle(title);
}
updateOgUrl(url: string) {
this.meta.updateTag({ name: 'og:url', content: url })
}
updateDescription(desc: string) {
this.meta.updateTag({ name: 'description', content: desc })
}
После внедрения SEOService в ваш компонент установите метатеги и заголовок в методе OnInit.
ngOnInit() {
this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
})
.filter((route) => route.outlet === 'primary')
.mergeMap((route) => route.data)
.subscribe((event) => {
this._seoService.updateTitle(event['title']);
this._seoService.updateOgUrl(event['ogUrl']);
//Updating Description tag dynamically with title
this._seoService.updateDescription(event['title'] + event['description'])
});
}
Изменение: Для RxJs 6+, который использует оператор трубы
ngOnInit() {
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
}),
filter((route) => route.outlet === 'primary'),
mergeMap((route) => route.data)
)
.subscribe((event) => {
this._seoService.updateTitle(event['title']);
this._seoService.updateOgUrl(event['ogUrl']);
//Updating Description tag dynamically with title
this._seoService.updateDescription(event['title'] + event['description'])
});
}
Затем настройте свои маршруты как
{
path: 'about',
component: AboutComponent,
data: {
title: 'About',
description:'Description Meta Tag Content',
ogUrl: 'your og url'
}
},
ИМХО, это четкий способ работы с мета-тегами. Вы можете легко обновить теги для Facebook и Twitter.
Ответ 2
Title
и Meta
- провайдеры, которые были введены в Angular 4 и должны делать это как на стороне сервера, так и на стороне клиента.
Чтобы создать или обновить тег title
и метатег description
, это:
import { Meta, Title } from '@angular/platform-browser';
...
constructor(public meta: Meta, public title: Title, ...) { ... }
...
this.meta.updateTag({ name: 'description', content: description });
this.title.setTitle(title);
Ответ 3
Угловое решение 6+ и RxJS 6+ для динамически устанавливаемого заголовка при изменении маршрута
Если/когда вы обновитесь до Angular 6, это решение там.
Эта услуга будет:
- Обновить мета-заголовок при изменении маршрута.
- Возможность переопределить заголовок по любым причинам, которые вы хотите.
Создайте/измените ваш SEO/мета сервис следующим образом.
import { Injectable } from '@angular/core';
import { Title, Meta } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class MetaService {
constructor(
private titleService: Title,
private meta: Meta,
private router: Router,
private activatedRoute: ActivatedRoute
) { }
updateMetaInfo(content, author, category) {
this.meta.updateTag({ name: 'description', content: content });
this.meta.updateTag({ name: 'author', content: author });
this.meta.updateTag({ name: 'keywords', content: category });
}
updateTitle(title?: string) {
if (!title) {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) { route = route.firstChild; }
return route;
}),
filter((route) => route.outlet === 'primary'),
mergeMap((route) => route.data)).subscribe((event) => {
this.titleService.setTitle(event['title'] + ' | Site name');
});
} else {
this.titleService.setTitle(title + ' | Site name');
}
}
}
Импортируйте ваш сервис и вызовите его в конструкторе.
app.component.ts
constructor(private meta: MetaService) {
this.meta.updateTitle();
}
И это все еще требует форматировать маршруты, как это.
Маршрут file.ts
{
path: 'about',
component: AboutComponent,
data: {
title: 'About',
description:'Description Meta Tag Content'
}
},
Надеюсь, это поможет вам и другим людям, которые хотят динамически обновлять заголовок/мета в Angular 6.
Ответ 4
Вы можете сделать следующее из Angular (на самом деле для решения требуется только jQuery, а не что-то особенное из Angular)
В конфигурации маршрутизатора:
{
path: 'about',
component: AboutComponent,
data: {
title: 'About',
description: 'Here some description'
}
},
В вашем компоненте:
...
.subscribe((event) => {
this.titleService.setTitle(event['title']);
$('meta[name=description]').attr('content', event['description']);
});
Если вы не хотите использовать jQuery, есть простые функции JavaScript для поиска мета-элементов и изменения их атрибутов (getElementsByTagName и getAttribute). Полный код для альтернативы JavaScript можно найти в этом другом SO-вопросе здесь.
Примечание.. Я также хотел бы сохранить заголовок и описание как частные поля в самих компонентах, а не в конфигурации маршрутизатора. Это позволяет избежать необходимости подписываться на что угодно и оставляет в настройках маршрутизатора только связанные с маршрутизатором вещи.
Ответ 5
Вот соответствующие части из моего проекта. (Угловой 2/4)
приложение-routing.module.ts: Маршруты:
... const appRoutes: Routes = [
{
path: 'path1', loadChildren: './path1#path1Module',
data: {
title: '...',
description: '...',
keywords: '...'
}
},
{
path: 'path2', loadChildren: './path2#path2Module',
data: {
title: '...',
description: '...',
keywords: '...'
}
} ...
app.component.ts (или ваш компонент начальной загрузки):
импорт:
// imports
import { Component, OnInit} from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import { Title,Meta } from '@angular/platform-browser';
конструктор:
// constructor:
constructor(private router: Router,
private route: ActivatedRoute,
private titleService: Title, private meta: Meta) {}
Метод ngOnInit():
ngOnInit() {
this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.route)
.map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
})
.filter((route) => route.outlet === 'primary')
.mergeMap((route) => route.data)
.subscribe((event) => {
this.updateDescription(event['description'], event['keywords'], event['title']);
});
}
метод, который обновляет заголовок и метатеги → вызывается из ngOnInit():
updateDescription(desc: string, keywords: string, title: string) {
this.titleService.setTitle(title);
this.meta.updateTag({ name: 'description', content: desc })
this.meta.updateTag({ name: 'keywords', content: keywords })
this.meta.updateTag({ name: 'og:title', content: title })
this.meta.updateTag({ name: 'og:description', content: desc })
}
Надеюсь, поможет.
Ответ 6
Пожалуйста, перейдите по этой ссылке
[Нажмите здесь] [1] https://angularfirebase.com/lessons/seo-angular-part-1-rendertron-meta-tags/