如果使用HTML5=true路由器,则Angularjs和change metatags支持不同视图的SEO
我在客户端使用Angularjs,在服务器端使用dustjs&Nodejs,用于我基于SPA的站点。我需要在如果使用HTML5=true路由器,则Angularjs和change metatags支持不同视图的SEO,angularjs,Angularjs,我在客户端使用Angularjs,在服务器端使用dustjs&Nodejs,用于我基于SPA的站点。我需要在部分添加标记以支持SEO。我也在使用HTML5=true路由方法,因此我的URL没有#。由于我使用的是HTML5=true路由,因此我可以选择以下两个选项之一来实现搜索引擎优化 通过从视图控制器发出事件来更改元标记,并将其捕获到全局控制器中,然后更新元标记。下面的文章中提到了这种方法。 由于SEO将使用带有#的绝对URL,因此我可以使用dust.js+nodejs并根据URL更改元标记
部分添加
标记以支持SEO。我也在使用HTML5=true
路由方法,因此我的URL没有#。由于我使用的是HTML5=true
路由,因此我可以选择以下两个选项之一来实现搜索引擎优化
注意:我使用prerender.io为搜索引擎提供页面服务 我在这方面有一些经验。 我的实现在客户端,我还使用了prerender.io 根据我的经验-从变体#1开始(无论如何,为用户显示正确的标题是好的)。。。第一次(直到高负载,或者如果您可以缓存内容)。而且它很容易实现,并且在服务器和客户端之间没有逻辑复制 但它也有缺点:prerender速度慢且不稳定(注意:我不是在prerender.io中谈论saas,而是关于我自己的服务器) 因此,很可能以后您会决定将变体#2作为#1的补充或作为prerender的替代品来实现,但它更复杂,因为您需要在服务器端复制一些逻辑 关于我的实施: 我有一项服务,用于存储元标记信息:
angular.module('....')
.factory('seoParams', function ($rootScope) {
var projectName = '....';
var states = [];
return {
title: projectName,
description: '',
keywords: '',
properties: {},
canonical: false,
prerenderStatusCode: 200,
enter: function () {
states.push({
title: this.title,
desctiption: this.desctiption,
keyworwds: this.keyworwds,
properties: this.properties,
canonical: this.canonical,
prerenderStatusCode: this.prerenderStatusCode
});
this.title = projectName;
this.desctiption = '';
this.keyworwds = '';
this.properties = {};
this.prerenderStatusCode = 200;
this.canonical = false;
return this;
},
exit: function () {
var data = states.pop();
_.assign(this, data);
},
setTitle: function (title) {
this.title = title;
return this;
},
setTitlePart: function (title) {
this.title = title + ' ~ ' + projectName;
return this;
},
setDescription: function (description) {
this.description = description;
return this;
},
setKeywords: function (keywords) {
this.keywords = keywords;
return this;
},
setCanonical: function (canonical) {
this.canonical = canonical;
return this;
},
setProperty: function (name, value) {
this.properties[name] = value;
return this;
},
appendProperties: function (properties) {
_.assign(this.properties, properties);
return this;
},
replaceProperties: function (properties) {
this.properties = properties;
return this;
},
setStatus: function (status) {
this.prerenderStatusCode = status;
return this;
}
};
});
要实际更新元标记的控制器:
angular.module('....')
.controller('SeoCtrl', function ($scope, seoParams, FB_APP_ID, TWITTER_SITE) {
$scope.seoParams = seoParams;
$scope.fbAppId = FB_APP_ID;
$scope.twitterSite = TWITTER_SITE;
});
和视图:
<head ng-controller="SeoCtrl">
<base href="/"/>
<title ng-bind="seoParams.title"></title>
<meta property="fb:app_id" content="{{fbAppId}}">
<meta ng-if="twitterSite" name="twitter:site" content="{{twitterSite}}">
<meta name="description" content="{{seoParams.description}}">
<meta name="keywords" content="{{seoParams.keywords}}">
<meta
ng-repeat="(property, content) in seoParams.properties"
property="{{property}}"
content="{{content}}"/>
<meta name="prerender-status-code" content="{{seoParams.prerenderStatusCode}}">
<link ng-if="seoParams.canonical" rel="canonical" href="{{seoParams.canonical}}" />
<meta name="fragment" content="!">
...
</head>
如果需要,可以从控制器使用它,如下所示:
seoParams.enter().setTitle(title)....
$scope.$on('$destroy', function(){ seoParams.exit() });
谢谢我忘记了哪些是与功能相关的。我现在将尝试客户端实现。@Bogdan Savluk我在哪里插入OneNet和onExit回调?谢谢在ui路由器中定义新状态时,它位于状态定义对象中。
$stateProvider
seoParams.enter().setTitle(title)....
$scope.$on('$destroy', function(){ seoParams.exit() });