I have a Gatsby site that I'm trying to add a third-party js widget to but for some strange reason it will only load if I refresh the page manually. On first page load, it as is if it doesn't exist at all, no errors in dev-tools, nothing... but if I refresh the page, it then appears. It's almost as if it's lazy loading? Is there a way to force load?
I've checked the elements
, console
, and network
tabs in dev tools but there's nothing to indicate any errors. elements
shows the tags that I would expect, console
shows nothing at all, and network
everything shows up with 200.
Could this be an issue with Gatsby and/or Helmet, it might be but I don't think it's an issue with the widget itself (it's third-party, I have no control over it, see last paragraph)?
<Helmet
script={[
{
type: 'text/javascript',
src: '//widget-url.com/path/to/jsfile.min.js',
},
{
type: 'text/javascript',
innerHTML: `
(function() {
var widget = Stuff.happens.here();
widget.Initialise();
})();
`,
},
]}
/>
In the body I then have:
<div id='widget-id'></div>
Things I've tried to attempt to understand where the issue is:
As I mentioned, I have to force refresh the page where the widget is located. If I force refresh any other page, it doesn't help. So something I tried is: rather than only including the JS into the head of the page in question, I would including it on ALL pages. But this has made no difference.
I've also tried adding the widget to a simple stand-alone html file, the widget loads without problem. Which leads me to think that it's probably not a widget issue?
I don't know where to go from here :(
The problem is that you are pointing a DOM element that may or may not be rendered at the moment your request the script.
In your case, I'd try:
<Helmet>
<script async defer src="//widget-url.com/path/to/jsfile.min.js" />
<script async defer>
{`
(function() {
var widget = Stuff.happens.here();
widget.Initialise();
})();
`}
</script>
</Helmet>
Or using one of the multiple Server-Side Rendering APIs. onRenderBody
should work:
// gatsby-ssr.js
import React from "react"
export const onRenderBody = ({ setHeadComponents, setPostBodyComponents }) => {
setHeadComponents([
<script
src="//widget-url.com/path/to/jsfile.min.js"
type="text/javascript"
async
/>,
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
var widget = Stuff.happens.here();
widget.Initialise();
})();
`,
}}
/>,
])
}