【问题标题】:How do i share title and metadata on LInkedin / FB of dynamically generated titles on sub-pages of Single page application?如何在 LInkedin / FB 上共享单页应用程序子页面上动态生成的标题的标题和元数据?
【发布时间】:2021-06-04 12:27:23
【问题描述】:

我在 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 上共享我的应用程序的其中一个子页面时,它不会根据我在我的应用程序中动态生成的参数更新 URL 的标题和 OG 项,而是显示默认标题在我的应用预路由上设置。

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

【问题讨论】:

    标签: angular linkedin sharing page-title


    【解决方案1】:

    使用单页网络应用程序更新元数据只会在客户端更新它。 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);
      });
    });
    

    【讨论】:

    • 谢谢凯尔。你有这方面的例子吗?试图理解这究竟意味着什么,这是否意味着所有页面都不会作为单页应用程序加载?我用谷歌搜索,这就是我得到的——你的意思是这样的吗? thirdrocktechkno.com/blog/prerendering-in-angular-9
    • 是的。那篇文章概述了实现此目的的两种主要方法:预渲染和服务器端渲染。如果您的页面数量有限(数百或更少),则预渲染是理想的选择,但如果您有很多页面,则最好使用服务器端渲染动态创建它们。还有一种更简单的方法,如果您不需要填充所有内容,您可以只修改元数据。 Google 确实会解释您的 JS,因此就 SEO 而言,没有必要填充所有内容,除非您希望在其他搜索引擎中排名。我将在一个示例中进行编辑
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2013-12-15
    • 2014-07-13
    • 2020-10-30
    • 1970-01-01
    • 2023-03-23
    • 2014-07-03
    相关资源
    最近更新 更多