6

Our React app uses universal rendering. The html/body/head elements of the page are generated server-side using a React component. Normally, we can create things like <script> and <link> elements in our <head> just fine via JSX. Unfortunately, things got tricky once we started needing to insert third-party HTML fragments. These fragments are essentially a string like '<script src="some/url.js"></script><link rel="stylesheet" href="/some/css">'. Normally, HTML fragments can be injected into some element container via dangerouslySetInnerHTML, but there are no container elements for the <head> of an HTML document. This has forced us to either:

  1. Parse the HTML fragments (no easy task) and convert them into React elements
  2. Abandon JSX and build all our head content as one big concatenated/templated string

Is there any way in React to inject an HTML fragment into a document without a container element?

Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Do they have to go inside the head? – jimjkelly Oct 13 '16 at 22:24
  • That's a good question; I know that links typically go in the head. Has that changed in recent years? – Jacob Oct 13 '16 at 22:40
  • I don't think link is officially kosher, but I've done style tags in the body to load external css. Could also just use vanilla js server side to do it. – jimjkelly Oct 13 '16 at 22:46
  • 1
    You might be interested in https://github.com/nfl/react-helmet – Matthew Herbst Oct 14 '16 at 02:16
  • @Jacob If you wan't them loaded before the site is rendered they go to the head. If you wan't them loaded after the first render, they go at the end of the body. Scripts therefore often go in the body. https://stackoverflow.com/questions/196702/where-to-place-javascript-in-an-html-file – Markus Mar 09 '19 at 01:37
  • Can't [React fragments](https://reactjs.org/docs/fragments.html) be used for this? – Pavindu Mar 14 '19 at 23:21
  • @pavindu not if you have HTML strings; you can't use `dangerouslySetInnerHTML` on a fragment. – Jacob Mar 15 '19 at 00:48

1 Answers1

0

I think a combination of React Helmet to set the <head> at a component level and Interweave to inject/parse the HTML without using dangerouslySetInnerHTML could achieve what you're looking for?

RPK
  • 48
  • 5
  • `Interweave` does look like it supports this scenario with its `Markup` component, which you can wrap in a fragment. Looks like that option came out April 2018. – Jacob Sep 07 '19 at 17:06