Заголовок и метатеги не отображаются в угловом SSR на сервере - PullRequest
0 голосов
/ 05 ноября 2018

Я разработал веб-сайт, используя Angular 6 во внешнем интерфейсе. По умолчанию Angular не оптимизирован для SEO, поэтому для этого я реализовал его в виде Angular-Universal или Angular SSR (рендеринг на стороне сервера). Я обновил код и сравнил исходные коды страниц ранее и теперь, я могу видеть свое приложение внутри тегов <app-root> и </app-root>, прежде чем появится только «загрузка ...».

Я использую MetaService и TitleService из @angular/platform-browser, чтобы обновить нужные теги <meta> для Facebook и Twitter и тег <title> соответственно.

Проблема в том, что когда я запускаю сервер узлов в моей локальной системе, view-source показывает мне обработанные теги meta, но когда я запускаю тот же код на сервере узлов на виртуальной машине AWS, я не получаю визуализированный meta тегов, но доступен другой код приложения.

UPDATE: Функция, которая добавляет 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 }
    ]);
  }

Я вызываю эту функцию в ngOnInit (). Он правильно выполняет рендеринг на моей локальной машине, но не на сервере.

egElement и id возвращаются из вызова службы в бэкэнд, а meta служба импортируется и внедряется в конструктор.

Ответы [ 2 ]

0 голосов
/ 30 июля 2019

Привет, я также столкнулся с этой ошибкой, поэтому убедитесь, что в вашем файле server.ts был импортирован import 'reflect-metadata';, чтобы отразить все мета в index.html

Вы можете взглянуть на мой 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}`);
});
0 голосов
/ 13 ноября 2018

Если вы используете пользовательские вызовы XHR, например, не используя Angular HttpClient, SSR не будет ждать ответов на вызовы API (это также может произойти при использовании сторонних библиотек для получения данных API). Глядя на ваш сайт, не происходит рендеринг на стороне сервера, кроме макета страницы / header / footer

Я предполагаю, что это связано с тем, что данные API не извлекаются в SSR. Может быть, вы могли бы обновить свой вопрос с некоторой информацией по этому вопросу?

Существует хорошо протестированная и поддерживаемая библиотека под названием ngx-meta, которая является универсальной (SSR) совместимой. Вы можете посмотреть на их реализацию и демонстрации, или попробовать их библиотеку https://github.com/fulls1z3/ngx-meta

...