angular - 使用外部 API 调用更新 angular universal 中的元标记

标签 angular seo meta-tags angular-universal server-side-rendering

我已经花了 2 个多月的时间,但找不到关于如何使用 angular universal 的明确解决方案。 我已经花了大约 6 个月的时间在一个我没有太多时间的项目上实现 angular universal,现在我遇到了这个问题。谁能帮我解决这个问题,因为似乎全世界都想知道 Angular SSR 的解决方案。

这是我的代码(元标记服务):

import {Injectable} from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
import {commonMetas} from './meta-data.model';

@Injectable()
export class SeoService {
    public commonMetas = commonMetas;
    constructor(public meta: Meta, public title: Title) {}

    setAutomatically (key = 'none') {
        const detail = this.commonMetas[key];
        /** setting defaults */
        this.setTitle(detail.title);
        this.setAuthor();
        this.setDescription(detail.description);
        this.setKeywords(detail.keyword);
    }
    setFromJson(key: {
        title: any,
        description: any,
        image: any,
        keyword: any,
        author: any
    }) {
        key.title = key.title ? key.title : this.commonMetas['none'].title;
        key.description = key.description ? key.description : this.commonMetas['none'].description;

    }
    setTitle(titleToSet = '') {
        this.title.setTitle(titleToSet);
    }
    setAuthor (nameToSet = '') {
        this.meta.addTag({ name: 'author',   content: 'havemybooks.com'});
    }
    setKeywords (keyword = '') {
        this.meta.addTag({ name: 'keywords', content: keyword});
    }
    }
}

还有我的 component.ts

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
      this.id = +params['id'];
      this.api.getParticular({id: this.id}).subscribe((response) => {
        this.content = response.blog_data[0];
        this.content.main_image = this.getImage(this.content.main_image);
        this.content.metaCreatedAt = moment(this.content.created_at).format('YYYY-MM-DD');
        this.content.displayCreatedAt = moment.utc(new Date(this.content.created_at)).fromNow();
        this.content.name = this.handleName(this.content.name);
        this.seo.setFromJson({
          title: this.content.title,
          image: this.content.main_image,
          description: this.content.blog,
          author: this.content.name,
          keyword: ''
        });
      });
   });
  }

以下是一些链接的 StackOverflow 问题和 GitHub 问题:

Angular universal Server Side Rendering, Meta tags

Updating meta tags for SEO using angular universal

Angular Universal + External API

https://github.com/fulls1z3/ngx-meta/issues/101

Angular Universal - OG meta tags not working with child routes

https://github.com/fulls1z3/ngx-meta/issues/118(I试图从成功实现但没有得到帮助的人那里获得帮助)

https://github.com/maciejtreder/ng-toolkit/issues/460 (我打开了)

这个 list 还在继续 我看到过许多从未结束的讨论。任何可以建议如何在 ng-express 中呈现之前进行 API 调用的人。

我已经实现了 SSR 并使用了 ngx-meta 标签,但 fb 爬虫仍然显示我在 head 标签中使用的默认元标签。

UPDATE: I'm able to get the source updated with view source option in chrome but the Facebook and Google crawler show the default meta tags which are there by default. It's very tough to launch my website with it remaining any help is appreciated. @Brandon guided me a lot I spent quite some time on implementing node with Jade and Nunchucks but since angular universal use angular-express by default so I wasn't able to use the above-mentioned render engines.

那么有没有一种方法可以使用 ng express 引擎呈现元标记。

像这样<title>{{meta.title}}</title>...

最佳答案

找不到简单的方法,但这是 GitHub 用户提供的临时/hacky 解决方案 here我直接引用他的回答:

//all imports
enableProdMode();

export const app = express();

const mysql = require('mysql');
const httpRequest = require("request");
// all other consts

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));
//all other piece of code in server.ts

app.get('/*', (req, res) => {
  res.render('index', {req, res}, (err, html) => {
    if (html) {
        
        //console.log(html);
        // This is where you get hold of HTML which "is about to be rendered"
    
        // after some conditional checks make a HTTP call
        let url = 'http://....';
        httpRequest.get(url, (error, response, body) => {
                        if(error) {
                            return console.log(error);
                        }
                        const respBody = JSON.parse(body);
                        if(respBody){
                              html = html.replace(/\$TITLE/g, respBody.title);
                              html = html.replace(/\$DESCRIPTION/g, respBody.description);
                              html = html.replace(/\$OG_META_KEYWORDS/g, respBody.metaKeywords);
                              html = html.replace(/\$OG_META_DESCRIPTION/g, respBody.metaDescription);
                              html = html.replace(/\$OG_DESCRIPTION/g, respBody.ogDescription);
                              html = html.replace(/\$OG_TITLE/g, respBody.ogTitle);
                              html = html.replace(/\$OG_IMAGE/g, respBody.img);
                              html = html.replace(/\$OG_SITE/g, respBody.ogSite);
                        }
                        res.send(html);
            });
     }
  }
}

然后在 index.html 中,创建如下模板值:

    <title>$TITLE</title>

    <meta name="description" content="$DESCRIPTION"/> 
    <meta name="keywords" content="$OG_META_KEYWORDS" />
    <meta name="metaDescription" content="$OG_META_DESCRIPTION"/> 
    <meta name="metaKeywords" content="$OG_META_KEYWORDS" />
    <meta property="og:title" content="$OG_TITLE" />
    <meta property="og:description" content="$OG_DESCRIPTION" />
    <meta property="og:site_name" content="$OG_SITE" /> 
    <meta property="og:type" content="website" />   
    <meta property="og:image" content="$OG_IMAGE" />

关于angular - 使用外部 API 调用更新 angular universal 中的元标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52765453/

相关文章:

angular - 等待 ngOnInit 在 Jasmine Angular2 中完成

search - 如何防止Google重复内容问题|多站点

html - 专为文章和摘录标题使用 h1-h6 标题

http - 需要元标记使用浏览器超时保持事件

javascript - 如何动态设置 Angular JS 页面的标题?

angular - child 不呈现 parent 传递的模板

javascript - Angular2 缓存 HTTP 响应的最简单方法

seo - 网站在 Google Suggest 下拉列表中的外观可以被操纵吗?

c# - 页面 _load "og:image"元标记 asp.net 上的更改

Angular 路由有多个参数,有的在中间