由于Angular Universal不会在CLI中使用很长一段时间,我必须使用prerender.io来让SEO正常工作。但是,在经过一些测试之后,似乎它并没有那么好用,因为它似乎没有等待延迟加载的模块,所以SEO仍然失败。
他们在this location的网站上说:
您的网页是否仅部分呈现?
我们的Prerender服务器会尽力确定页面何时完成 通过计算飞行中的请求数量来加载。一旦数量 在飞行中的请求达到零,我们等待一小段时间 然后保存HTML。如果这样过早保存页面,则可以使用 我们的window.prerenderReady标志用于通知服务器您的页面是 准备好了。
将它放在HTML中:
<script> window.prerenderReady = false; </script>
当我们看到window.prerenderReady设置为false时,我们会等到它 设置为true以保存HTML。当您的页面出现时执行此操作 准备好(通常是在ajax调用之后):
window.prerenderReady = true;
这是我不明白如何去做的地方。由于Angular从模板中删除脚本标记(不确定这只是CLI行为还是Angular本身),我无法设置初始脚本标记。我也无法弄清楚如何从我的组件类更新模板脚本标记内的window
属性prerenderReady
,因为我不能只使用window.prerenderReady = true
并期望它可以工作,因为脚本必须添加到模板中。
有没有人设法解决这个问题,或者对如何实现这一目标有任何想法?
答案 0 :(得分:0)
删除:server.use(prerender.removeScriptTags());
prerender.io可以设置为在脚本中保留,以便它们可以运行。
我的Meteor-Angular2设置给了我同样的悲伤。我的页眉和页脚模块将呈现,但不是我的路由器出口输出。我放了:
<script> window.prerenderReady = false; </script>
在我的主index.html(包含主<app></app>
标签)上,并放置:
window.prerenderReady = true;
在我上一次回调结束时。然后我注释掉了://server.use(prerender.removeScriptTags());
在我prerender server的server.js中 - 它最终正确呈现。
答案 1 :(得分:0)
好的,我有这个工作,但它似乎是一个相当复杂的解决方案,所以希望有人在这里比我聪明:)
首先,取消注释fstream & const
中的所有浏览器polyfill(可能并非所有浏览器polyfill都需要,但我还没有对它们进行逐个测试):
src/polyfills.ts
接下来,您需要在/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';
prerenderReady
的脚本标记中获取<head>
标记。在我建立之前,Angular并没有删除评论,我在那里留下了一面旗帜:
index.html
现在,在运行<head>
<!--prerender-->
</head>
之后,您需要将该标志替换为实际的脚本标记。我使用shell脚本和ng build
命令执行此操作。类似的东西:
sed
注
我对OSX上安装TPL="\<!--prerender--\>"
PRERENDER_SCRIPT="\<script\>window.prerenderReady = false;\<\/script\>"
# replace the comment with the actual script tag in the html file and save
# that file's contents as a string in the INDEX_HTML variable
INDEX_HTML=$(sed "s/$TPL/$PRERENDER_SCRIPT/g;" dist/browser/index.html);
# remove the original index.html file and create an empty one in its place
rm dist/browser/index.html
touch dist/browser/index.html
# echo the INDEX_HTML string into the new file
echo "$INDEX_HTML" > dist/browser/index.html
有一个模糊的回忆,但我不记得这些步骤。如果您不在Linux上并且sed
不能为您工作,那么您只需向谷歌寻求解决方案。
最后,您需要在某处将sed
标志设置为true。我是在prerenderReady
AppComponent
实施中执行此操作的:
OnInit
可能还要提到的是,为了在TypeScript应用程序中使用export class AppComponent implements OnInit
{
ngOnInit()
{
window.prerenderReady = true;
}
}
,我需要在文件中调用window
这样的内容:
typings.d.ts
除了我对interface Window
{
prerenderReady:boolean;
}
文件顶部的那个打字文件的引用:
app.module.ts
希望能帮助别人。