Angular2 - SEO - 如何操作元描述

Posted

技术标签:

【中文标题】Angular2 - SEO - 如何操作元描述【英文标题】:Angular2 - SEO - how to manipulate the meta description 【发布时间】:2016-06-20 22:03:34 【问题描述】:

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

剩下的是描述。

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

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

【问题讨论】:

【参考方案1】:

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

你当然可以自己实现类似标题服务的东西,只需使用TitleService作为模板

类似于Title 服务的Meta 服务正在开发中(目前只是一个拉取请求)。

【讨论】:

非常感谢。我想我会采用标题服务的方式 在发布版本中有变化吗?我知道平台浏览器中有一个内置的标题服务,但有什么描述吗? 不,到目前为止没有任何变化。 此 PR 现已合并,是 4.0.0-beta.0 的一部分【参考方案2】:

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

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

【讨论】:

我已经启动了实时 ng2-metadata,它工作正常,但是当我让谷歌抓取我的页面时,它仍然说我有重复的元标记。我还有什么需要做的吗? 我认为您应该从您的 html 中删除“静态”标签。 ng2-metadata 将即时写入它们。 非常适合我。非常感谢! 当使用延迟加载的路由时,我发现 @RonaldPadur 这不起作用 @AngularM 延迟加载路由在 Angular 中是一个大问题,尤其是当您使用 ngtools 在 AoT 中编译应用程序时。 Angular 团队正在解决它的问题。【参考方案3】:

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

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

// [...]

constructor(private meta: Meta) 

// [...]

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

【讨论】:

这会帮助谷歌正确索引标题和元标签吗? 通过 Meta 添加/更新的标签没有被爬虫抓取,有没有办法解决这个问题? 我想这一定是注定要与 Angular Universal 一起使用的。 对不起,其实我不明白,在哪个文件,我要更新这段代码。 这适用于 Angular Universal。以下是我所做的更改:github.com/kmturley/universal-starter/commit/…【参考方案4】:

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

基本思路是使用Meta from @angular/platform-browser

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

    使用removeTag(attrSelector: string) : void删除旧的 方法。 使用addTag(tag: MetaDefinition, forceCreation?: boolean) : HTMLMetaElement 方法添加新的。

当路由器触发路由更改事件时,您必须这样做。

注意:实际上index.html的头部还需要有默认的&lt;title&gt;...&lt;/title&gt;&lt;meta name="description"..." content="..."/&gt;,所以在动态设置之前已经有一些静态内容了。

我的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);
    );
  


    可以看出,有一个额外的 data 对象字段用于 每条路线。它包含 titlemetaDescription 字符串 这将用作标题和元标记内容。 在构造函数中,我们过滤掉路由器事件并订阅过滤后的事件 路由器事件。那里用的是rxjs,但其实没必要用。常规的if statementsloops 可用于流、过滤器和映射。 我们还将我们的数据对象字段与我们的事件合并,这样我们就可以轻松地 使用 titlemetaDescription 字符串等信息。 我们动态更改&lt;title&gt;...&lt;/title&gt;&lt;meta name="description"..." content="..."/&gt; 标签。

效果:

第一个组件

第二个组件

事实上,我目前使用这个解决方案的更复杂的版本,它还使用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 元文档:https://angular.io/docs/ts/latest/api/platform-browser/index/Meta-class.html。事实上,它们的信息量不是很大,我必须试验并研究真正的 .js 代码才能使这种动态元更改生效。

【讨论】:

我试过这个标签正在被添加,但在 facebook 上的 facebook 打开图上它没有显示。有什么办法解决吗?

以上是关于Angular2 - SEO - 如何操作元描述的主要内容,如果未能解决你的问题,请参考以下文章

seo搜索引擎优化原理方法实战台州seo服务公司哪家好?台州seo优化价格大概是多少?

用于网络爬虫的 Angular 2+ SEO [重复]

SEO优化论坛让我懂了没团队经验,看如何制作短视频赚钱一天20元

angular2-jwt 编译元数据解析器错误

使用类装饰器时需要 Angular2 反射元数据填充程序

新手做网站SEO优化,该如何进行优化操作?