如何使用 React Helmet 在 React 中生成动态元描述和图像?

How do I generate dynamic meta description and image in React using React Helmet?

我的程序 (https://rohanweb.netlify.app) is sanity API driven. It has blog post so whenever I share particular blog(using react-share), It displays default meta description and image which is inside index.html file. I have used React Helmet for dynamic meta tags but is doesn't seem to be working. No matter what I share, It is displaying default meta and when I remove that from index.html file it displays nothing. I have checked from https://heymeta.com 。这是代码示例:

<Helmet>
<title>{singlePost.blogTitle}</title>
<link rel="canonical" href={window.location.href} />
<meta property="og:url" content={window.location.href} />
<meta property="og:type" content="website" />

<meta name="twitter:card" content={singlePost.publicImg.asset.url} />

//for Title
<meta property="og:title" content={singlePost.blogTitle} />
<meta itemprop="name" content={singlePost.blogTitle} />
<meta name="twitter:title" content={singlePost.blogTitle}/>

//for Description
<meta property="og:description" content={singlePost.blogDescription} />
<meta itemprop="description" content={singlePost.blogDescription} />
<meta name="twitter:description" content={singlePost.blogDescription} />

//for Image
<meta property="og:image" content={singlePost.publicImg.asset.url} />
<meta itemprop="image" content={singlePost.publicImg.asset.url} />
<meta name="twitter:image" content={singlePost.publicImg.asset.url} />
</Helmet>

Image Demo

React-helmet 不是所需解决方案的理想选择。下面是浏览器处理的顺序

  1. 请求页面及其路径。
  2. 获取该页面的资源。
  3. 加载默认 HTML(带有元标记...)
  4. 执行 JavaScript 代码,从而通过 react-helmet 更新元标记。

将您的应用程序托管在服务器上,默认的元标记呈现为已获取。它仅在浏览器请求页面上的资源时发生变化,之后执行 react-helmet 函数。

我能想到的更好的解决方案是从服务器配置元标记并在前端配置 Hydrate。

下面的例子,

<html>
  <head>
    __PLACEHOLDER_FOR_DYNAMIC_META_TAG__
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

同步读取索引并用需要的元标记替换占位符

const path = require("path")
const express = require("express")
const app = express()
const fs = require("fs")

const indexFilePath= path.join(__dirname, "build/index.html")
app.get("/", (req, res) => {
  const myFile = fs.readFileSync(indexFilePath)
  const myMetaTag= "Meta tag details as per requirement"
  const toHydrate = myFile.replace("__PLACEHOLDER_FOR_DYNAMIC_META_TAG__", myMetaTag)
  res.send(toHydrate)
});

app.get("*", (req, res) =>
  res.sendFile(path.join(__dirname, "build/index.html"))
)
const port = process.env.PORT || 5000
app.listen(port, () => {
  console.log(`Server listening on port ${port}`)
});

在你的 React 应用中而不是 ReactDOM.render(<App/>, ...) use ReactDOM.hydrate(<App />, ...)

或者直接选择 Next.js :)

更新了您在下方评论的答案

document.getElementsByTagName('meta')["keywords"].content = "Hello";
document.getElementsByTagName('meta')["description"].content = "description";