How can I render a custom component in `head` with React Helmet?

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:


<span style="color:#323232;">type SocialMetaProps = {
</span><span style="color:#323232;">  title: string,
</span><span style="color:#323232;">  description: string,
</span><span style="color:#323232;">}
</span><span style="color:#323232;">
</span><span style="color:#323232;">const SocialMeta = ({ title, description }: SocialMetaProps) => {
</span><span style="color:#323232;">  return (
</span><span style="color:#323232;">    <>
</span><span style="color:#323232;">      <meta property="og:title" content={title} />
</span><span style="color:#323232;">      <meta property="og:description" content={description} />
</span><span style="color:#323232;">      <meta property="og:url" content={window.location.href} />
</span><span style="color:#323232;">
</span><span style="color:#323232;">      <meta property="twitter:title" content={title} />
</span><span style="color:#323232;">      <meta property="twitter:description" content={description} />
</span><span style="color:#323232;">      <meta property="twitter:url" content={window.location.href} />
</span><span style="color:#323232;">    </>
</span><span style="color:#323232;">  )
</span><span style="color:#323232;">}
</span><span style="color:#323232;">
</span><span style="color:#323232;">export default SocialMeta
</span>

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


<span style="color:#323232;"><Helmet>
</span><span style="color:#323232;">  <title>{resource.title}</title>
</span><span style="color:#323232;">  <SocialMeta title={resource.title} description={resource.shortDescription} />
</span><span style="color:#323232;"></Helmet>
</span>

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:


<span style="color:#323232;"><Helmet>
</span><span style="color:#323232;">  <title>{resource.title}</title>
</span><span style="color:#323232;">  
</span><span style="color:#323232;">  <meta property="og:title" content={resource.title} />
</span><span style="color:#323232;">  <meta property="og:description" content={resource.shortDescription} />
</span><span style="color:#323232;">  <meta property="og:url" content={window.location.href} />
</span><span style="color:#323232;">
</span><span style="color:#323232;">  <meta property="twitter:title" content={resource.title} />
</span><span style="color:#323232;">  <meta property="twitter:description" content={resource.shortDescription} />
</span><span style="color:#323232;">  <meta property="twitter:url" content={window.location.href} />
</span><span style="color:#323232;"></Helmet>
</span>

…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)
mattd,

Yeah, Helmet doesn’t support Fragments

I think one workaround is to return an array of meta tags instead of using Fragments

Another way is to have your component wrap the meta tags in Helmet instead of Fragment, and call it next to page level Helmet

erayerdin,

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

  • All
  • Subscribed
  • Moderated
  • Favorites
  • react@programming.dev
  • DreamBathrooms
  • mdbf
  • ethstaker
  • magazineikmin
  • GTA5RPClips
  • rosin
  • thenastyranch
  • Youngstown
  • osvaldo12
  • slotface
  • khanakhh
  • kavyap
  • InstantRegret
  • Durango
  • JUstTest
  • everett
  • cisconetworking
  • Leos
  • normalnudes
  • cubers
  • modclub
  • ngwrru68w68
  • tacticalgear
  • provamag3
  • anitta
  • tester
  • megavids
  • lostlight
  • All magazines