Angular 5在服务器端渲染中动态添加amphtml链接标记

时间:2018-10-04 09:02:17

标签: angular angular5 amp-html angular-universal

我有带有服务器端渲染的Angular 5 SPA。我想将指向Google amp静态页面的链接动态添加到<head>,例如:

<link rel="amphtml" href="https://www.example.com/amp/dynamic.amp.html">

我发现angular已在@angular/platform-browser/Meta中实现了类似的功能,并且 @angular/platform-browser/Title。除了链接标记外,我如何实现类似的方法?我希望amp链接可以在不运行js的情况下由viewsource中的机器人预先渲染和访问。

2 个答案:

答案 0 :(得分:0)

好的,因此感谢@ xrobert35,我最终得到了这个解决方案,该解决方案似乎可以与ssr和我的ASP.NET Core + Angular 5项目一起正常工作

main.server.ts中,我编辑了createServerRenderer(),以截取以字符串形式返回的html,并在<link>之后紧接添加了<head>标签作为文本

显然NO AMP LINK DEFINED FOR CURRENT PAGE是用于调试的,如果没有可用的放大器页面,您应该避免添加整个标签

let promise = renderPromise.then(html => {
        let ampTag = `<link rel="amphtml" href="${ampHTMLPages[params.url] || 'NO AMP LINK DEFINED FOR CURRENT PAGE'}">`;
        return { html: html.replace("<head>", `<head>${ampTag}`) };
    });

对于那些需要在下面添加我的完整main.server.ts的人:

import { RoutePaths } from './app/shared/routePaths.constants';
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { renderModule, renderModuleFactory } from '@angular/platform-server';
import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode } from '@angular/core';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { createServerRenderer } from 'aspnet-prerendering';
export { AppServerModule } from './app/app.server.module';
import { ORIGIN_URL } from './app/shared/baseurl.constants';

enableProdMode();

export default createServerRenderer(params => {
    const { AppServerModule, AppServerModuleNgFactory, LAZY_MODULE_MAP } = (module as any).exports;

    const options = {
        document: params.data.originalHtml,
        url: params.url,
        extraProviders: [
            provideModuleMap(LAZY_MODULE_MAP),
            { provide: APP_BASE_HREF, useValue: params.baseUrl },
            { provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
            { provide: ORIGIN_URL, useValue: params.origin }
        ]
    };

    const ampHTMLPages = {
        [RoutePaths.exampleRoute]: 'some/amp/page/example.html'
    }

    const renderPromise = AppServerModuleNgFactory
        ? /* AoT */ renderModuleFactory(AppServerModuleNgFactory, options)
        : /* dev */ renderModule(AppServerModule, options);

    let promise = renderPromise.then(html => {
        //@see https://www.ampproject.org/docs/getting_started/create/prepare_for_discovery
        let ampTag = `<link rel="amphtml" href="${ampHTMLPages[params.url] || 'NO AMP LINK DEFINED FOR CURRENT PAGE'}">`;
        return { html: html.replace("<head>", `<head>${ampTag}`) };
    });
    promise.catch(response => { console.error(response) });
    return promise;
});

答案 1 :(得分:0)

我有类似的问题。

在这里,由于这篇文章,我如何解决我的问题:http://blog.davidjs.com/2018/09/insert-script-tags-in-angular-components/

要添加/更改标题或meta balise,我使用import { Title, Meta } from '@angular/platform-browser'

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


constructor(
    private titleService:Title,
    private metaService:Meta
) {}

ngOnInit() {
    // Set the page title
    this.titleService.setTitle('title');

    // Update the meta balise 'name=description'
    if (this.metaService.getTag('name=description')) {
        this.metaService.updateTag({ name: 'description', content: 'New Meta' }, `name='description'`);
        } else {
        this.metaService.addTag({ name:'description', content: 'New Meta' });
    }
}

要添加链接或脚本之类的新栏杆,请使用import { Inject, Renderer2 } from '@angular/core';import { DOCUMENT } from '@angular/common';

import { Inject, Renderer2  } from '@angular/core';
import { DOCUMENT } from '@angular/common';


constructor(
    private renderer2: Renderer2,
    @Inject(DOCUMENT) private _document
) {}

ngOnInit() {
    const link = this.renderer2.createElement('link');
    link.rel = "amphtml";
    link.href = "https://www.example.com/amp/dynamic.amp.html";
    this.renderer2.appendChild(this._document.head, link);
}

我希望我的回答会有所帮助。