I use React Helmet. I wanted to inject social meta tags in some of the pages. In order to DRY, I wanted to define these social meta tags as a separate component, which looks as below:

type SocialMetaProps = {
  title: string,
  description: string,
}

const SocialMeta = ({ title, description }: SocialMetaProps) => {
  return (
    <>
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:url" content={window.location.href} />

      <meta property="twitter:title" content={title} />
      <meta property="twitter:description" content={description} />
      <meta property="twitter:url" content={window.location.href} />
    </>
  )
}

export default SocialMeta

...which looks as such when I use it in a page:

<Helmet>
  <title>{resource.title}</title>
  <SocialMeta title={resource.title} description={resource.shortDescription} />
</Helmet>

The problem with that is that SocialMeta component does not render anything. I can confirm it by firing up browser console and doing document.head.getElementsByTagName("meta"). However, if I do it as below:

<Helmet>
  <title>{resource.title}</title>
  
  <meta property="og:title" content={resource.title} />
  <meta property="og:description" content={resource.shortDescription} />
  <meta property="og:url" content={window.location.href} />

  <meta property="twitter:title" content={resource.title} />
  <meta property="twitter:description" content={resource.shortDescription} />
  <meta property="twitter:url" content={window.location.href} />
</Helmet>

...it naturally renders the tags.

My best guess is that Helmet does not unpack <></>. Is there a way to render a custom component inside Helmet component?

Thanks in advance.


Environment

  • Vite
  • Typescript
  • React ^18.2.0
  • Helmet ^6.1.0
  • React Router (DOM) ^6.20.1 (if relevant)
  • erayerdin@programming.dev
    hexagon
    ·
    10 months ago

    Using an array and unpacking seems the most genius hacky solution to this problem. Imma go with that I guess.