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

Angular 我如何在LInkedin/FB上共享单页应用程序子页上动态生成的标题和元数据?,angular,linkedin,sharing,page-title,Angular,Linkedin,Sharing,Page Title,我已经在Angular中设置了一个单页应用程序,目前根据路由动态设置页面标题和OG/meta参数。i、 例如,每次在应用程序中使用此选项更改路线时。titleService还更新页面的页面标题和元标记: import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/mergeMap'; import { Component, OnInit } from '@angular

我已经在Angular中设置了一个单页应用程序,目前根据路由动态设置页面标题和OG/meta参数。i、 例如,每次在应用程序中使用此选项更改路线时。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,以便它根据我页面上动态更新的标题显示标题和说明?

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

虽然有许多可能的解决方案,但都需要相当多的工作,并且根据项目的范围有其优缺点。您可以在服务器上为初始页面加载预先构建HTML,或者在发送HTML文件之前在服务器上调整HTML文件的元数据

一种简单的预渲染方法:

只预呈现元数据的一种方法是在构建代码后运行脚本,该代码使用调整后的元数据创建单个html页面。(免责声明:我主要使用React,角度不多,因此示例可能有点偏离,但总体思路在各个框架中应该是相同的)

以此文件为例查看-

在这里,我读入构建的
index.html
文件,使用regex查找并替换一组关键字符(放在html模板文件中),修改每个路由的元数据,然后将其保存回一个单独的html文件,该文件将与适当的元数据一起提供(但当页面完全加载时,将以相同的方式运行SPA)

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

$OG\u标题
在构建脚本之后,我使用一个简单的
节点prerender metadata.js

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

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

app.get('/terms of use',(req,res)=>{
const filePath=path.resolve(_dirname,“../../client”,“build”,“index.html”);
//读入index.html文件
读取文件(文件路径,'utf8',函数(错误,数据){
如果(错误){
返回控制台。错误(err);
}
//用服务器生成的字符串替换特殊字符串
数据=数据。替换(/\$OG\U标题/g,“使用条款”);
const result=data.replace(/\$OG\u DESCRIPTION/g,“使用条款”);
res.send(结果);
});
});

谢谢Kyle。你有这样的例子吗?试图准确理解这意味着什么,这是否意味着所有页面都不会作为一个页面应用程序加载?我在谷歌上搜索,这就是我得到的——你的意思是这样的吗?没错。那篇文章概述了实现这一点的两种主要方法:预渲染和服务器端渲染如果页面数量有限(数百页或更少),预渲染是理想的,但如果您有很多页面,则最好使用服务器端呈现动态创建它们。还有一种更简单的方法,如果您不需要填充所有内容,您可以只修改元数据。谷歌会解释您的JS,因此就SEO而言,不必填充所有内容,除非您希望排名在其他搜索引擎。我会在一个例子中编辑谢谢,我会试试这个!!