I'm developing an isomorphic JS app using react-router and react-helmet.
Server-side, I pre-render my app as
const helmet = Helmet.rewind();
`<!DOCTYPE html>
<html ${helmet.htmlAttributes.toString()}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
${helmet.meta.toString()}
${helmet.title.toString()}
${helmet.base.toString()}
${helmet.link.toString()}
</head>
<body>
<main id="react-root">
${reactOutput}
</main>
${helmet.script.toString()}
</body>
</html>`
reactOutput is the result on rendering on server my route, and it's all handled by react-router.
My top-level components have the following structure
<div>
<Helmet />
<NavStuff />
<PageStuff />
</div>
Thus when I navigate client-side and react-router renders a new route, Helmet creates new <script>s inside <head> because there is no one telling it to put them elsewhere.
This has the undesired effect of reloading my scripts. They are cached so that's not a big deal, but there's no reason to make an HTTP request.
This also happens when changing page a second time, and I'm not really sure why given the script tags are already in the head now.
Any suggestions?
@mattecapu - Thanks for your interest in Helmet. For your situation, unfortunately it is as-designed. This library is a document head manager and really only deals with managing the head. As you've found, regardless of where you prerender your head attributes, they will always be written and updated in the head on the client-side.
Can the functionality of that external script be handled within React's routing? I'd like to understand your use case.
Hi @cwelch5, thank you for your time.
I could probably handle this manually using react-router's onUpdate hook, but it seems unelegant, that's why I asked here.
What would I need to to that? Should Helmet be rendered to be able to call Helmet.rewind?
@mattecapu This may be a worthwhile feature for someone who needs to have an external script outside of React. We can look into Helmet observing where the script tags are rendered and updating them in that location in the DOM. I don't imagine the API changing, just Helmet being smart is knowing where you've prerendered your script tags.
Closing - This issues is over a year old. If needed, please feel free to file a new issue.
Most helpful comment
@mattecapu This may be a worthwhile feature for someone who needs to have an external script outside of React. We can look into Helmet observing where the script tags are rendered and updating them in that location in the DOM. I don't imagine the API changing, just Helmet being smart is knowing where you've prerendered your script tags.