Angular2 - SEO - 如何操纵元描述

时间:2016-03-07 11:17:16

标签: seo angular meta-tags

谷歌中的搜索结果通过TitleTag和<meta name="description"..."/>标签显示。 <title> - 标记可通过Angular2 how to change page title in angular2 router

进行编辑

剩下的就是描述。

是否可以在angular2中编写一个指令,用于操纵页面<head>部分的元标记。
因此,根据所选路线,元描述会改变如下:

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

4 个答案:

答案 0 :(得分:34)

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

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

// [...]

constructor(private meta: Meta) {}

// [...]

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

答案 1 :(得分:8)

有可能。我在我的应用程序中实现了它,下面我提供了它是如何制作的。

基本想法是使用Meta

中的@angular/platform-browser

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

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

    注意:事实上,还需要在index.html的头部使用默认<title>...</title><meta name="description"..." content="..."/>,因此在动态设置之前,已经存在一些静态内容。

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

    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);
        });
      }
    
    }
    
    1. 可以看出,还有一个额外的data对象字段 每条路线。它包含titlemetaDescription个字符串 这将用作标题和元标记内容。
    2. 在构造函数中,我们过滤掉路由器事件,并订阅过滤 路由器事件。在那里使用Rxjs,但实际上没有必要使用它。常规if statementsloops可以使用流,过滤器和地图。
    3. 我们还将数据对象字段与事件合并,以便我们轻松完成 使用titlemetaDescription字符串等信息。
    4. 我们动态更改<title>...</title><meta name="description"..." content="..."/>代码。
    5. 效果:

      第一个组成部分 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

      当然,这不是唯一的方法,可能有更好的方法。但是我测试了这个解决方案并且有效。

      事实上,解决方案与关于更改标题的相应帖子非常相似:How to change page title in angular2 router

      Angular Meta文档:https://angular.io/docs/ts/latest/api/platform-browser/index/Meta-class.html。事实上,它们并不是非常有用,我不得不进行实验并研究真正的.js代码,以使这种动态元变更起作用。

答案 2 :(得分:5)

我开发并刚刚发布了@ngx-meta/core插件,它在路由级操纵元标记,并允许在组件构造函数中以编程方式设置元标记。

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

答案 3 :(得分:3)

目前没有开箱即用的解决方案只是一个实现它的未解决问题https://github.com/angular/angular/issues/7438

您当然可以自己实施标题服务,只需使用TitleService作为模板

类似于const char服务的Meta服务正在进行中(目前只有拉取请求)。