【问题标题】:React Helmet not updating meta tagsReact Helmet 不更新元标记
【发布时间】:2021-01-18 21:46:48
【问题描述】:

我在 react 项目中有我的 index.html 页面,如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>Bucard | Digital Business Card</title>

  <meta name="title" content="Bucard | Digital Business Card">
  <meta name="description" content="Bucard - Description for bucard" />
  <meta property="og:title" content="Bucard | Digital Business Card" />
  <meta property="og:image" content="http://m.digital-card.co.il/zedka/152/images/icon.png" />
  <meta property="og:description" content="Bucard - Description for bucard" />
  <meta property="og:url" content="https://bucard.co.il/" />
</head>

<body>
  <div id="root"></div>
</body>

</html>

还有我的 react-helmet 部分,该部分存在于组件中,并且在 url 上有一条路径:

<Helmet>
   <title>{"Digital card of " + this.state.card.Name}</title>

   <meta name="title" content={"Digital card of " + this.state.card.Name} />
   <meta name="description" content="Description for the react-helmet section" />
   <meta property="og:title" content={"Digital card of " + this.state.card.Name} />
   <meta property="og:image" content="http://m.digital-card.co.il/friedman/249/images/icon.png" />
   <meta property="og:description" content="Description for the react-helmet section" />
   <meta property="og:url" content={"https://bucard.co.il/digitalCard/" + this.state.card.ShortID} />
</Helmet>

现在,这里的问题是 这里唯一替换的标签是 标签,但没有替换任何 <meta> 标签。

我没有服务器端渲染,我有服务器端 (node.js) 和返回某些值的 json 的函数,我在我的 react 应用程序中渲染。

我搜索了将近 2 周,但还没有解决这个问题,这对我的项目非常重要。 还尝试将data-react-helmet=true 置于不同的情况下,但仍然无法正常工作。

谁能帮我解决这个问题?非常感谢:)

【问题讨论】:

标签: html reactjs meta-tags react-helmet


【解决方案1】:

对于没有 SSR(服务器端渲染)的 SPA,从机器人的角度来看,您的 head 标签位于 dist/public 文件夹中的静态 index.html 文件中。要添加从 head 标签向机器人提供动态元素的功能,您可以:

  • 使用预渲染服务
  • 或者使用 next.js 在服务器上呈现您的页面(或页面的一部分),以便机器人可以抓取此内容
  • 寻找其他 SSR 解决方案

您可以阅读-https://github.com/nfl/react-helmet/issues/489

一种对我有用的方法:

  1. 将您的流量引导到节点服务器

  2. 从此节点服务器返回您的 index.html 文件并传递头标签。

    return res.render('index', {
      headTags: ReactDOMServer.renderToStaticMarkup(tags),
    })
    

这里,tags 是一个 HTML 元素数组,例如 &lt;meta/&gt;, &lt;title/&gt; 等。

奖励:您可以在前端导入相同的 tags 模块来获取 Helmet 的头部标签。

  1. 在您的 index.html 中,您可以使用把手来读取从节点服务器传递的头标签并在头部分打印头标签。

    <head>
    
      {{{
        headTags
      }}}
      ...
    </head>
    

要将车把用作引擎,请将其添加到您的节点服务器

app.engine('html', handlebars.engine);

【讨论】:

  • 您好,非常感谢您的评论。你认为最好的选择是什么?服务器端渲染会那么复杂吗?
  • 最佳选择取决于您的用例。如果你想使用 SSR 渲染所有的 html,那么像 Next.js 这样的东西可以节省你很多时间。如果您只需要 SSR 的头标签,您可以设置自己的节点服务器,该服务器具有仅构建头标签的最少代码。它并不复杂。我在答案中添加了一个简短的内容。
  • @roshan 你能给出一个示例源代码吗?
  • @Beu 不幸的是,设置的代码库是不公开的。但我可以详细说明你觉得困难的部分。
  • 嗨@roshan 我在我的服务器文件中使用了 Helmet.renderStatic()。它现在工作。谢谢:)
【解决方案2】:

我遇到了同样的问题。并解决如下。

在您的服务器文件(例如 server/index.js)中,添加 const 头盔 = Helmet.renderStatic() 在 ReactDOMServer.renderToString 之后。我的代码如下:

const app = ReactDOMServer.renderToString(<App />);

const helmet = Helmet.renderStatic()
const indexFile = path.resolve('./build/index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
     let updated = data.replace('<div id="root"></div>', `<div id="root">${app}</div>`);
     return res.send(updateHtmlContent(updated, helmet));
  }

并添加以下功能。这是用头盔标签更新html内容。

function updateHtmlContent(app, helmet) {
      return `
        <!DOCTYPE html>
        <html lang="en">
          <head>
            ${helmet.title.toString()}
            ${helmet.meta.toString()}
          </head>
          <body>
            <div id="root">
              ${app}
            </div>
          </body>
        </html>
      `
    }

这可能对你有帮助:)

【讨论】:

  • 嗨,谢谢 :) 我没有任何服务器文件,我有 2 个项目 - 一个用于客户端,一个用于服务器。你是指哪一个?我应该在我的客户端项目中创建服务器文件并在不同于现有的两个项目上运行它吗?
  • 哦没有SSR啊?我的意思是上面的SSR。对不起
  • 那么...如何将 SSR 准确地添加到我的项目中?还有一件事我想我应该说...这个组件应该在 SSR 中使用,而不是在 SSR 中,作为一个普通的 React 组件(我有两种不同的情况需要那个组件)。你觉得我应该怎么做?
猜你喜欢
  • 2019-10-14
  • 2021-10-10
  • 1970-01-01
  • 2022-06-12
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
相关资源
最近更新 更多