我如何在 sub-pages 单页应用程序的动态生成标题的 LInkedin/FB 上共享标题和元数据?

How do i share title and metadata on LInkedin / FB of dynamically generated titles on sub-pages of Single page application?

我已经在 Angular 中设置了一个单页应用程序,目前根据路由动态设置页面标题和 OG/元参数。即例如每次在应用程序中使用此更改路线时。 titleService 还更新页面的页面标题和元标记 :

import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { Title } from '@angular/platform-browser';

@Component({...})
export class AppComponent implements OnInit {
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private titleService: Title
  ) {}
  ngOnInit() {
    this.router.events
      .filter((event) => event instanceof NavigationEnd)
      .map(() => this.activatedRoute)
      .map((route) => {
        while (route.firstChild) route = route.firstChild;
        return route;
      })
      .filter((route) => route.outlet === 'primary')
      .mergeMap((route) => route.data)
      .subscribe((event) => this.titleService.setTitle(event['title']));
  }
}

现在的问题是,当我在 Linkedin 上分享我的应用程序 sub-pages 之一时,它不会根据我在其中动态生成的参数更新 URL 的标题和 OG 项目我的应用程序,而是显示在我的应用程序上设置的默认标题 pre-routing。

我如何分享到 Linkedin / Facebook,以便它根据我页面上动态更新的标题显示标题和描述?

使用单页网络应用程序更新元数据只会在客户端进行更新。 LinkedIn、Facebook 和其他社交共享网站不会加载和解释 JavaScript。他们只是获取从服务器返回的 HTML 文件并使用其中包含的任何元数据。因此,在 JavaScript 中实现的自定义路由和相关数据将永远不会被读取,而是始终显示默认值。

尽管有许多可能的解决方案,但所有这些都需要大量的工作,并且根据项目的范围各有利弊。您可以考虑在服务器上预先构建 HTML 以进行初始页面加载,或者在发送文件之前在服务器上调整 HTML 文件的元数据。

一个简单的预渲染方法:

一种预呈现 只是 元数据的方法是在构建创建个人 html 具有调整后的元数据的页面。 (免责声明:我主要使用 React,用得不多 Angular,因此示例可能略有偏差,但跨框架的总体思路应该是相同的)

查看此文件作为示例 -
https://github.com/cid-harvard/growth-lab-app-front-end/blob/master/prerender-metadata.js

这里我读入了内置的index.html文件,通过使用正则表达式查找和替换关键字符集(放置在HTML模板文件中)修改每个路由的元数据然后另存为一个单独的 HTML 文件,该文件将与适当的元数据一起提供(但在页面完全加载时 运行 SPA 将以相同的方式提供)。

为了便于搜索和替换,HTML 模板包含如下“默认”元数据:

<title>$OG_TITLE</title>
<meta name="description" content="$OG_DESCRIPTION" />

我运行上面的脚本在构建脚本后用了一个简单的node prerender-metadata.js

一个简单的服务器端渲染方法:

使用相同样式构建带有可搜索字符串的 HTML 模板,您还可以在服务器上执行类似的搜索和替换以获取更多动态内容。不是在构建步骤之后 运行 立即创建一个脚本,而是每次请求特定 url 时,您都会在服务器上 运行 它。这是一个在服务器上使用 express 和 Node 的例子:

app.get('/terms-of-use', (req, res) => {
  const filePath = path.resolve(__dirname, '../../client', 'build', 'index.html');
  // read in the index.html file
  fs.readFile(filePath, 'utf8', function(err, data) {
    if (err) {
      return console.error(err);
    }
    // replace the special strings with server generated strings
    data = data.replace(/$OG_TITLE/g, 'Terms of Use');
    const result  = data.replace(/$OG_DESCRIPTION/g, "Terms of Use.");
    res.send(result);
  });
});