简体   繁体   English

标题和元标记未在服务器的角度SSR中呈现

[英]Title and Meta tags not rendering in angular SSR in server

I have developed a website using Angular 6 in the frontend. 我已经在前端使用Angular 6开发了一个网站。 By default Angular is not SEO friendly, so in order to do that, I implemented it in the way of Angular-Universal or Angular SSR (Server Side Rendering). 默认情况下,Angular不是SEO友好的,因此,为了做到这一点,我以Angular-Universal或Angular SSR(服务器端渲染)的方式实现了它。 I updated the code and comparing the page sources from before and now, I can see my application inside the tags <app-root> and </app-root> , before only "loading..." would come. 我更新了代码并比较了以前和现在的页面源,我可以在标签“ <app-root>和“ </app-root> ”中看到我的应用程序,然后才出现“正在加载...”。

I am using the MetaService and TitleService from @angular/platform-browser to update the desired <meta> tags for Facebook and Twitter and the <title> tag respectively. 我正在使用@angular/platform-browserMetaServiceTitleService为Facebook和Twitter更新所需的<meta>标签以及<title>标签。

The problem is when I run the node server in my local system, view-source shows me the rendered meta tags, but when I run the same code in node server on AWS VM, I don't get the rendered meta tags, but other application code is available. 问题是当我在本地系统中运行节点服务器时,view-source向我显示了渲染的meta标记,但是当我在AWS VM上的节点服务器中运行相同的代码时,我没有得到渲染的meta标记,而其他应用程序代码可用。

UPDATE: The function that adds the meta tags 更新:添加meta标记的功能

updateMetaTags(egElement: Elements[]) {
    this.url = 'https://example.com/eg/' + this.id;
    const title = egElement[1].innerHTML;
    this.tweetText = 'Check the latest blog on \"' + title + '\"';
    this.meta.addTags([
      { property: 'og:url', content: this.url },
      { property: 'og:type', content: 'website' },
      { property: 'og:title', content: title },
      { property: 'og:description', content: 'Author: ' + egElement[2].innerHTML },
      { property: 'og:image', content: this.egElement[3].img }
    ]);
  }

I call this function in ngOnInit(). 我在ngOnInit()中调用此函数。 It does the rendering properly in my local machine, but does not do it on the server. 它可以在我的本地计算机上正确执行渲染,但不能在服务器上进行渲染。

egElement and id is returned from the service call to backend and meta service has been imported and injected in the constructor. egElementid从服务调用返回到后端,并且meta服务已导入并注入到构造函数中。

If you're using custom XHR calls , eg not using Angular HttpClient, the SSR won't wait for API call responses (this can also occur if using 3rd party libraries to retrieve API data). 如果您正在使用自定义XHR调用(例如,未使用Angular HttpClient),则SSR不会等待API调用响应(如果使用第3方库来检索API数据,也会发生这种情况)。 Looking at your site there is no server side rendering occurring other than the page layout/header/footer 查看您的站点,除了页面布局/页眉/页脚之外,没有服务器端渲染发生

I'm guessing it's related to the API data not being retrieved in SSR. 我猜这与未在SSR中检索到的API数据有关。 Maybe you could update your question with some info on this? 也许您可以使用一些信息来更新您的问题?

There is a well tested and maintained library called ngx-meta that's universal (SSR) compatible. 有一个经过良好测试和维护的名为ngx-meta库,该库具有通用(SSR)兼容性。 You could look at their implementation, and demos, or give their library a go https://github.com/fulls1z3/ngx-meta 您可以查看它们的实现和演示,或者尝试一下他们的库https://github.com/fulls1z3/ngx-meta

Hi I also was facing this error so make sure in your server.ts file to have imported import 'reflect-metadata'; 嗨,我也遇到了此错误,因此请确保您的server.ts文件中已导入import 'reflect-metadata'; to reflect all meta to index.html 反映所有meta到index.html

You can take a look at my server.ts config file\\ 您可以看一下我的server.ts配置文件\\

import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';
// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString();

const domino = require('domino');
const win = domino.createWindow(template);
global['localStorage'] = win.localStorage;
global['window'] = win;
global['document'] = win.document;
global['Document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;
global['MutationObserver'] = getMockMutationObserver();

function getMockMutationObserver() {
  return class {
    observe(node, options) {}

    disconnect() {}

    takeRecords() {
      return [];
    }
  };
}

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
  'html',
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [provideModuleMap(LAZY_MODULE_MAP)],
  }),
);

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get(
  '*.*',
  express.static(DIST_FOLDER, {
    maxAge: '1y',
  }),
);

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM