title: Dynamic link previews with React helmet in ReactJS
body: <p>Does anyone know if there's a possibility to set truly dynamic meta tags per page in a React App without Server Side Rendering?</p>
  <p>In a project that I am building I have some pages with a route like / article / {Id} and I would like to define dynamic meta tags (title, image, description). I use a reaction helmet as a component but it doesn't work here is the code of my component, part of the code page article / {id}, and my page index.html</p>
  <p>index.html :</p>
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
  
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;meta property=&quot;og:title&quot; content=&quot;title&quot; data-rh=&quot;true&quot;&gt;
  &lt;meta property=&quot;og:description&quot; content=&quot;description&quot; data-rh=&quot;true&quot;&gt;
  &lt;meta property=&quot;og:image&quot; content=&quot;icon%20maracana%20app.png&quot; data-rh=&quot;true&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
    &lt;meta name=&quot;theme-color&quot; content=&quot;#000000&quot; /&gt;
    &lt;link rel=&quot;apple-touch-icon&quot; href=&quot;%PUBLIC_URL%/logo192.png&quot; /&gt;
    &lt;link rel=&quot;manifest&quot; href=&quot;%PUBLIC_URL%/manifest.json&quot; /&gt;
    &lt;link href=&quot;https://fonts.googleapis.com/css?family=Montserrat:400,700&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
    &lt;link href=&quot;https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&quot; rel=&quot;stylesheet&quot;
      type=&quot;text/css&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css&quot;&gt;
    &lt;!-- Global site tag (gtag.js) - Google Analytics --&gt;
    &lt;script async src=&quot;https://www.googletagmanager.com/gtag/js?id=UA-173374516-1&quot;&gt;&lt;/script&gt;
    &lt;script data-ad-client=&quot;ca-pub-7237319988145838&quot; async
      src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
    &lt;script&gt;
      window.dataLayer = window.dataLayer || [];
      function gtag() { dataLayer.push(arguments); }
      gtag('js', new Date());
  
      gtag('config', 'UA-173374516-1');
    &lt;/script&gt;
    &lt;!-- &lt;script type=&quot;text/javascript&quot; src=&quot;js/my_script.js&quot;&gt;&lt;/script&gt; --&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/​moment.js/2.19.1/moment.min.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
    &lt;!-- Plugin Comments --&gt;
    &lt;div id=&quot;fb-root&quot;&gt;&lt;/div&gt;
    &lt;script async defer crossorigin=&quot;anonymous&quot;
      src=&quot;https://connect.facebook.net/fr_FR/sdk.js#xfbml=1&amp;version=v9.0&amp;appId=357191748915887&amp;autoLogAppEvents=1&quot;
      nonce=&quot;QVCodNV8&quot;&gt;&lt;/script&gt;
    &lt;!-- ---------------- --&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
  
  &lt;/html&gt;
  </code></pre>
  <p>component:</p>
  <pre><code>import React from &quot;react&quot;;
  import PropTypes from &quot;prop-types&quot;;
  import { Helmet } from &quot;react-helmet&quot;;
  import { IMAGES_LINK, API_LINK } from '../../utils/constants'
  
  //const metaDecorator = require(&quot;../../data/metaDecorator&quot;);
  const MetaDecorator = ({ title, description, imageUrl, imageAlt }) =&gt; {
  
      if (title != undefined &amp; description != undefined &amp; imageUrl != undefined &amp; imageAlt != undefined) {
          return (
              &lt;Helmet&gt;
              &lt;title&gt;{title}&lt;/title&gt;
              &lt;meta property=&quot;og:title&quot; content={title} /&gt;
              &lt;meta name=&quot;description&quot; content={description} /&gt;
              &lt;meta property=&quot;og:description&quot; content={description} /&gt;
              &lt;meta property=&quot;og:image&quot; content={API_LINK + imageUrl} /&gt;
              &lt;meta
                  property=&quot;og:url&quot;
                  content={&quot;https://maracanafoot.com&quot; + window.location.pathname + window.location.search}
              /&gt;
              &lt;meta name=&quot;twitter:card&quot; content=&quot;summary_large_image&quot; /&gt;
              &lt;meta name=&quot;twitter:image:alt&quot; content={imageAlt} /&gt;
              {/* &lt;meta name=&quot;twitter:site&quot; content={metaDecoratortwitterUsername} /&gt; */}
          &lt;/Helmet&gt;
  
          );
      } else {
          return (
              &lt;Helmet&gt;
              &lt;/Helmet&gt;
          );
      }
  }
  MetaDecorator.propTypes = {
      title: PropTypes.string.isRequired,
      description: PropTypes.string.isRequired,
      imageUrl: PropTypes.string.isRequired,
      imageAlt: PropTypes.string.isRequired,
  };
  export default MetaDecorator;
  </code></pre>
  <p>article page :</p>
  <pre><code> render = () =&gt; {
      const s = this.state;
  
      return (&lt;&gt;
  
        &lt;div&gt;
          
          {this.state.loadingArticle ? &lt;&gt;
  
            &lt;br /&gt;
            &lt;div style={this.styleSpinner} className='mt-3 mb-3'&gt;
              &lt;ImpulseSpinner size={30} color=&quot;#208FDF&quot; loading={this.state.loadingArticle} /&gt;
            &lt;/div&gt;&lt;/&gt;
            : null}
          {!this.isEmpty(this.state.article) ? &lt;&gt;
            
            
            &lt;MetaDecorator
              description={this.state.article.resumer}
              title={this.state.article.title}
              imageUrl={this.state.article.image}
              imageAlt=&quot;image alt&quot;
            /&gt;
  
  </code></pre>
  <p>Thanks in advance for any hint!</p>