关于angular:Angular2-SEO-如何操作元描述

Angular2 - SEO - how to manipulate the meta description

Google的搜索结果通过TitleTag和标签显示。
-Tag可通过Angular2编辑,如何在angular2路由器中更改页面标题

剩下的就是描述。

是否可以在angular2中编写指令,以操纵页面部分中的元标记。
因此,根据所选的路线,元描述将更改为:

1
<meta name="description" content="**my description for this route**"/>

从Angular4开始,您可以使用Angular Meta服务。

1
2
3
4
5
6
7
8
9
import { Meta } from '@angular/platform-browser';

// [...]

constructor(private meta: Meta) {}

// [...]

this.meta.addTag({ name: 'robots', content: 'noindex' });


有可能的。我在我的应用程序中实现了它,并在下面提供了描述它的制作方法。

基本思想是使用@angular/platform-browser中的Meta

要动态更改特定的元标记,您必须:

  • 使用removeTag(attrSelector: string) : void删除旧的
    方法。
  • 使用addTag(tag: MetaDefinition, forceCreation?:
    boolean) : HTMLMetaElement
    方法添加新的。
  • 当路由器触发路由更改事件时,您必须这样做。

    注意:实际上,也有必要在index.html的开头具有默认的...,因此在动态设置它之前,已经有一些静态内容。

    我的app-routing.module.ts内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    import 'rxjs/add/operator/filter';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/mergeMap';

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes, Router, NavigationEnd, ActivatedRoute } from '@angular/router';

    import { StringComparisonComponent }  from '../module-string-comparison/string-comparison.component';
    import { ClockCalculatorComponent }  from '../module-clock-calculator/clock-calculator.component';

    import { Title, Meta } from '@angular/platform-browser';

    const routes: Routes = [
      {
        path: '', redirectTo: '/string-comparison', pathMatch: 'full',
        data: { title: 'String comparison title', metaDescription: 'String comparison meta description content' }
      },
      {
        path: 'string-comparison',  component: StringComparisonComponent,
        data: { title: 'String comparison title', metaDescription: 'String comparison meta description content' }
      },
      {
        path: 'clock-time-calculator',  component: ClockCalculatorComponent,
        data: { title: 'Clock time calculator title', metaDescription: 'Clock time calculator meta description content' }
      }
    ];

    @NgModule({
      imports: [ RouterModule.forRoot(routes) ],
      exports: [ RouterModule ]
    })

    export class AppRoutingModule {

      constructor(
        private router: Router,
        private activatedRoute: ActivatedRoute,
        private titleService: Title,
        private metaService: Meta
      ){
        //Boilerplate code to filter out only important router events and to pull out data object field from each route
        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')
        //Data fields are merged so we can use them directly to take title and metaDescription for each route from them
        .mergeMap(route => route.data)
        //Real action starts there
        .subscribe((event) => {
            //Changing title
            this.titleService.setTitle(event['title']);

            //Changing meta with name="description"
            var tag = { name: 'description', content: event['metaDescription'] };
            let attributeSelector : string = 'name="description"';
            this.metaService.removeTag(attributeSelector);
            this.metaService.addTag(tag, false);
        });
      }

    }
  • 可以看出,还有一个附加的data对象字段用于
    每条路线。它包含TitlemetaDescription字符串
    它将用作标题和元标记内容。
  • 在构造函数中,我们过滤掉路由器事件,并订阅过滤
    路由器事件。在那里使用Rxjs,但实际上没有必要使用它。常规if statementsloops可用于流,过滤器和地图。
  • 我们还将数据对象字段与事件合并,以便我们可以轻松地
    使用诸如TitlemetaDescription字符串之类的信息。
  • 我们动态更改...标签。
  • 效果:

    第一部分
    String comparison title and meta description tags

    第二部分
    Clock time calculator title and meta description tags

    实际上,我目前正在使用该解决方案的更高级版本,该版本还使用ngx-translate来显示不同语言的不同标题和元描述。
    完整代码可在angular2-bootstrap-translate-website-starter项目中找到。
    带有ngx-translate解决方案的app-routing.module.ts文件完全存在:app-routing.module.ts。

    也有使用相同解决方案的生产应用程序:http://www.online-utils.com。

    当然,这不是唯一的方法,而且可能会有更好的方法。但是我测试了此解决方案,它可以工作。

    实际上,解决方案与相应的关于更改标题的帖子中的解决方案非常相似:如何在angular2路由器中更改页面标题。

    Angular Meta文档:https://angular.io/docs/ts/latest/api/platform-b??rowser/index/Meta-class.html。实际上,它们的信息不是很丰富,我不得不进行实验并研究真正的.js代码,以使此动态元更改生效。


    我已经开发并发布了@ ngx-meta / core插件,该插件可以在路由级别操作meta标签,并允许在组件构造函数中以编程方式设置meta标签。

    您可以在@ ngx-meta / core github存储库中找到详细说明。同样,源文件可能有助于引入自定义逻辑。


    当前没有开箱即用的解决方案,只有一个开放的问题可以实现它https://github.com/angular/angular/issues/7438。

    您当然可以自己实现诸如title服务之类的东西,只需使用TitleService作为模板

    Title服务类似的Meta服务正在开发中(当前仅是请求请求)。